From ff8e3dd2ada3d9de4075e3bd05fc982f2ebce23a Mon Sep 17 00:00:00 2001 From: Mickael BARON Date: Tue, 9 Apr 2024 15:51:45 +0200 Subject: [PATCH] Initial commit --- .gitignore | 1 + LICENSE | 28 + README.md | 142 + db_init.sql | 74 + docker-compose.yaml | 58 + images/rql_web.png | Bin 0 -> 115253 bytes nginx-conf/nginx.conf | 25 + rql-backend/.gitignore | 4 + rql-backend/Dockerfile | 24 + rql-backend/pom.xml | 151 + rql-backend/rql-api/pom.xml | 37 + .../fr/ensma/lias/rql/api/ApiConstant.java | 8 + .../fr/ensma/lias/rql/api/ApiParameters.java | 46 + .../java/fr/ensma/lias/rql/api/ApiPaths.java | 44 + .../lias/rql/api/AuthenticationResource.java | 32 + .../fr/ensma/lias/rql/api/DataBaseImport.java | 56 + .../rql/api/NotYetImplementedException.java | 10 + .../ensma/lias/rql/api/ProjectResource.java | 73 + .../ensma/lias/rql/api/QueryConstruction.java | 33 + .../fr/ensma/lias/rql/api/QueryResource.java | 105 + .../fr/ensma/lias/rql/api/SchemaResource.java | 41 + .../lias/rql/api/TokenAuthenticated.java | 17 + .../fr/ensma/lias/rql/api/UserResource.java | 46 + .../fr/ensma/lias/rql/api/XlsxResource.java | 45 + .../ensma/lias/rql/dto/CheckRuleResult.java | 35 + .../ensma/lias/rql/dto/CheckRuleSummary.java | 70 + .../fr/ensma/lias/rql/dto/Credentials.java | 61 + .../ensma/lias/rql/dto/ExecutionSummary.java | 47 + .../java/fr/ensma/lias/rql/dto/Favorite.java | 78 + .../fr/ensma/lias/rql/dto/FilePreview.java | 44 + .../java/fr/ensma/lias/rql/dto/Project.java | 85 + .../fr/ensma/lias/rql/dto/QueryEnumType.java | 8 + .../fr/ensma/lias/rql/dto/QueryResult.java | 37 + .../java/fr/ensma/lias/rql/dto/RQLResult.java | 40 + .../java/fr/ensma/lias/rql/dto/RQLRow.java | 67 + .../lias/rql/dto/RuleGenerationSummary.java | 13 + .../java/fr/ensma/lias/rql/dto/SQLResult.java | 51 + .../java/fr/ensma/lias/rql/dto/SQLRow.java | 24 + .../fr/ensma/lias/rql/dto/SchemaResult.java | 27 + .../fr/ensma/lias/rql/dto/SheetContent.java | 61 + .../ensma/lias/rql/dto/TableImportResult.java | 53 + .../java/fr/ensma/lias/rql/dto/TypeQuery.java | 72 + .../main/java/fr/ensma/lias/rql/dto/User.java | 55 + .../rql-api/src/main/resources/DELETE.me | 0 rql-backend/rql-api/src/test/java/DELETE.me | 0 .../rql-api/src/test/resources/DELETE.me | 0 rql-backend/rql-core/pom.xml | 68 + .../java/fr/ensma/lias/rql/RQLManager.java | 356 + .../java/fr/ensma/lias/rql/RQLResults.java | 28 + .../src/main/java/fr/ensma/lias/rql/Rule.java | 62 + .../ensma/lias/rql/baseresults/BaseLine.java | 32 + .../lias/rql/baseresults/BaseResult.java | 32 + .../fr/ensma/lias/rql/cfg/CoreConfig.java | 80 + .../fr/ensma/lias/rql/cfg/RqlCoreConf.java | 37 + .../fr/ensma/lias/rql/cfg/SqlCoreConf.java | 17 + .../fr/ensma/lias/rql/database/Column.java | 34 + .../lias/rql/database/DataBaseSchema.java | 24 + .../ensma/lias/rql/database/DataBaseType.java | 8 + .../fr/ensma/lias/rql/database/Database.java | 28 + .../fr/ensma/lias/rql/database/MysqlDB.java | 46 + .../fr/ensma/lias/rql/database/OracleDB.java | 65 + .../ensma/lias/rql/database/PostgresqlDB.java | 50 + .../fr/ensma/lias/rql/database/Table.java | 38 + .../fr/ensma/lias/rql/dfg/AttributSet.java | 220 + .../lias/rql/dfg/AttributeCalculation.java | 489 + .../main/java/fr/ensma/lias/rql/dfg/Dfg.java | 418 + .../lias/rql/dfg/KilledProcessException.java | 15 + .../fr/ensma/lias/rql/dfg/KnownException.java | 18 + .../fr/ensma/lias/rql/dfg/MutableInt.java | 46 + .../rql/dfg/MyUncaughtExceptionHandler.java | 11 + .../NotifyingBlockingThreadPoolExecutor.java | 317 + .../ensma/lias/rql/dfg/Set_AttributSet.java | 138 + .../lias/rql/dfg/ThreadRunException.java | 29 + .../queryconstruction/QueryConstructor.java | 94 + .../ensma/lias/rql/rulecheck/CheckResult.java | 95 + .../ensma/lias/rql/rulecheck/RuleChecker.java | 514 + .../fr/ensma/lias/rql/sql/SQLManager.java | 346 + .../fr/ensma/lias/rql/sql/SQLResults.java | 36 + .../ensma/lias/rql/sql/SQLResultsObject.java | 25 + .../fr/ensma/lias/rql/sql/SQLResultsRow.java | 25 + .../java/fr/ensma/lias/rql/sql/SQLRow.java | 23 + .../fr/ensma/lias/rql/rqlgrammar/RQL.jj | 418 + .../fr/ensma/lias/rql/rulesgrammar/Rules.jj | 158 + rql-backend/rql-core/src/test/java/DELETE.me | 0 .../rql-core/src/test/resources/DELETE.me | 0 rql-backend/rql-server/pom.xml | 98 + .../java/fr/ensma/lias/rql/AuthToken.java | 39 + .../fr/ensma/lias/rql/CrossDomainFilter.java | 21 + .../java/fr/ensma/lias/rql/RqlConstant.java | 13 + .../java/fr/ensma/lias/rql/RqlLauncher.java | 61 + .../main/java/fr/ensma/lias/rql/RqlUtil.java | 81 + .../fr/ensma/lias/rql/cfg/Configuration.java | 23 + .../fr/ensma/lias/rql/cfg/IConfiguration.java | 9 + .../java/fr/ensma/lias/rql/cfg/RqlConfig.java | 61 + .../java/fr/ensma/lias/rql/core/IRql.java | 50 + .../fr/ensma/lias/rql/core/RqlConstant.java | 9 + .../java/fr/ensma/lias/rql/core/RqlImp.java | 204 + .../dao/dbconfiguration/ConfigurationDAO.java | 68 + .../dbconfiguration/IConfigurationDAO.java | 17 + .../rql/dao/dbschema/AbstractSchemaDAO.java | 67 + .../lias/rql/dao/dbschema/ISchemaDAO.java | 19 + .../lias/rql/dao/dbschema/MySqlSchemaDAO.java | 20 + .../rql/dao/dbschema/OracleSchemaDAO.java | 21 + .../rql/dao/dbschema/PostgresSchemaDAO.java | 151 + .../dao/dbschema/favorite/FavoriteDAO.java | 105 + .../dao/dbschema/favorite/IFavoriteDAO.java | 20 + .../ensma/lias/rql/dao/inmemory/InMemory.java | 63 + .../dao/postgressession/IPostgresSession.java | 12 + .../dao/postgressession/PostgresSession.java | 42 + .../lias/rql/dao/project/IProjectDAO.java | 23 + .../lias/rql/dao/project/ProjectDAO.java | 128 + .../ensma/lias/rql/dao/query/IQueryDAO.java | 23 + .../fr/ensma/lias/rql/dao/query/QueryDAO.java | 84 + .../ensma/lias/rql/dao/userdao/IUserDAO.java | 25 + .../ensma/lias/rql/dao/userdao/UserDAO.java | 113 + .../rql/dbimport/MySqlNameNormalizer.java | 21 + .../lias/rql/dbimport/NameNormalizer.java | 20 + .../rql/dbimport/OracleNameNormalizer.java | 21 + .../rql/dbimport/PostgresNameNormalizer.java | 22 + .../ensma/lias/rql/model/DataBaseConfig.java | 93 + .../service/AuthenticationResourceImpl.java | 73 + .../lias/rql/service/BearerTokenFilter.java | 65 + .../lias/rql/service/DataBaseImportImp.java | 377 + .../lias/rql/service/ProjectResourceImp.java | 193 + .../rql/service/QueryConstructionImp.java | 32 + .../lias/rql/service/QueryResourceImp.java | 131 + .../lias/rql/service/SchemaResourceImp.java | 85 + .../lias/rql/service/UserResourceImp.java | 65 + .../lias/rql/service/XlsxResourceImp.java | 418 + .../src/main/resources/META-INF/beans.xml | 7 + .../rql-server/src/test/java/DELETE.me | 0 .../rql-server/src/test/resources/DELETE.me | 0 rql-backend/shd31/01conv.pl | 33 + rql-backend/shd31/aheap.c | 216 + rql-backend/shd31/aheap.h | 111 + rql-backend/shd31/alist.c | 637 + rql-backend/shd31/alist.h | 225 + rql-backend/shd31/appendnum.pl | 31 + rql-backend/shd31/barray.c | 238 + rql-backend/shd31/barray.h | 74 + rql-backend/shd31/base.c | 92 + rql-backend/shd31/base.h | 59 + rql-backend/shd31/col_conv.pl | 101 + rql-backend/shd31/exec_shd | 5 + rql-backend/shd31/exec_shd_ | 7 + rql-backend/shd31/itemset.c | 496 + rql-backend/shd31/itemset.h | 157 + rql-backend/shd31/makefile | 2 + rql-backend/shd31/problem.c | 350 + rql-backend/shd31/problem.h | 177 + rql-backend/shd31/queue.c | 528 + rql-backend/shd31/queue.h | 176 + rql-backend/shd31/readme.txt | 603 + rql-backend/shd31/sep_shd | 5 + rql-backend/shd31/sep_shd_ | 7 + rql-backend/shd31/shd.c | 788 + rql-backend/shd31/sortout.pl | 41 + rql-backend/shd31/stdlib2.c | 1282 ++ rql-backend/shd31/stdlib2.h | 823 + rql-backend/shd31/test.dat | 6 + rql-backend/shd31/test2.dat | 6 + rql-backend/shd31/test3.dat | 11 + rql-backend/shd31/testLN2.dat | 19 + rql-backend/shd31/transnum.pl | 86 + rql-backend/shd31/transpose.pl | 33 + rql-backend/shd31/undo.c | 95 + rql-backend/shd31/undo.h | 72 + rql-backend/shd31/untransnum.pl | 51 + rql-backend/shd31/vec.c | 731 + rql-backend/shd31/vec.h | 171 + rql-ui/.babelrc | 18 + rql-ui/.editorconfig | 9 + rql-ui/.eslintignore | 5 + rql-ui/.eslintrc.js | 33 + rql-ui/.gitignore | 17 + rql-ui/.postcssrc.js | 10 + rql-ui/Dockerfile | 22 + rql-ui/build/build.js | 49 + rql-ui/build/check-versions.js | 54 + rql-ui/build/logo.png | Bin 0 -> 6849 bytes rql-ui/build/utils.js | 101 + rql-ui/build/vue-loader.conf.js | 22 + rql-ui/build/webpack.base.conf.js | 92 + rql-ui/build/webpack.dev.conf.js | 95 + rql-ui/build/webpack.prod.conf.js | 149 + rql-ui/config/dev.env.js | 8 + rql-ui/config/index.js | 76 + rql-ui/config/prod.env.js | 5 + rql-ui/default.conf | 25 + rql-ui/index.html | 16 + rql-ui/package-lock.json | 18342 ++++++++++++++++ rql-ui/package.json | 116 + rql-ui/src/App.vue | 14 + rql-ui/src/assets/RQL.css | 516 + rql-ui/src/assets/bg.jpg | Bin 0 -> 246648 bytes rql-ui/src/assets/favicon.ico | Bin 0 -> 4286 bytes rql-ui/src/assets/favicon.png | Bin 0 -> 1213 bytes .../graphicloads_filetype_excel_xls-6.png | Bin 0 -> 1258 bytes .../assets/graphicloads_filetype_pdf-6.png | Bin 0 -> 1254 bytes .../assets/graphicloads_filetype_txt-6.png | Bin 0 -> 1156 bytes rql-ui/src/assets/tick.png | Bin 0 -> 2912 bytes rql-ui/src/components/CheckRule.vue | 427 + rql-ui/src/components/DataBaseSchema.vue | 138 + rql-ui/src/components/DatabaseTableImport.vue | 517 + rql-ui/src/components/Login.vue | 231 + rql-ui/src/components/Project.vue | 669 + rql-ui/src/components/QueryArea.vue | 886 + rql-ui/src/components/RulesArea.vue | 427 + rql-ui/src/components/SqlArea.vue | 290 + rql-ui/src/components/UtilsMixins.vue | 9 + rql-ui/src/components/VueDualList.vue | 151 + rql-ui/src/components/Workspace.vue | 337 + .../vue-materialize-datatable/package.json | 78 + .../src/DataTable.vue | 563 + .../src/locales/ar.json | 7 + .../src/locales/br.json | 6 + .../src/locales/cat.json | 6 + .../src/locales/en.json | 6 + .../src/locales/es.json | 6 + .../src/locales/index.js | 7 + .../webpack.config.js | 29 + rql-ui/src/directives/Dropdown.js | 27 + rql-ui/src/directives/Expandable.js | 54 + rql-ui/src/directives/ResizeHandler.js | 26 + rql-ui/src/directives/StickyScroll.js | 48 + rql-ui/src/fonts/Glyphter.eot | Bin 0 -> 5688 bytes rql-ui/src/fonts/Glyphter.svg | 1 + rql-ui/src/fonts/Glyphter.ttf | Bin 0 -> 5520 bytes rql-ui/src/fonts/Glyphter.woff | Bin 0 -> 3440 bytes .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes rql-ui/src/main.js | 32 + rql-ui/src/router/index.js | 62 + rql-ui/src/sass/_base.scss | 40 + rql-ui/src/sass/_fonts.scss | 46 + rql-ui/src/sass/_glyphicons.scss | 307 + rql-ui/src/sass/_icons-styles.scss | 54 + rql-ui/src/sass/_icons.scss | 76 + rql-ui/src/sass/_material-forms.scss | 357 + rql-ui/src/sass/_mixins.scss | 59 + rql-ui/src/sass/_override-bootstrap.scss | 465 + rql-ui/src/sass/_override-custom-libs.scss | 167 + rql-ui/src/sass/_typography.scss | 113 + rql-ui/src/sass/_variables.scss | 348 + rql-ui/src/sass/main.scss | 23 + rql-ui/static/.gitkeep | 0 249 files changed, 45483 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 db_init.sql create mode 100644 docker-compose.yaml create mode 100644 images/rql_web.png create mode 100644 nginx-conf/nginx.conf create mode 100644 rql-backend/.gitignore create mode 100644 rql-backend/Dockerfile create mode 100644 rql-backend/pom.xml create mode 100644 rql-backend/rql-api/pom.xml create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiConstant.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiParameters.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiPaths.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/AuthenticationResource.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/DataBaseImport.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/NotYetImplementedException.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ProjectResource.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/QueryConstruction.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/QueryResource.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/SchemaResource.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/TokenAuthenticated.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/UserResource.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/XlsxResource.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/CheckRuleResult.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/CheckRuleSummary.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Credentials.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/ExecutionSummary.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Favorite.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/FilePreview.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Project.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/QueryEnumType.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/QueryResult.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RQLResult.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RQLRow.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RuleGenerationSummary.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SQLResult.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SQLRow.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SchemaResult.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SheetContent.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/TableImportResult.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/TypeQuery.java create mode 100644 rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/User.java create mode 100644 rql-backend/rql-api/src/main/resources/DELETE.me create mode 100644 rql-backend/rql-api/src/test/java/DELETE.me create mode 100644 rql-backend/rql-api/src/test/resources/DELETE.me create mode 100644 rql-backend/rql-core/pom.xml create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/RQLManager.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/RQLResults.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/Rule.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/baseresults/BaseLine.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/baseresults/BaseResult.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/CoreConfig.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/RqlCoreConf.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/SqlCoreConf.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Column.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/DataBaseSchema.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/DataBaseType.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Database.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/MysqlDB.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/OracleDB.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/PostgresqlDB.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Table.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/AttributSet.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/AttributeCalculation.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/Dfg.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/KilledProcessException.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/KnownException.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/MutableInt.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/MyUncaughtExceptionHandler.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/NotifyingBlockingThreadPoolExecutor.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/Set_AttributSet.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/ThreadRunException.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/queryconstruction/QueryConstructor.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/rulecheck/CheckResult.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/rulecheck/RuleChecker.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLManager.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResults.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResultsObject.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResultsRow.java create mode 100644 rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLRow.java create mode 100644 rql-backend/rql-core/src/main/resources/fr/ensma/lias/rql/rqlgrammar/RQL.jj create mode 100644 rql-backend/rql-core/src/main/resources/fr/ensma/lias/rql/rulesgrammar/Rules.jj create mode 100644 rql-backend/rql-core/src/test/java/DELETE.me create mode 100644 rql-backend/rql-core/src/test/resources/DELETE.me create mode 100644 rql-backend/rql-server/pom.xml create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/AuthToken.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/CrossDomainFilter.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlConstant.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlLauncher.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlUtil.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/Configuration.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/IConfiguration.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/RqlConfig.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/IRql.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/RqlConstant.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/RqlImp.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbconfiguration/ConfigurationDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbconfiguration/IConfigurationDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/AbstractSchemaDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/ISchemaDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/MySqlSchemaDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/OracleSchemaDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/PostgresSchemaDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/favorite/FavoriteDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/favorite/IFavoriteDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/inmemory/InMemory.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/postgressession/IPostgresSession.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/postgressession/PostgresSession.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/project/IProjectDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/project/ProjectDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/query/IQueryDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/query/QueryDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/userdao/IUserDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/userdao/UserDAO.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/MySqlNameNormalizer.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/NameNormalizer.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/OracleNameNormalizer.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/PostgresNameNormalizer.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/model/DataBaseConfig.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/AuthenticationResourceImpl.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/BearerTokenFilter.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/DataBaseImportImp.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/ProjectResourceImp.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/QueryConstructionImp.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/QueryResourceImp.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/SchemaResourceImp.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/UserResourceImp.java create mode 100644 rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/XlsxResourceImp.java create mode 100644 rql-backend/rql-server/src/main/resources/META-INF/beans.xml create mode 100644 rql-backend/rql-server/src/test/java/DELETE.me create mode 100644 rql-backend/rql-server/src/test/resources/DELETE.me create mode 100644 rql-backend/shd31/01conv.pl create mode 100644 rql-backend/shd31/aheap.c create mode 100644 rql-backend/shd31/aheap.h create mode 100644 rql-backend/shd31/alist.c create mode 100644 rql-backend/shd31/alist.h create mode 100644 rql-backend/shd31/appendnum.pl create mode 100644 rql-backend/shd31/barray.c create mode 100644 rql-backend/shd31/barray.h create mode 100644 rql-backend/shd31/base.c create mode 100644 rql-backend/shd31/base.h create mode 100644 rql-backend/shd31/col_conv.pl create mode 100644 rql-backend/shd31/exec_shd create mode 100644 rql-backend/shd31/exec_shd_ create mode 100644 rql-backend/shd31/itemset.c create mode 100644 rql-backend/shd31/itemset.h create mode 100644 rql-backend/shd31/makefile create mode 100644 rql-backend/shd31/problem.c create mode 100644 rql-backend/shd31/problem.h create mode 100644 rql-backend/shd31/queue.c create mode 100644 rql-backend/shd31/queue.h create mode 100644 rql-backend/shd31/readme.txt create mode 100644 rql-backend/shd31/sep_shd create mode 100644 rql-backend/shd31/sep_shd_ create mode 100644 rql-backend/shd31/shd.c create mode 100644 rql-backend/shd31/sortout.pl create mode 100644 rql-backend/shd31/stdlib2.c create mode 100644 rql-backend/shd31/stdlib2.h create mode 100644 rql-backend/shd31/test.dat create mode 100644 rql-backend/shd31/test2.dat create mode 100644 rql-backend/shd31/test3.dat create mode 100644 rql-backend/shd31/testLN2.dat create mode 100644 rql-backend/shd31/transnum.pl create mode 100644 rql-backend/shd31/transpose.pl create mode 100644 rql-backend/shd31/undo.c create mode 100644 rql-backend/shd31/undo.h create mode 100644 rql-backend/shd31/untransnum.pl create mode 100644 rql-backend/shd31/vec.c create mode 100644 rql-backend/shd31/vec.h create mode 100644 rql-ui/.babelrc create mode 100644 rql-ui/.editorconfig create mode 100644 rql-ui/.eslintignore create mode 100644 rql-ui/.eslintrc.js create mode 100644 rql-ui/.gitignore create mode 100644 rql-ui/.postcssrc.js create mode 100644 rql-ui/Dockerfile create mode 100644 rql-ui/build/build.js create mode 100644 rql-ui/build/check-versions.js create mode 100644 rql-ui/build/logo.png create mode 100644 rql-ui/build/utils.js create mode 100644 rql-ui/build/vue-loader.conf.js create mode 100644 rql-ui/build/webpack.base.conf.js create mode 100644 rql-ui/build/webpack.dev.conf.js create mode 100644 rql-ui/build/webpack.prod.conf.js create mode 100644 rql-ui/config/dev.env.js create mode 100644 rql-ui/config/index.js create mode 100644 rql-ui/config/prod.env.js create mode 100644 rql-ui/default.conf create mode 100644 rql-ui/index.html create mode 100644 rql-ui/package-lock.json create mode 100644 rql-ui/package.json create mode 100644 rql-ui/src/App.vue create mode 100644 rql-ui/src/assets/RQL.css create mode 100644 rql-ui/src/assets/bg.jpg create mode 100644 rql-ui/src/assets/favicon.ico create mode 100644 rql-ui/src/assets/favicon.png create mode 100644 rql-ui/src/assets/graphicloads_filetype_excel_xls-6.png create mode 100644 rql-ui/src/assets/graphicloads_filetype_pdf-6.png create mode 100644 rql-ui/src/assets/graphicloads_filetype_txt-6.png create mode 100644 rql-ui/src/assets/tick.png create mode 100644 rql-ui/src/components/CheckRule.vue create mode 100644 rql-ui/src/components/DataBaseSchema.vue create mode 100644 rql-ui/src/components/DatabaseTableImport.vue create mode 100644 rql-ui/src/components/Login.vue create mode 100644 rql-ui/src/components/Project.vue create mode 100644 rql-ui/src/components/QueryArea.vue create mode 100644 rql-ui/src/components/RulesArea.vue create mode 100644 rql-ui/src/components/SqlArea.vue create mode 100644 rql-ui/src/components/UtilsMixins.vue create mode 100644 rql-ui/src/components/VueDualList.vue create mode 100644 rql-ui/src/components/Workspace.vue create mode 100644 rql-ui/src/components/vue-materialize-datatable/package.json create mode 100644 rql-ui/src/components/vue-materialize-datatable/src/DataTable.vue create mode 100644 rql-ui/src/components/vue-materialize-datatable/src/locales/ar.json create mode 100644 rql-ui/src/components/vue-materialize-datatable/src/locales/br.json create mode 100644 rql-ui/src/components/vue-materialize-datatable/src/locales/cat.json create mode 100644 rql-ui/src/components/vue-materialize-datatable/src/locales/en.json create mode 100644 rql-ui/src/components/vue-materialize-datatable/src/locales/es.json create mode 100644 rql-ui/src/components/vue-materialize-datatable/src/locales/index.js create mode 100644 rql-ui/src/components/vue-materialize-datatable/webpack.config.js create mode 100644 rql-ui/src/directives/Dropdown.js create mode 100644 rql-ui/src/directives/Expandable.js create mode 100644 rql-ui/src/directives/ResizeHandler.js create mode 100644 rql-ui/src/directives/StickyScroll.js create mode 100644 rql-ui/src/fonts/Glyphter.eot create mode 100644 rql-ui/src/fonts/Glyphter.svg create mode 100644 rql-ui/src/fonts/Glyphter.ttf create mode 100644 rql-ui/src/fonts/Glyphter.woff create mode 100644 rql-ui/src/fonts/glyphicons-halflings-regular.eot create mode 100644 rql-ui/src/fonts/glyphicons-halflings-regular.svg create mode 100644 rql-ui/src/fonts/glyphicons-halflings-regular.ttf create mode 100644 rql-ui/src/fonts/glyphicons-halflings-regular.woff create mode 100644 rql-ui/src/fonts/glyphicons-halflings-regular.woff2 create mode 100644 rql-ui/src/main.js create mode 100644 rql-ui/src/router/index.js create mode 100644 rql-ui/src/sass/_base.scss create mode 100644 rql-ui/src/sass/_fonts.scss create mode 100644 rql-ui/src/sass/_glyphicons.scss create mode 100644 rql-ui/src/sass/_icons-styles.scss create mode 100644 rql-ui/src/sass/_icons.scss create mode 100644 rql-ui/src/sass/_material-forms.scss create mode 100644 rql-ui/src/sass/_mixins.scss create mode 100644 rql-ui/src/sass/_override-bootstrap.scss create mode 100644 rql-ui/src/sass/_override-custom-libs.scss create mode 100644 rql-ui/src/sass/_typography.scss create mode 100644 rql-ui/src/sass/_variables.scss create mode 100644 rql-ui/src/sass/main.scss create mode 100644 rql-ui/static/.gitkeep diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2de89b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/db diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ffc0b40 --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +SHD (rql-backend/shd31) +======================= +Copyright (c) 2007 Takeaki Uno. +See rql-backend/shd31/readme.txt for details. + +RQL-API, RQL-Core, RQL-Server, and RQL-UI +========================================= +Copyright (c) 2011-2024 [LIMOS/ISIMA, LIRIS/INSA Lyon, LIAS/ISAE-ENSMA] + +These portions of the software are licensed under the terms of the MIT License. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3afd637 --- /dev/null +++ b/README.md @@ -0,0 +1,142 @@ +# RQL project + +RQL (Rule Query Language) is a framework that allows the user to mine dependencies such as association rules, functional dependencies, order dependencies, etc. + +This project includes a Web interface to write SQL or RQL queries on top of a local DBMS, and browse generated rules. + +You can read more about RQL using the following resources: + +- [RQL: A Query Language for Rule Discovery in Databases](https://hal.science/hal-01395083/), a TCS paper, 2017. +- [RQL: An SQL-like Query Language for Discovering Meaningful Rules](https://hal.science/hal-01301091/), an ICDM demo, 2014. +- [Query Rewriting for Rule Mining in Databases](https://hal.science/hal-01339257/), an LML workshop paper, 2013. +- [Armstrong-compliant Logical Query Languages](https://hal.science/hal-00649604/), an LID workshop paper, 2011. + + +## Software requirements + +* [Docker](https://www.docker.com/) (that's all) + +RQL building and deployment have been tested on: + +* macOS Sonoma (with Docker Desktop), +* Ubuntu 20.04.6 LTS +* Debian 12.5 + +In fact, any operating system that supports [Docker](https://www.docker.com/) should be able to build RQL. + +## Build + +```console +$ docker compose build +``` + +## Run + +* Create all containers + +```console +$ docker compose up -d +``` + +* Initialize the database + +```console +$ docker exec -i rql_db psql -U postgres < db_init.sql +``` + +* Open the http://localhost/rql URL with your favorite web browser. +To log in, the default account has credentials admin/adminadmin. + +## Example + +The following example is based on a sample employee table. It can be created from the RQL main query form, which supports both SQL and RQL queries. + +~~~SQL +CREATE TABLE emp ( + empno INT, + lastname VARCHAR(20), + workdept VARCHAR(3), + job VARCHAR(20), + educlevel INT, + gender CHAR, + sal INT, + bonus INT, + comm INT, + mgrno INT +); +INSERT INTO EMP VALUES (10, 'SPEN', 'C01', 'FINANCE', 18, 'F', 52750, 500, 4220, 20); +INSERT INTO EMP VALUES (20, 'THOMP', NULL, 'MANAGER', 18, 'M', 41250, 800, 3300, NULL); +INSERT INTO EMP VALUES (30, 'KWAN', NULL, 'FINANCE', 20, 'F', 38250, 500, 3060, 10); +INSERT INTO EMP VALUES (50, 'GEYER', NULL, 'MANAGER', 16, 'M', 40175, 700, 3214, 20); +INSERT INTO EMP VALUES (60, 'STERN', 'D21', 'SALE', 14, 'M', 32250, 500, 2580, 30); +INSERT INTO EMP VALUES (70, 'PULASKI', 'D21', 'SALE', 16, 'F', 36170, 700, 2893, 100); +INSERT INTO EMP VALUES (90, 'HENDER', 'D21', 'SALE', 17, 'F', 29750, 500, 2380, 10); +INSERT INTO EMP VALUES (100, 'SPEN', 'C01', 'FINANCE', 18, 'M', 26150, 800, 2092, 20); +~~~ + +RQL can then be used to identify dependencies within the data. For instance, the following query identifies functional dependencies. + +~~~RQL +FINDRULES +OVER empno, lastname, workdept, job, educlevel, gender, sal, bonus, comm, mgrno +SCOPE t1, t2 emp +CONDITION ON A IS t1.A = t2.A +~~~ + +![The RQL Web interface](images/rql_web.png) + +## User accounts + +New user accounts must be added manually. + +```console +$ docker exec -i rql_db psql -U postgres -d rql +``` + +~~~SQL +INSERT INTO users (username, firstname, lastname, hashpassword, isadmin) +VALUES +('jdoe', 'Jane', 'Doe', '', FALSE); +~~~ + +RQL uses the original version of bcrypt hashing with 12 rounds. +Therefore, hashed passwords should be of the form: `$2a$12$...`. + +An example of such password is provided at the end of the `db_init.sql` file. + +## Acknowledgments + +RQL has been partially funded by: + +- LIRIS, INSA Lyon and the French National Research Agency (ANR), as part of the DAG project +- CNRS, as part of the Mastodons PetaSky, QualiSky and QDoSSI projects +- LIAS, ISAE-ENSMA and the MIRES research federation + +### Historic contributors + +* Mickael Baron, LIAS, ISAE-ENSMA +* Nicolas Buisson, LIRIS, INSA Lyon +* Brice Chardin, LIAS, ISAE-ENSMA +* Emmanuel Coquery, LIRIS, Université Claude Bernard Lyon 1 +* Benjamin Gouriou, LIMOS, ISIMA +* Marie Pailloux, LIMOS, ISIMA +* Jean-Marc Petit, LIRIS, INSA Lyon +* Bilal Rezkellah, LIAS, ISAE-ENSMA + +## Citation + +If you use RQL in a scientific publication, please reference the following work: + +Chardin, B., Coquery, E., Pailloux, M., & Petit, J.-M. (2017). RQL: A Query Language for Rule Discovery in Databases. Theoretical Computer Science, 658, 357-374. + +~~~bibtex +@article{rql2017, + title={RQL: A Query Language for Rule Discovery in Databases}, + author={Chardin, Brice and Coquery, Emmanuel and Pailloux, Marie and Petit, Jean-Marc}, + journal={Theoretical Computer Science}, + volume={658}, + pages={357--374}, + year={2017}, + publisher={Elsevier}, +} +~~~ diff --git a/db_init.sql b/db_init.sql new file mode 100644 index 0000000..0cda41c --- /dev/null +++ b/db_init.sql @@ -0,0 +1,74 @@ +CREATE DATABASE rql; +\c rql; +CREATE TABLE users +( + userid serial NOT NULL, + username character varying, + firstname character varying, + hashpassword character varying, + lastname character varying, + isadmin boolean, + CONSTRAINT user_pkey PRIMARY KEY (userid), + CONSTRAINT user_username_key UNIQUE (username) +); +CREATE TABLE project +( + projectid serial NOT NULL, + projectname character varying, + creationdate character varying, + userid character varying, + description character varying, + CONSTRAINT project_pkey PRIMARY KEY (projectid), + CONSTRAINT project_userid_fkey FOREIGN KEY (userid) + REFERENCES public.users (username) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION +); +CREATE TABLE database +( + "databaseID" serial NOT NULL, + host character varying, + port integer, + name character varying, + userid character varying, + password character varying, + type character varying, + projectid bigint, + CONSTRAINT database_pkey PRIMARY KEY ("databaseID"), + CONSTRAINT pro FOREIGN KEY (projectid) + REFERENCES public.project (projectid) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION +); +CREATE TABLE collaborator +( + collaboratorid serial NOT NULL, + projectid bigint, + userid character varying, + CONSTRAINT collaborator_pkey PRIMARY KEY (collaboratorid), + CONSTRAINT collaborator_projectid_fkey FOREIGN KEY (projectid) + REFERENCES public.project (projectid) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT collaborator_userid_fkey FOREIGN KEY (userid) + REFERENCES public.users (username) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION +); +CREATE TABLE favorite +( + favoriteid serial NOT NULL, + description character varying, + query character varying, + creationdate character varying, + projectid bigint, + favoritename character varying, + type character varying, + CONSTRAINT favorite_pkey PRIMARY KEY (favoriteid), + CONSTRAINT favorite_projectid_fkey FOREIGN KEY (projectid) + REFERENCES public.project (projectid) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT favorite_favoritename_key UNIQUE (favoritename) +); + +INSERT INTO users( + username, firstname, hashpassword, lastname, isadmin) + VALUES ('admin', 'admin', '$2a$12$Cq1GoUaBySCjWBHJJALYNOetItTezPXr1B9JdsLa8xqH5ARVVFplm', 'admin', TRUE); +-- login: admin +-- password: adminadmin diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..3446bbd --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,58 @@ +services: + + backend: + container_name: rql_backend + build: rql-backend/ + image: rql:backend-1.1.0-SNAPSHOT + depends_on: + - db + networks: + - rqlnetwork + + db: + container_name: rql_db + image: postgres:9.6 + volumes: + - ./db/rql:/var/lib/postgresql/data + networks: + - rqlnetwork + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + + business_db: + container_name: rql_business_db + image: postgres:9.6 + volumes: + - ./db/business:/var/lib/postgresql/data + networks: + - rqlnetwork + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + + frontend: + container_name: rql_frontend + build: rql-ui/ + image: rql:frontend-1.1.0-SNAPSHOT + depends_on: + - backend + networks: + - rqlnetwork + + web: + container_name: rql_proxy + image: nginx:1.25.4 + depends_on: + - frontend + - backend + volumes: + - ./nginx-conf:/etc/nginx/conf.d + ports: + - "80:80" + networks: + - rqlnetwork + +networks: + rqlnetwork: + name: rqlnetwork diff --git a/images/rql_web.png b/images/rql_web.png new file mode 100644 index 0000000000000000000000000000000000000000..0308f0187c191c6a90f6b145b0ab7ac4182daa9c GIT binary patch literal 115253 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 + 4.0.0 + fr.ensma.lias + rql-backend + 1.1.0-SNAPSHOT + pom + REST API module of RQL platform + + rql-core + rql-api + rql-server + + + + 3.4.3 + + + 1.0.8 + + + 2.25.1 + + + 1.1.1 + + + 0.4 + + + 3.1 + 8 + 8 + + + 1.7.25 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.version} + + ${maven.compiler.source} + ${maven.compiler.target} + ${project.build.sourceEncoding} + + + + + + + + + + + com.google.code.gson + gson + 2.2.2 + compile + + + + org.aeonbits.owner + owner + ${owner.version} + + + + + javax.ws.rs + jsr311-api + ${jsr311.version} + compile + + + + + org.glassfish.jersey.containers + jersey-container-servlet-core + ${jersey.version} + + + + org.glassfish.jersey.containers + jersey-container-grizzly2-http + ${jersey.version} + + + org.glassfish.jersey.media + jersey-media-multipart + ${jersey.version} + + + + org.glassfish.jersey.media + jersey-media-json-jackson + ${jersey.version} + + + + org.glassfish.jersey.ext.cdi + jersey-weld2-se + ${jersey.version} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-csv + 2.8.4 + + + + org.apache.poi + poi-ooxml + 3.17 + + + + org.slf4j + slf4j-api + ${sl4j.version} + + + org.slf4j + slf4j-log4j12 + ${sl4j.version} + + + + org.mongodb + mongodb-driver + ${mongodb.version} + + + org.mindrot + jbcrypt + ${jbcrypt.version} + + + fr.ensma.lias + rql-core + ${project.version} + + + + \ No newline at end of file diff --git a/rql-backend/rql-api/pom.xml b/rql-backend/rql-api/pom.xml new file mode 100644 index 0000000..06aa4ec --- /dev/null +++ b/rql-backend/rql-api/pom.xml @@ -0,0 +1,37 @@ + + 4.0.0 + rql-api + + fr.ensma.lias + rql-backend + 1.1.0-SNAPSHOT + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-csv + + + javax.ws.rs + jsr311-api + + + org.glassfish.jersey.media + jersey-media-multipart + + + org.glassfish.jersey.media + jersey-media-json-jackson + + + fr.ensma.lias + rql-core + + + com.google.code.gson + gson + + + \ No newline at end of file diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiConstant.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiConstant.java new file mode 100644 index 0000000..49ba60a --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiConstant.java @@ -0,0 +1,8 @@ +package fr.ensma.lias.rql.api; + +/** + * @author Bilal REZKELLAH + */ +public class ApiConstant { + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiParameters.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiParameters.java new file mode 100644 index 0000000..efc5ced --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiParameters.java @@ -0,0 +1,46 @@ +package fr.ensma.lias.rql.api; + +/** + * @author Bilal REZKELLAH + */ +public interface ApiParameters { + + static final String QUERY = "query"; + + static final String TABLE = "table"; + + static final String ID = "id"; + + static final String SUPPORT = "support"; + + static final String CONFIDENCE = "confidence"; + + static final String LEFT_ATTRIBUTES = "leftAttributes"; + + static final String RIGHT_ATTRIBUTES = "rightAttribute"; + + static final String QUERY_TYPE = "QueryType"; + + static final String SQL_QUERY = "sqlQuery"; + + static final String IS_ALL_DATA = "isALLData"; + + static final String IS_TABLE = "isTable"; + + static final String TABLE_NAME = "tableName"; + + static final String SUBSET_WHERE = "subsetWhere"; + + static final String ATTRIBUTES_LIST = "attributesList"; + + static final String IS_CONDITIONAL = "isConditional"; + + static final String CONDITIONAL_WHERE = "conditionalWhere"; + + static final String TOLERENCE = "tolerence"; + + static final String COLUMN_LIST = "columnList"; + + static final String SHEET_INDEX = "sheetIndex"; + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiPaths.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiPaths.java new file mode 100644 index 0000000..17a59fc --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ApiPaths.java @@ -0,0 +1,44 @@ +package fr.ensma.lias.rql.api; + +/** + * @author Bilal REZKELLAH + */ +public interface ApiPaths { + + static final String TABLE = "/table"; + + static final String QUERY = "/query"; + + static final String PROJECT = "/project"; + + static final String USER = "/user"; + + final String HEADER = "/header"; + + static final String TEST = "/test"; + + static final String QUERY_CONSTRUCTION = "/queryconstruction"; + + static final String TYPE = "/typequery"; + + static final String RULE = "/rule"; + + static final String RULECHECK = "/rulecheck"; + + static final String RESULTSET = "/resultset"; + + static final String DB_IMPORT = "/dbimport"; + + static final String TABLE_IMPORT = "/tableImport"; + + static final String AUTHENTICATION = "/authentication"; + + static final String LOGIN = "login"; + + static final String LOGOUT = "logout"; + + static final String UPLOAD_XLSX = "uploadXlsx"; + + static final String SCRIPT_DOWNLOAD = "/scriptdownload"; + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/AuthenticationResource.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/AuthenticationResource.java new file mode 100644 index 0000000..805bfc4 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/AuthenticationResource.java @@ -0,0 +1,32 @@ +package fr.ensma.lias.rql.api; + +import static fr.ensma.lias.rql.api.ApiPaths.AUTHENTICATION; +import static fr.ensma.lias.rql.api.ApiPaths.LOGIN; +import static fr.ensma.lias.rql.api.ApiPaths.LOGOUT; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import fr.ensma.lias.rql.dto.Credentials; + +/** + * @author Bilal REZKELLAH + */ +@Path(AUTHENTICATION) +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface AuthenticationResource { + + @Path(LOGIN) + @POST + Response login(Credentials credentials); + + @Path(LOGOUT) + @DELETE + Response logout(); +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/DataBaseImport.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/DataBaseImport.java new file mode 100644 index 0000000..8d07f18 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/DataBaseImport.java @@ -0,0 +1,56 @@ +package fr.ensma.lias.rql.api; + +import static fr.ensma.lias.rql.api.ApiParameters.COLUMN_LIST; +import static fr.ensma.lias.rql.api.ApiParameters.ID; +import static fr.ensma.lias.rql.api.ApiParameters.TABLE_NAME; +import static fr.ensma.lias.rql.api.ApiParameters.SHEET_INDEX; +import static fr.ensma.lias.rql.api.ApiPaths.DB_IMPORT; +import static fr.ensma.lias.rql.api.ApiPaths.TABLE_IMPORT; +import static fr.ensma.lias.rql.api.ApiPaths.UPLOAD_XLSX; +import static fr.ensma.lias.rql.api.ApiPaths.SCRIPT_DOWNLOAD; +import java.io.InputStream; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; + +import fr.ensma.lias.rql.dto.FilePreview; +import fr.ensma.lias.rql.dto.TableImportResult; + +/** + * @author Bilal REZKELLAH + */ +@Path(DB_IMPORT) +@Produces(MediaType.APPLICATION_JSON) +public interface DataBaseImport { + + @TokenAuthenticated + @Path(UPLOAD_XLSX) + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + FilePreview uploadFile(@FormDataParam("file") InputStream filestream, + @FormDataParam("file") FormDataContentDisposition fileDetail); + + @TokenAuthenticated + @Path("{id}" + TABLE_IMPORT) + @GET + @Consumes(MediaType.APPLICATION_JSON) + TableImportResult tableImport(@PathParam(ID) String id, @QueryParam(SHEET_INDEX) Integer sheetIndex, + @QueryParam(TABLE_NAME) String tableName, @QueryParam("projectID") String projectID, + @QueryParam(COLUMN_LIST) String columnList); + + @TokenAuthenticated + @Path("{id}" + SCRIPT_DOWNLOAD) + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces("text/plain") + Response scriptDownload(@PathParam(ID) String id); + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/NotYetImplementedException.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/NotYetImplementedException.java new file mode 100644 index 0000000..2d746e0 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/NotYetImplementedException.java @@ -0,0 +1,10 @@ +package fr.ensma.lias.rql.api; + +/** + * @author Bilal REZKELLAH + */ +public class NotYetImplementedException extends RuntimeException { + + private static final long serialVersionUID = -1762035426001482646L; + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ProjectResource.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ProjectResource.java new file mode 100644 index 0000000..d337ddf --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/ProjectResource.java @@ -0,0 +1,73 @@ +package fr.ensma.lias.rql.api; + +import static fr.ensma.lias.rql.api.ApiParameters.ID; +import static fr.ensma.lias.rql.api.ApiPaths.PROJECT; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import fr.ensma.lias.rql.dto.Favorite; +import fr.ensma.lias.rql.dto.Project; + +/** + * @author Bilal REZKELLAH + */ +@Path(PROJECT) +@Produces(MediaType.APPLICATION_JSON) +public interface ProjectResource { + + @Path("/allproject") + @GET + @Consumes(MediaType.APPLICATION_JSON) + List getAllProjectByUserID(@QueryParam("userID") String userID); + + @Path("/create") + @POST + @Consumes(MediaType.APPLICATION_JSON) + String createNewProject(Project project); + + @Path("{id}") + @GET + @Consumes(MediaType.APPLICATION_JSON) + Project getProjectById(@PathParam(ID) String id); + + @Path("{id}") + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + boolean deleteProjectById(@PathParam(ID) String id); + + @Path("/update") + @POST // à remplacer par un PUT + @Consumes(MediaType.APPLICATION_JSON) + boolean updateProject(Project project); + + @Path("{id}/favorite") + @GET + @Consumes(MediaType.APPLICATION_JSON) + List getAllFavoriteByProject(@PathParam(ID) String id); + + @Path("{id}/favorite/sql") + @GET + @Consumes(MediaType.APPLICATION_JSON) + List getAllFavoriteSqlQueries(@PathParam(ID) String id); + + @Path("/favorite/{id}") + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + boolean deleteFavoriteById(@PathParam(ID) String id); + + @Path("/favorite/create") + @POST + @Consumes(MediaType.APPLICATION_JSON) + String createNewFavorite(Favorite favorite); + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/QueryConstruction.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/QueryConstruction.java new file mode 100644 index 0000000..b62cffe --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/QueryConstruction.java @@ -0,0 +1,33 @@ +package fr.ensma.lias.rql.api; + +import static fr.ensma.lias.rql.api.ApiParameters.ATTRIBUTES_LIST; +import static fr.ensma.lias.rql.api.ApiParameters.CONDITIONAL_WHERE; +import static fr.ensma.lias.rql.api.ApiParameters.IS_ALL_DATA; +import static fr.ensma.lias.rql.api.ApiParameters.IS_TABLE; +import static fr.ensma.lias.rql.api.ApiParameters.SQL_QUERY; +import static fr.ensma.lias.rql.api.ApiParameters.IS_CONDITIONAL; +import static fr.ensma.lias.rql.api.ApiParameters.QUERY_TYPE; +import static fr.ensma.lias.rql.api.ApiParameters.SUBSET_WHERE; +import static fr.ensma.lias.rql.api.ApiParameters.TABLE_NAME; +import static fr.ensma.lias.rql.api.ApiParameters.TOLERENCE; +import static fr.ensma.lias.rql.api.ApiPaths.QUERY_CONSTRUCTION; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; + +/** + * @author Bilal REZKELLAH + */ +@Path(QUERY_CONSTRUCTION) +public interface QueryConstruction { + + @TokenAuthenticated + @GET + String getQuery(@QueryParam(QUERY_TYPE) String QueryType, @QueryParam(IS_TABLE) String isTable, + @QueryParam(IS_ALL_DATA) String isALLData, @QueryParam(SQL_QUERY) String sqlQuery, + @QueryParam(TABLE_NAME) String tableName, @QueryParam(SUBSET_WHERE) String subsetWhere, + @QueryParam(ATTRIBUTES_LIST) String attributesList, @QueryParam(IS_CONDITIONAL) String isConditional, + @QueryParam(CONDITIONAL_WHERE) String conditionalWhere, @QueryParam(TOLERENCE) String tolerence); + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/QueryResource.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/QueryResource.java new file mode 100644 index 0000000..9516e63 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/QueryResource.java @@ -0,0 +1,105 @@ +package fr.ensma.lias.rql.api; + +import static fr.ensma.lias.rql.api.ApiParameters.CONFIDENCE; +import static fr.ensma.lias.rql.api.ApiParameters.ID; +import static fr.ensma.lias.rql.api.ApiParameters.LEFT_ATTRIBUTES; +import static fr.ensma.lias.rql.api.ApiParameters.RIGHT_ATTRIBUTES; +import static fr.ensma.lias.rql.api.ApiParameters.SUPPORT; +import static fr.ensma.lias.rql.api.ApiPaths.QUERY; +import static fr.ensma.lias.rql.api.ApiPaths.RESULTSET; +import static fr.ensma.lias.rql.api.ApiPaths.RULE; +import static fr.ensma.lias.rql.api.ApiPaths.RULECHECK; +import static fr.ensma.lias.rql.api.ApiPaths.TEST; +import static fr.ensma.lias.rql.api.ApiPaths.TYPE; + +import java.io.IOException; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.media.multipart.FormDataParam; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import fr.ensma.lias.rql.dto.CheckRuleResult; +import fr.ensma.lias.rql.dto.RQLResult; +import fr.ensma.lias.rql.dto.SQLResult; +import fr.ensma.lias.rql.dto.TypeQuery; + +/** + * @author Bilal REZKELLAH + */ +@Path(QUERY) +@Produces(MediaType.APPLICATION_JSON) +public interface QueryResource { + + /** + * Returns the type and the id of the query and save it on the DataBase + * + * @param query The SQL or the RQL query to + */ + @TokenAuthenticated + @Path(TYPE) + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + TypeQuery createQuery(@FormDataParam("query") String query, @FormDataParam("projectID") String projectID); + + /** + * Returns all Rules calculated after executing the RQL query corresponding to + * the ID. + * + * @param id The ID of the query in the database + */ + + @TokenAuthenticated + @Path("{id}" + RULE) + @GET + RQLResult getAllRulesID(@PathParam(ID) String id, @QueryParam(SUPPORT) String support, + @QueryParam(CONFIDENCE) String confidence); + + /** + * Returns a boolean value that indicate if the rule is true or not and if it's + * not true it returns a table of counter examples. + * + * @param id The ID of the query in the database + * @param leftAttributes The left Attributes of the rule to check + * + * @param rightAttribute The right Attributes of the rule to check + */ + + @TokenAuthenticated + @Path("{id}" + RULECHECK) + @GET + CheckRuleResult checkForThisRule(@PathParam(ID) String id, @QueryParam(LEFT_ATTRIBUTES) String leftAttributes, + @QueryParam(RIGHT_ATTRIBUTES) String rightAttribute, @QueryParam(SUPPORT) String support, + @QueryParam(CONFIDENCE) String confidence, @QueryParam("projectID") String projectID); + + /** + * Returns all rows of the table if query is a Select SQL query and returns null + * if it's another type of SQL query + * + * @param id The ID of the SQL query + * @throws IOException + * @throws JsonMappingException + * @throws JsonParseException + */ + + @TokenAuthenticated + @Path("{id}" + RESULTSET) + @GET + SQLResult getResultSet(@PathParam("id") String id, @QueryParam("projectID") String projectID) + throws JsonParseException, JsonMappingException, IOException; + + @TokenAuthenticated + @Path(TEST) + @GET + String isGoodConstructed(@QueryParam("query") String query); + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/SchemaResource.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/SchemaResource.java new file mode 100644 index 0000000..94b2b43 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/SchemaResource.java @@ -0,0 +1,41 @@ +package fr.ensma.lias.rql.api; + +import static fr.ensma.lias.rql.api.ApiParameters.ID; +import static fr.ensma.lias.rql.api.ApiParameters.QUERY_TYPE; +import static fr.ensma.lias.rql.api.ApiPaths.HEADER; +import static fr.ensma.lias.rql.api.ApiPaths.TABLE; + +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import fr.ensma.lias.rql.api.TokenAuthenticated; +import fr.ensma.lias.rql.dto.SchemaResult; + +/** + * @author Bilal REZKELLAH + */ +@Path(TABLE) +@Produces(MediaType.APPLICATION_JSON) +public interface SchemaResource { + + @TokenAuthenticated + @GET + SchemaResult getAllTables(@QueryParam("projectID") String projectID); + + @TokenAuthenticated + @Path("{id}") + @GET + List getAttributesList(@PathParam(ID) String id, @QueryParam(QUERY_TYPE) String queryType, + @QueryParam("projectID") String projectID); + + @TokenAuthenticated + @Path(HEADER) + @GET + List getAllTablesHeader(@QueryParam("projectID") String projectID); +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/TokenAuthenticated.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/TokenAuthenticated.java new file mode 100644 index 0000000..41598eb --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/TokenAuthenticated.java @@ -0,0 +1,17 @@ +package fr.ensma.lias.rql.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.NameBinding; + +/** + * @author Bilal REZKELLAH + */ +@NameBinding +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +public @interface TokenAuthenticated { +} \ No newline at end of file diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/UserResource.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/UserResource.java new file mode 100644 index 0000000..808f4db --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/UserResource.java @@ -0,0 +1,46 @@ +package fr.ensma.lias.rql.api; + +import static fr.ensma.lias.rql.api.ApiPaths.USER; +import static fr.ensma.lias.rql.api.ApiParameters.ID; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.media.multipart.FormDataParam; + +import fr.ensma.lias.rql.dto.User; + +/** + * @author Bilal REZKELLAH + */ +@Path(USER) +@Produces(MediaType.APPLICATION_JSON) +public interface UserResource { + + @GET + @Consumes(MediaType.APPLICATION_JSON) + List getAllCollaborarors(@QueryParam(ID) String userid); + + @Path("/collaborator") + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + boolean deleteCollaborator(@QueryParam("projectid") String projectid, @QueryParam("username") String username); + + @Path("/collaborator") + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + String addCollaborator(@FormDataParam("projectid") String projectid, @FormDataParam("username") String username); + + @Path("/collaborator") + @GET + @Consumes(MediaType.APPLICATION_JSON) + String getCollaborators(@QueryParam("projectid") String projectid, @QueryParam("username") String username); + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/XlsxResource.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/XlsxResource.java new file mode 100644 index 0000000..59d1d6d --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/api/XlsxResource.java @@ -0,0 +1,45 @@ +package fr.ensma.lias.rql.api; + +import static fr.ensma.lias.rql.api.ApiParameters.CONFIDENCE; +import static fr.ensma.lias.rql.api.ApiParameters.ID; +import static fr.ensma.lias.rql.api.ApiParameters.LEFT_ATTRIBUTES; +import static fr.ensma.lias.rql.api.ApiParameters.RIGHT_ATTRIBUTES; +import static fr.ensma.lias.rql.api.ApiParameters.SUPPORT; +import static fr.ensma.lias.rql.api.ApiPaths.RULE; +import static fr.ensma.lias.rql.api.ApiPaths.RULECHECK; +import static fr.ensma.lias.rql.api.ApiPaths.RESULTSET; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +import fr.ensma.lias.rql.api.TokenAuthenticated; + +/** + * @author Bilal REZKELLAH + */ +@Path("/excel") +@Produces("application/vnd.ms-excel") +public interface XlsxResource { + + @Path("{id}" + RULE) + @GET + @TokenAuthenticated + Response getRule(@PathParam(ID) String id, @QueryParam(SUPPORT) String support, + @QueryParam(CONFIDENCE) String confidence); + + @Path("{id}" + RULECHECK) + @GET + @TokenAuthenticated + Response getCounterExample(@PathParam(ID) String id, @QueryParam(LEFT_ATTRIBUTES) String leftAttributes, + @QueryParam(RIGHT_ATTRIBUTES) String rightAttribute, @QueryParam(SUPPORT) String support, + @QueryParam(CONFIDENCE) String confidence, @QueryParam("projectID") String projectID); + + @TokenAuthenticated + @Path("{id}" + RESULTSET) + @GET + Response getResultSet(@PathParam(ID) String id, @QueryParam("projectID") String projectID); +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/CheckRuleResult.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/CheckRuleResult.java new file mode 100644 index 0000000..dc65890 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/CheckRuleResult.java @@ -0,0 +1,35 @@ +package fr.ensma.lias.rql.dto; + +import fr.ensma.lias.rql.rulecheck.CheckResult; + +/** + * @author Bilal REZKELLAH + */ +public class CheckRuleResult { + + private CheckResult checkResult; + + private CheckRuleSummary summary; + + public CheckResult getCheckResult() { + return checkResult; + } + + public void setCheckResult(CheckResult checkResult) { + this.checkResult = checkResult; + } + + public CheckRuleSummary getSummary() { + return summary; + } + + public CheckRuleResult(CheckResult checkResult, CheckRuleSummary summary) { + super(); + this.checkResult = checkResult; + this.summary = summary; + } + + public void setSummary(CheckRuleSummary summary) { + this.summary = summary; + } +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/CheckRuleSummary.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/CheckRuleSummary.java new file mode 100644 index 0000000..e7f527e --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/CheckRuleSummary.java @@ -0,0 +1,70 @@ +package fr.ensma.lias.rql.dto; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class CheckRuleSummary extends ExecutionSummary { + + private int counterExampleNB; + + private int tupleNB; + + private String isTrue; + + private String support; + + private String confidence; + + public String getSupport() { + return support; + } + + public void setSupport(String support) { + this.support = support; + } + + public String getConfidence() { + return confidence; + } + + public void setConfidence(String confidence) { + this.confidence = confidence; + } + + public CheckRuleSummary(long timeExecution, List attributesList, List tuplesList, + int counterExampleNB, int tupleNB, String isTrue, String support, String confidence) { + super(timeExecution, attributesList, tuplesList); + this.counterExampleNB = counterExampleNB; + this.tupleNB = tupleNB; + this.isTrue = isTrue; + this.support = support; + this.confidence = confidence; + } + + public int getCounterExampleNB() { + return counterExampleNB; + } + + public void setCounterExampleNB(int counterExampleNB) { + this.counterExampleNB = counterExampleNB; + } + + public int getTupleNB() { + return tupleNB; + } + + public void setTupleNB(int tupleNB) { + this.tupleNB = tupleNB; + } + + public String getIsTrue() { + return isTrue; + } + + public void setIsTrue(String isTrue) { + this.isTrue = isTrue; + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Credentials.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Credentials.java new file mode 100644 index 0000000..95ed154 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Credentials.java @@ -0,0 +1,61 @@ +package fr.ensma.lias.rql.dto; + +import fr.ensma.lias.rql.dto.Credentials; + +/** + * @author Bilal REZKELLAH + */ +public class Credentials { + + protected String username; + + protected String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((password == null) ? 0 : password.hashCode()); + result = prime * result + ((username == null) ? 0 : username.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Credentials other = (Credentials) obj; + if (password == null) { + if (other.password != null) + return false; + } else if (!password.equals(other.password)) + return false; + if (username == null) { + if (other.username != null) + return false; + } else if (!username.equals(other.username)) + return false; + return true; + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/ExecutionSummary.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/ExecutionSummary.java new file mode 100644 index 0000000..6f4921a --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/ExecutionSummary.java @@ -0,0 +1,47 @@ +package fr.ensma.lias.rql.dto; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class ExecutionSummary { + + private long timeExecution; + + private List attributesList; + + private List tuplesList; + + public long getTimeExecution() { + return timeExecution; + } + + public void setTimeExecution(long timeExecution) { + this.timeExecution = timeExecution; + } + + public List getAttributesList() { + return attributesList; + } + + public void setAttributesList(List attributesList) { + this.attributesList = attributesList; + } + + public List getTuplesList() { + return tuplesList; + } + + public void setTuplesList(List tuplesList) { + this.tuplesList = tuplesList; + } + + public ExecutionSummary(long timeExecution, List attributesList, List tuplesList) { + super(); + this.timeExecution = timeExecution; + this.attributesList = attributesList; + this.tuplesList = tuplesList; + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Favorite.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Favorite.java new file mode 100644 index 0000000..d19b225 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Favorite.java @@ -0,0 +1,78 @@ +package fr.ensma.lias.rql.dto; + +/** + * @author Bilal REZKELLAH + */ +public class Favorite { + + private String id; + + private String name; + + private String query; + + private String creationDate; + + private String projectID; + + private String type; + + private String description; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + public String getCreationDate() { + return creationDate; + } + + public void setCreationDate(String creationDate) { + this.creationDate = creationDate; + } + + public String getProjectID() { + return projectID; + } + + public void setProjectID(String projectID) { + this.projectID = projectID; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/FilePreview.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/FilePreview.java new file mode 100644 index 0000000..7fa626f --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/FilePreview.java @@ -0,0 +1,44 @@ +package fr.ensma.lias.rql.dto; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class FilePreview { + + private List sheetList = new ArrayList(); + private String fileID; + + private boolean goNext; + + public boolean isGoNext() { + return goNext; + } + + public void setGoNext(boolean goNext) { + this.goNext = goNext; + } + + public FilePreview() { + + } + + public String getFileID() { + return fileID; + } + + public void setFileID(String fileID) { + this.fileID = fileID; + } + + public List getSheetList() { + return sheetList; + } + + public void setSheetList(List sheetList) { + this.sheetList = sheetList; + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Project.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Project.java new file mode 100644 index 0000000..0aab8a2 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/Project.java @@ -0,0 +1,85 @@ +package fr.ensma.lias.rql.dto; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class Project { + + private String id; + private String name; + private String description; + private String userid; + private String creationDate; + private String dbType; + private List collaborators; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + + public String getCreationDate() { + return creationDate; + } + + public void setCreationDate(String creationDate) { + this.creationDate = creationDate; + } + + public Project(String id, String name, String userid, String string) { + super(); + this.id = id; + this.name = name; + this.userid = userid; + this.creationDate = string; + } + + public Project() { + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDbType() { + return dbType; + } + + public void setDbType(String dbType) { + this.dbType = dbType; + } + + public List getCollaborators() { + return collaborators; + } + + public void setCollaborators(List collaborators) { + this.collaborators = collaborators; + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/QueryEnumType.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/QueryEnumType.java new file mode 100644 index 0000000..c6044d6 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/QueryEnumType.java @@ -0,0 +1,8 @@ +package fr.ensma.lias.rql.dto; + +/** + * @author Bilal REZKELLAH + */ +public enum QueryEnumType { + RQL, SQL +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/QueryResult.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/QueryResult.java new file mode 100644 index 0000000..09a524c --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/QueryResult.java @@ -0,0 +1,37 @@ +package fr.ensma.lias.rql.dto; + +/** + * @author Bilal REZKELLAH + */ +public class QueryResult { + + private RQLResult rules; // rules + + private SQLResult sqlTuples; // SQLTuples + + public RQLResult getrules() { + return rules; + } + + public void setrules(RQLResult rules) { + this.rules = rules; + } + + public SQLResult getsqlTuples() { + return sqlTuples; + } + + public void setsqlTuples(SQLResult sqlTuples) { + this.sqlTuples = sqlTuples; + } + + public QueryResult(RQLResult rules, SQLResult sqlTuples) { + this.rules = rules; + this.sqlTuples = sqlTuples; + } + + public QueryResult() { + + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RQLResult.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RQLResult.java new file mode 100644 index 0000000..5f35c2c --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RQLResult.java @@ -0,0 +1,40 @@ +package fr.ensma.lias.rql.dto; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class RQLResult { + + private List exactRule; + + private RuleGenerationSummary summary; + + public RuleGenerationSummary getSummary() { + return summary; + } + + public void setSummary(RuleGenerationSummary summary) { + this.summary = summary; + } + + public List getexactRule() { + return exactRule; + } + + public RQLResult(List exactRule, RuleGenerationSummary summary) { + super(); + this.exactRule = exactRule; + this.summary = summary; + } + + public void setexactRule(List exactRule) { + this.exactRule = exactRule; + } + + public RQLResult() { + + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RQLRow.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RQLRow.java new file mode 100644 index 0000000..a756545 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RQLRow.java @@ -0,0 +1,67 @@ +package fr.ensma.lias.rql.dto; + +/** + * @author Bilal REZKELLAH + */ +public class RQLRow { + + private String leftAttributes; + + private String rightAttribute; + + private double support; + + private double confidence; + + private double lift; + + public String getLeftAttributes() { + return leftAttributes; + } + + public void setLeftAttributes(String leftAttributes) { + this.leftAttributes = leftAttributes; + } + + public String getRightAttribute() { + return rightAttribute; + } + + public void setRightAttribute(String rightAttribute) { + this.rightAttribute = rightAttribute; + } + + public RQLRow(String leftAttributes, String rightAttribute) { + super(); + this.leftAttributes = leftAttributes; + this.rightAttribute = rightAttribute; + } + + public RQLRow() { + } + + public double getSupport() { + return support; + } + + public void setSupport(double support) { + this.support = support; + } + + public double getConfidence() { + return confidence; + } + + public void setConfidence(double confidence) { + this.confidence = confidence; + } + + public double getLift() { + return lift; + } + + public void setLift(double lift) { + this.lift = lift; + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RuleGenerationSummary.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RuleGenerationSummary.java new file mode 100644 index 0000000..3c3ef48 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/RuleGenerationSummary.java @@ -0,0 +1,13 @@ +package fr.ensma.lias.rql.dto; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class RuleGenerationSummary extends ExecutionSummary { + + public RuleGenerationSummary(long timeExecution, List attributesList, List tuplesList) { + super(timeExecution, attributesList, tuplesList); + } +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SQLResult.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SQLResult.java new file mode 100644 index 0000000..29aa40f --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SQLResult.java @@ -0,0 +1,51 @@ +package fr.ensma.lias.rql.dto; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class SQLResult { + + public List rows = new ArrayList(); + + public List header = new ArrayList(); + + boolean IsSelect; + + public boolean isIsSelect() { + return IsSelect; + } + + public void setIsSelect(boolean isSelect) { + IsSelect = isSelect; + } + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public List getHeader() { + return header; + } + + public void setHeader(List header) { + this.header = header; + } + + public SQLResult(List header, List rows, Boolean isSelect) { + this.header = header; + this.rows = rows; + this.IsSelect = isSelect; + } + + public SQLResult() { + + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SQLRow.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SQLRow.java new file mode 100644 index 0000000..ef25f64 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SQLRow.java @@ -0,0 +1,24 @@ +package fr.ensma.lias.rql.dto; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class SQLRow { + + private List cels; + + public List getCels() { + return cels; + } + + public void setCels(List cels) { + this.cels = cels; + } + + public SQLRow(List cels) { + super(); + this.cels = cels; + } +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SchemaResult.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SchemaResult.java new file mode 100644 index 0000000..254a2d0 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SchemaResult.java @@ -0,0 +1,27 @@ +package fr.ensma.lias.rql.dto; + +import java.util.List; + +import fr.ensma.lias.rql.database.Table; + +/** + * @author Bilal REZKELLAH + */ +public class SchemaResult { + + private List tables; + + public List
getTables() { + return tables; + } + + public void setTables(List
tables) { + this.tables = tables; + } + + public SchemaResult(List
tables) { + super(); + this.tables = tables; + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SheetContent.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SheetContent.java new file mode 100644 index 0000000..4203506 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/SheetContent.java @@ -0,0 +1,61 @@ +package fr.ensma.lias.rql.dto; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class SheetContent { + + private List rows = new ArrayList(); + + private List header = new ArrayList(); + + private String tableName; + + private Integer nbRow; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public List getHeader() { + return header; + } + + public void setHeader(List header) { + this.header = header; + } + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public SheetContent(List rows, List header, String tableName) { + super(); + this.rows = rows; + this.header = header; + this.tableName = tableName; + } + + public SheetContent() { + + } + + public Integer getNbRow() { + return nbRow; + } + + public void setNbRow(Integer nbRow) { + this.nbRow = nbRow; + } +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/TableImportResult.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/TableImportResult.java new file mode 100644 index 0000000..c7b5f22 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/TableImportResult.java @@ -0,0 +1,53 @@ +package fr.ensma.lias.rql.dto; + +/** + * @author Bilal REZKELLAH + */ +public class TableImportResult { + + private String tableName; + private Integer nbRow; + private Integer nbCol; + private boolean goNext2; + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public Integer getNbRow() { + return nbRow; + } + + public void setNbRow(Integer nbRow) { + this.nbRow = nbRow; + } + + public Integer getNbCol() { + return nbCol; + } + + public void setNbCol(Integer nbCol) { + this.nbCol = nbCol; + } + + public TableImportResult(String tableName, Integer nbRow, Integer nbCol, boolean goNext2) { + super(); + this.tableName = tableName; + this.nbRow = nbRow; + this.nbCol = nbCol; + this.goNext2 = goNext2; + } + + public boolean isGoNext2() { + return goNext2; + } + + public void setGoNext2(boolean goNext2) { + this.goNext2 = goNext2; + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/TypeQuery.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/TypeQuery.java new file mode 100644 index 0000000..740ebc1 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/TypeQuery.java @@ -0,0 +1,72 @@ +package fr.ensma.lias.rql.dto; + +import java.util.List; + +import fr.ensma.lias.rql.baseresults.BaseLine; + +/** + * @author Bilal REZKELLAH + */ +public class TypeQuery { + + private QueryEnumType type; + + private String ruleParsed; + + private String queryKey; + + private List baseContent; + + private List attributesList; + + public List getAttributesList() { + return attributesList; + } + + public void setAttributesList(List attributesList) { + this.attributesList = attributesList; + } + + public TypeQuery(QueryEnumType type, String ruleParsed, String queryKey, List baseContent, + List attributesList) { + super(); + this.setType(type); + this.ruleParsed = ruleParsed; + this.queryKey = queryKey; + this.baseContent = baseContent; + this.attributesList = attributesList; + } + + public String getQueryKey() { + return queryKey; + } + + public void setQueryKey(String queryKey) { + this.queryKey = queryKey; + } + + public List getBaseContent() { + return baseContent; + } + + public void setBaseContent(List baseContent) { + this.baseContent = baseContent; + } + + public String getRuleParsed() { + return ruleParsed; + } + + public void setRuleParsed(String ruleParsed) { + this.ruleParsed = ruleParsed; + } + + public QueryEnumType getType() { + return type; + } + + public void setType(QueryEnumType type) { + this.type = type; + } + +} diff --git a/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/User.java b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/User.java new file mode 100644 index 0000000..9ed4f86 --- /dev/null +++ b/rql-backend/rql-api/src/main/java/fr/ensma/lias/rql/dto/User.java @@ -0,0 +1,55 @@ +package fr.ensma.lias.rql.dto; + +/** + * @author Bilal REZKELLAH + */ +public class User { + + private Integer userID; + private String firstName; + private String lastName; + private String username; + + public User(Integer userID, String firstName, String lastName, String username) { + super(); + this.userID = userID; + this.firstName = firstName; + this.lastName = lastName; + this.username = username; + } + + public User() { + } + + public Integer getUserID() { + return userID; + } + + public void setUserID(Integer userID) { + this.userID = userID; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/rql-backend/rql-api/src/main/resources/DELETE.me b/rql-backend/rql-api/src/main/resources/DELETE.me new file mode 100644 index 0000000..e69de29 diff --git a/rql-backend/rql-api/src/test/java/DELETE.me b/rql-backend/rql-api/src/test/java/DELETE.me new file mode 100644 index 0000000..e69de29 diff --git a/rql-backend/rql-api/src/test/resources/DELETE.me b/rql-backend/rql-api/src/test/resources/DELETE.me new file mode 100644 index 0000000..e69de29 diff --git a/rql-backend/rql-core/pom.xml b/rql-backend/rql-core/pom.xml new file mode 100644 index 0000000..2787382 --- /dev/null +++ b/rql-backend/rql-core/pom.xml @@ -0,0 +1,68 @@ + + 4.0.0 + rql-core + Core module of RQL platform + + + fr.ensma.lias + rql-backend + 1.1.0-SNAPSHOT + + + + + 11.2.0.4 + 2.6 + 42.2.1 + 20180130 + 2.8.4 + + + UTF-8 + + + + + org.codehaus.mojo + javacc-maven-plugin + ${javacc.version} + + src + + + + generate-javacc + generate-sources + + javacc + + + + + + + + + com.oracle.database.jdbc + ojdbc6 + ${ojdbc.version} + + + org.postgresql + postgresql + ${postgresql.version} + + + org.json + json + ${json.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind.version} + + + \ No newline at end of file diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/RQLManager.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/RQLManager.java new file mode 100644 index 0000000..ba01322 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/RQLManager.java @@ -0,0 +1,356 @@ +package fr.ensma.lias.rql; + +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +import fr.ensma.lias.rql.baseresults.BaseLine; +import fr.ensma.lias.rql.cfg.RqlCoreConf; +import fr.ensma.lias.rql.database.Database; +import fr.ensma.lias.rql.database.MysqlDB; +import fr.ensma.lias.rql.database.OracleDB; +import fr.ensma.lias.rql.database.PostgresqlDB; +import fr.ensma.lias.rql.dfg.Dfg; +import fr.ensma.lias.rql.rqlgrammar.RQLParser; +import fr.ensma.lias.rql.rulesgrammar.ParseException; +import fr.ensma.lias.rql.rulesgrammar.RulesParser; + +/** + * @author Gouriou Benjamin + * @author Bilal REZKELLAH + */ +public class RQLManager implements Closeable { + + private String agFile = null; + + private PrintStream output = null; + + private OutputStream outStream = null; + + private Database db = null; + + private long startTime; + + private String shdPath; + + private RqlCoreConf rqlCoreConf = new RqlCoreConf(); + + public RQLManager(String AgFile) { + this.agFile = AgFile; + } + + public RQLManager(RqlCoreConf cfgConf) { + this.rqlCoreConf = cfgConf; + this.shdPath = cfgConf.getPathToShd(); + agFile = cfgConf.getTmpAgFile(); + startTime = System.currentTimeMillis(); + } + + /** + * Initializes an RQL context without log output. + * + * @param tmpAgFile the URL of the temporary file to store the agree set + */ + public RQLManager(String tmpAgFile, String shdPath) { + if (tmpAgFile == null) { + throw new NullPointerException("Temporary file can not be null."); + } + this.shdPath = shdPath; + agFile = tmpAgFile; + startTime = System.currentTimeMillis(); + } + + /** + * Initializes an RQL context. + * + * @param tmpAgFile the URL of the temporary file to store the agree set + * @param log the output stream, or null to disable + */ + public RQLManager(String tmpAgFile, String shdPath, PrintStream log) { + this(tmpAgFile, shdPath); + output = log; + } + + /** + * Initializes an RQL context. + * + * @param tmpAgFile the URL of the temporary file to store the agree set + * @param log the URL of the output file, or null to disable + * + * @throws IOException IO-related error + */ + public RQLManager(String tmpAgFile, String shdPath, String log) throws IOException { + this(tmpAgFile, shdPath); + if (log != null) { + output = new PrintStream(log); + } + } + + /** + * Executes an RQL query. + * + * @param rqlQuery an RQL query + * @param outFilename the URL of the output file for rules + * + * @throws SQLException SQL-related error + * @throws IOException IO-related error + * @throws InterruptedException Interruption during the execution of DFG + * @throws rulesgrammar.ParseException Wrong syntax in rules generated by DFG + * @throws rqlgrammar.ParseException Wrong syntax in the RQL query + */ + public List executeQuery(String rqlQuery, String outFilename) + throws SQLException, IOException, InterruptedException, fr.ensma.lias.rql.rulesgrammar.ParseException, + fr.ensma.lias.rql.rqlgrammar.ParseException { + + log("RQL query:\n" + rqlQuery); + log("parsing RQL query"); + RQLParser parser = RQLParser.parse(rqlQuery); + System.out.println(rqlQuery); + log("generating SQL query"); + + String sqlQuery = ""; + if (rqlCoreConf.getRqlDbType().equals("oracle")) { + sqlQuery = parser.oracleQuery(); + } else if (rqlCoreConf.getRqlDbType().equals("postgresql")) { + sqlQuery = parser.postgresQuery(); + } else if (rqlCoreConf.getRqlDbType().equals("mysql")) { + sqlQuery = parser.mysqlQuery(); + } + log("SQL query:\n" + sqlQuery); + + log("initializing oracle connection"); + if (rqlCoreConf.getRqlDbType().equals("oracle")) { + db = new OracleDB(); + } else if (rqlCoreConf.getRqlDbType().equals("postgresql")) { + db = new PostgresqlDB(); + } else if (rqlCoreConf.getRqlDbType().equals("mysql")) { + db = new MysqlDB(); + } + db.open(rqlCoreConf.getRqlDbHost(), rqlCoreConf.getRqlDbPort(), rqlCoreConf.getRqlDbName(), + rqlCoreConf.getRqlDbAdminLogin(), rqlCoreConf.getRqlDbAdminPwd()); + + System.out.println("\nconnexion etablie \n"); + + log("oracle query"); + ResultSet results = db.executeQuery(sqlQuery); + + log("printing results"); + resultsToFile(results, parser.getAttributeList().size()); + results.close(); + db.close(); + + log("generating rules"); + int tailleMax = parser.getAttributeList().size(); + Dfg dfg = new Dfg(agFile, agFile + "_rules.txt", 0, 0, tailleMax, shdPath); + /* + * Dfg dfg = new Dfg(agFile + "_rules.txt", tailleMax, + * parser.getAttributeList().size()); // set agree set while (results.next()) { + * int card = results.getInt(1); String ag = results.getString(2); if (ag != + * null && !ag.equals("")) { String[] elems = ag.split(" "); int[] agr = new + * int[elems.length]; for (int i = 0; i < elems.length; i++) { agr[i] = + * Integer.parseInt(elems[i]); } dfg.init(card, agr); } } results.close(); + * db.close(); done + */ + try { + dfg.execute(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(-1); + } + + log("translating rules"); + List ruleResults = new ArrayList(); + int[] counts = new int[2]; + outStream = new BufferedOutputStream(new FileOutputStream(outFilename), 1024); + RulesParser.translate(agFile + "_rules.txt", outStream, parser.getAttributeList(), ruleResults, 100000, counts); + log("RQL query computed"); + return ruleResults; + } + + private void log(String log) { + if (output != null) { + output.println((System.currentTimeMillis() - startTime) + "\t" + log); + } + } + + /** + * Writes the agree set (results of the SQL query) to the file tmpAgFile + * specified in the constructor. + * + * @param result the result of the SQL query + * @param attSize the number of attributes used in rules + * + * @throws SQLException SQL-related error + * @throws IOException IO-related error + */ + private void resultsToFile(ResultSet result, int attSize) throws SQLException, IOException { + StringBuffer buf = new StringBuffer(); + + /* cardinality of the relation: sum of count */ + int cardinality = 0; + while (result.next()) { + cardinality += result.getInt(1); + buf.append(result.getString(1)); + String ag = result.getString(2); + if (ag != null && !ag.equals("")) { + buf.append(" " + ag.trim()); + } + buf.append("\n"); + } + + BufferedWriter out = new BufferedWriter(new FileWriter(agFile)); + + out.write(Integer.toString(attSize) + "\n"); + for (int i = 0; i < attSize; i++) { + if (i > 0) { + out.write(" "); + } + out.write(Integer.toString(i)); + } + out.write("\n" + Integer.toString(attSize) + " " + Integer.toString(cardinality) + "\n"); + out.write(buf.toString()); + + out.flush(); + out.close(); + } + + public void resultsToFile2(List result, int attSize) throws SQLException, IOException { + StringBuffer buf = new StringBuffer(); + + /* cardinality of the relation: sum of count */ + int cardinality = 0; + ListIterator it = result.listIterator(); + while (it.hasNext()) { + BaseLine ligne = it.next(); + cardinality += Integer.parseInt(ligne.getCount()); + buf.append(ligne.getCount()); + if (ligne.getAg() != null && !ligne.getAg().equals("")) { + buf.append(" " + ligne.getAg().trim()); + } + buf.append("\n"); + } + System.out.println(agFile); + BufferedWriter out = new BufferedWriter(new FileWriter(agFile)); + + out.write(Integer.toString(attSize) + "\n"); + for (int i = 0; i < attSize; i++) { + if (i > 0) { + out.write(" "); + } + out.write(Integer.toString(i)); + } + out.write("\n" + Integer.toString(attSize) + " " + Integer.toString(cardinality) + "\n"); + out.write(buf.toString()); + + out.flush(); + out.close(); + } + + /** + * Updates the temporary file used to store the agree set. + * + * @param tmpAgFile the URL of the temporary file + */ + public void setTemporaryFile(String tmpAgFile) { + agFile = tmpAgFile; + } + + public void executeDFG(String fileIn, String fileOut, int tailleMax, double support, double confidence, + String m_execpath) { + Dfg dfg = new Dfg(fileIn, fileOut, support, confidence, tailleMax, m_execpath); + try { + dfg.execute(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(-1); + } + } + + public RQLResults translate(String ruleFile, String outFile, List parseAttributeList) + throws ParseException, IOException { + List listrqlExact = new ArrayList(); + List ExactRule = new ArrayList(); + List leftAtts; + String[] sides; + String[] rightSides; + Rule rule = new Rule(); + int[] counts = new int[2]; + OutputStream outStream = null; + outStream = new BufferedOutputStream(new FileOutputStream(ruleFile), 1024); + RulesParser.translate(outFile, outStream, parseAttributeList, listrqlExact, 100000, counts); + DecimalFormat df = new DecimalFormat(); + df.setMaximumFractionDigits(3); // arrondi à 2 chiffres apres la virgules + for (int i = 0; i < listrqlExact.size(); i++) { + rule = new Rule(); + sides = listrqlExact.get(i).split("=>"); + rightSides = sides[1].split("\\s"); + rule.setRightAttributes(rightSides[1]); + rule.setSupport(Double.valueOf( + df.format(Double.valueOf(rightSides[5]) / Double.valueOf(rightSides[2])).replace(',', '.'))); + rule.setConfidence(Double.valueOf( + df.format(Double.valueOf(rightSides[5]) / Double.valueOf(rightSides[3])).replace(',', '.'))); + rule.setLift(Double.valueOf(df + .format(Double.valueOf( + rule.getConfidence() / (Double.valueOf(rightSides[4]) / Double.valueOf(rightSides[2])))) + .replace(',', '.'))); + leftAtts = new ArrayList(); + for (String w : sides[0].split("\\s")) { + leftAtts.add(w); + } + rule.setLeftAttributes(leftAtts); + ExactRule.add(rule); + } + return new RQLResults(ExactRule); + } + + /** + * Sets the output to trace the RQL query, the SQL query and execution times. + * + * @param log the URL of the output file, or null to disable + * + * @throws IOException IO-related error + */ + public void setOutput(String log) throws IOException { + if (output != null) { + output.flush(); + output.close(); + } + output = new PrintStream(log); + } + + /** + * Sets the output to trace the RQL query, the SQL query and execution times. + * + * @param log the output stream, or null to disable + */ + public void setOutput(PrintStream log) { + if (output != null) { + output.flush(); + output.close(); + } + output = log; + } + + /** + * Closes the connection to the DBMS and file handlers. + */ + public void close() throws IOException { + if (output != null) { + output.flush(); + output.close(); + output = null; + } + db.close(); + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/RQLResults.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/RQLResults.java new file mode 100644 index 0000000..eb86b1e --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/RQLResults.java @@ -0,0 +1,28 @@ +package fr.ensma.lias.rql; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class RQLResults { + + private List exactRules; + + public List getExactRules() { + return exactRules; + } + + public void setExactRules(List exactRules) { + this.exactRules = exactRules; + } + + public RQLResults() { + + } + + public RQLResults(List exactRules) { + super(); + this.exactRules = exactRules; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/Rule.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/Rule.java new file mode 100644 index 0000000..bf5bbb1 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/Rule.java @@ -0,0 +1,62 @@ +package fr.ensma.lias.rql; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class Rule { + + private List leftAttributes; + + private String rightAttributes; + + private double support; + + private double confidence; + + private double lift; + + public Rule() { + } + + public List getLeftAttributes() { + return leftAttributes; + } + + public void setLeftAttributes(List leftAttributes) { + this.leftAttributes = leftAttributes; + } + + public String getRightAttributes() { + return rightAttributes; + } + + public void setRightAttributes(String rightAttributes) { + this.rightAttributes = rightAttributes; + } + + public double getSupport() { + return support; + } + + public void setSupport(double support) { + this.support = support; + } + + public double getConfidence() { + return confidence; + } + + public void setConfidence(double confidence) { + this.confidence = confidence; + } + + public double getLift() { + return lift; + } + + public void setLift(double lift) { + this.lift = lift; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/baseresults/BaseLine.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/baseresults/BaseLine.java new file mode 100644 index 0000000..790af78 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/baseresults/BaseLine.java @@ -0,0 +1,32 @@ +package fr.ensma.lias.rql.baseresults; + +/** + * @author Bilal REZKELLAH + */ +public class BaseLine { + + private String count; + + private String ag; + + public String getCount() { + return count; + } + + public void setCount(String count) { + this.count = count; + } + + public String getAg() { + return ag; + } + + public void setAg(String ag) { + this.ag = ag; + } + + public BaseLine(String count, String ag) { + this.count = count; + this.ag = ag; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/baseresults/BaseResult.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/baseresults/BaseResult.java new file mode 100644 index 0000000..dd96650 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/baseresults/BaseResult.java @@ -0,0 +1,32 @@ +package fr.ensma.lias.rql.baseresults; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class BaseResult { + + private List content = new ArrayList(); + + public void resultsToList(ResultSet result) throws SQLException { + BaseLine ligne; + while (result.next()) { + String count = result.getString(1); + String ag = result.getString(2); + ligne = new BaseLine(count, ag); + this.content.add(ligne); + } + } + + public List getContent() { + return content; + } + + public void setContent(List content) { + this.content = content; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/CoreConfig.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/CoreConfig.java new file mode 100644 index 0000000..6f0aeba --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/CoreConfig.java @@ -0,0 +1,80 @@ +package fr.ensma.lias.rql.cfg; + +/** + * @author Bilal REZKELLAH + */ +public class CoreConfig { + + private String rqlDbName; + + private String rqlDbHost; + + private String rqlDbType; + + private Integer rqlDbPort; + + private String rqlDbAdminLogin; + + private String rqlDbAdminPwd; + + public String getRqlDbName() { + return rqlDbName; + } + + public void setRqlDbName(String rqlDbName) { + this.rqlDbName = rqlDbName; + } + + public CoreConfig() { + } + + public CoreConfig(String rqlDbName, String rqlDbHost, Integer rqlDbPort, String rqlDbType, String rqlDbAdminLogin, + String rqlDbAdminPwd) { + this.rqlDbName = rqlDbName; + this.rqlDbHost = rqlDbHost; + this.rqlDbType = rqlDbType; + this.rqlDbPort = rqlDbPort; + this.rqlDbAdminLogin = rqlDbAdminLogin; + this.rqlDbAdminPwd = rqlDbAdminPwd; + } + + public String getRqlDbHost() { + return rqlDbHost; + } + + public void setRqlDbHost(String rqlDbHost) { + this.rqlDbHost = rqlDbHost; + } + + public String getRqlDbType() { + return rqlDbType; + } + + public void setRqlDbType(String rqlDbType) { + this.rqlDbType = rqlDbType; + } + + public Integer getRqlDbPort() { + return rqlDbPort; + } + + public void setRqlDbPort(Integer rqlDbPort) { + this.rqlDbPort = rqlDbPort; + } + + public String getRqlDbAdminLogin() { + return rqlDbAdminLogin; + } + + public void setRqlDbAdminLogin(String rqlDbAdminLogin) { + this.rqlDbAdminLogin = rqlDbAdminLogin; + } + + public String getRqlDbAdminPwd() { + return rqlDbAdminPwd; + } + + public void setRqlDbAdminPwd(String rqlDbAdminPwd) { + this.rqlDbAdminPwd = rqlDbAdminPwd; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/RqlCoreConf.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/RqlCoreConf.java new file mode 100644 index 0000000..c6a4d3f --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/RqlCoreConf.java @@ -0,0 +1,37 @@ +package fr.ensma.lias.rql.cfg; + +/** + * @author Bilal REZKELLAH + */ +public class RqlCoreConf extends CoreConfig { + + private String pathToShd; + private String tmpAgFile; + + public RqlCoreConf(String rqlDbName, String rqlDbHost, Integer rqlDbPort, String rqlDbType, String rqlDbAdminLogin, + String rqlDbAdminPwd, String pathToShd, String tmpAgFile) { + super(rqlDbName, rqlDbHost, rqlDbPort, rqlDbType, rqlDbAdminLogin, rqlDbAdminPwd); + this.pathToShd = pathToShd; + this.tmpAgFile = tmpAgFile; + } + + public RqlCoreConf() { + super(); + }; + + public String getPathToShd() { + return pathToShd; + } + + public void setPathToShd(String pathToShd) { + this.pathToShd = pathToShd; + } + + public String getTmpAgFile() { + return tmpAgFile; + } + + public void setTmpAgFile(String tmpAgFile) { + this.tmpAgFile = tmpAgFile; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/SqlCoreConf.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/SqlCoreConf.java new file mode 100644 index 0000000..884dced --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/cfg/SqlCoreConf.java @@ -0,0 +1,17 @@ +package fr.ensma.lias.rql.cfg; + +/** + * @author Bilal REZKELLAH + */ +public class SqlCoreConf extends CoreConfig { + + public SqlCoreConf() { + super(); + } + + public SqlCoreConf(String rqlDbName, String rqlDbHost, Integer rqlDbPort, String rqlDbType, String rqlDbAdminLogin, + String rqlDbAdminPwd) { + super(rqlDbName, rqlDbHost, rqlDbPort, rqlDbType, rqlDbAdminLogin, rqlDbAdminPwd); + + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Column.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Column.java new file mode 100644 index 0000000..3907212 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Column.java @@ -0,0 +1,34 @@ +package fr.ensma.lias.rql.database; + +/** + * @author Bilal REZKELLAH + */ +public class Column { + + private String columnName; + + private String columnType; + + public Column(String columnName, String columnType) { + super(); + this.columnName = columnName; + this.columnType = columnType; + } + + public String getColumnName() { + return columnName; + } + + public void setColumnName(String columnName) { + this.columnName = columnName; + } + + public String getColumnType() { + return columnType; + } + + public void setColumnType(String columnType) { + this.columnType = columnType; + } + +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/DataBaseSchema.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/DataBaseSchema.java new file mode 100644 index 0000000..fa04888 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/DataBaseSchema.java @@ -0,0 +1,24 @@ +package fr.ensma.lias.rql.database; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class DataBaseSchema { + + private List
tables; + + public List
getTables() { + return tables; + } + + public void setTables(List
tables) { + this.tables = tables; + } + + public DataBaseSchema(List
tables) { + super(); + this.tables = tables; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/DataBaseType.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/DataBaseType.java new file mode 100644 index 0000000..0deb72d --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/DataBaseType.java @@ -0,0 +1,8 @@ +package fr.ensma.lias.rql.database; + +/** + * @author Bilal REZKELLAH + */ +public enum DataBaseType { + oracle, postgresql, mysql +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Database.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Database.java new file mode 100644 index 0000000..a2ece48 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Database.java @@ -0,0 +1,28 @@ +package fr.ensma.lias.rql.database; + +import java.io.Closeable; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * @author Bilal REZKELLAH + */ +public abstract interface Database extends Closeable { + + /** + * Executes a SQL query. + * + * @param query a SQL query + * @return the result of the query + * + * @throws SQLException SQL-related error + */ + public ResultSet executeQuery(String query) throws SQLException; + + /** + * Initializes the connection to the DBMS. + * + * @throws SQLException SQL-related error + */ + public void open(String host, int port, String database, String user, String password) throws SQLException; +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/MysqlDB.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/MysqlDB.java new file mode 100644 index 0000000..71e32ce --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/MysqlDB.java @@ -0,0 +1,46 @@ +package fr.ensma.lias.rql.database; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * @author Bilal REZKELLAH + */ +public class MysqlDB implements Database { + + private Connection cx; + + private Statement stmt; + + public ResultSet executeQuery(String query) throws SQLException { + ResultSet rs = null; + boolean isSelect = stmt.execute(query); + if (isSelect) { + rs = stmt.getResultSet(); + } + return rs; + } + + public void open(String host, int port, String database, String user, String password) throws SQLException { + try { + Class.forName("com.mysql.jdbc.Driver").newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + cx = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, user, password); + stmt = cx.createStatement(); + } + + public void close() throws IOException { + try { + stmt.close(); + cx.close(); + } catch (SQLException e) { + throw new IOException(e); + } + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/OracleDB.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/OracleDB.java new file mode 100644 index 0000000..9218799 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/OracleDB.java @@ -0,0 +1,65 @@ +package fr.ensma.lias.rql.database; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import fr.ensma.lias.rql.database.Database; +import oracle.jdbc.pool.OracleDataSource; + +/** + * @author Bilal REZKELLAH + */ +public class OracleDB implements Database { + + private OracleDataSource ora; + + private Connection cx = null; + + private Statement stmt = null; + + private ResultSet rs = null; + + @Override + public ResultSet executeQuery(String query) throws SQLException { + if (cx == null) { + cx = ora.getConnection(); + } + if (stmt == null) { + stmt = cx.createStatement(); + } + boolean isSelect = stmt.execute(query); + if (isSelect) { + rs = stmt.getResultSet(); + } else { + rs = null; + } + return rs; + } + + @Override + public void open(String host, int port, String database, String user, String password) throws SQLException { + ora = new OracleDataSource(); + ora.setDriverType("thin"); + // ora.setServerName("134.214.104.91"); + ora.setServerName(host); + ora.setPortNumber(port); + ora.setDatabaseName(database); + ora.setUser(user); + ora.setPassword(password); + ora.setLoginTimeout(20); + cx = ora.getConnection(); + stmt = cx.createStatement(); + } + + public void close() throws IOException { + try { + stmt.close(); + cx.close(); + } catch (SQLException e) { + throw new IOException(e); + } + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/PostgresqlDB.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/PostgresqlDB.java new file mode 100644 index 0000000..b500320 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/PostgresqlDB.java @@ -0,0 +1,50 @@ +package fr.ensma.lias.rql.database; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * @author Bilal REZKELLAH + */ +public class PostgresqlDB implements Database { + + private Connection cx; + private Statement stmt; + + @Override + public void close() throws IOException { + try { + stmt.close(); + cx.close(); + } catch (SQLException e) { + throw new IOException(e); + } + + } + + @Override + public ResultSet executeQuery(String query) throws SQLException { + ResultSet rs = null; + boolean isSelect = stmt.execute(query); + if (isSelect) { + rs = stmt.getResultSet(); + } + return rs; + } + + @Override + public void open(String host, int port, String database, String user, String password) throws SQLException { + try { + Class.forName("org.postgresql.Driver").newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + cx = DriverManager.getConnection("jdbc:postgresql://" + host + ":" + port + "/" + database, user, password); + + stmt = cx.createStatement(); + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Table.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Table.java new file mode 100644 index 0000000..5943c69 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/database/Table.java @@ -0,0 +1,38 @@ +package fr.ensma.lias.rql.database; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class Table { + + private String tableName; + + private List columnsName; + + public Table(String tableName, List columnsName) { + super(); + this.tableName = tableName; + this.columnsName = columnsName; + } + + public Table() { + } + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public List getColumnsName() { + return columnsName; + } + + public void setColumnsName(List columnsName) { + this.columnsName = columnsName; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/AttributSet.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/AttributSet.java new file mode 100644 index 0000000..9f5e6a6 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/AttributSet.java @@ -0,0 +1,220 @@ +package fr.ensma.lias.rql.dfg; + +import java.util.Iterator; +import java.util.TreeSet; + +/** + * @author Benjamin GOURIOU + */ +public class AttributSet { + + private TreeSet m_at; + + private int m_count; + + public AttributSet() { + this.m_count = 1; + } + + public AttributSet(TreeSet at) { + this.m_count = 1; + m_at = at; + } + + public AttributSet(String line) { + m_count = 1; + String val[] = line.split(" "); + m_at = new TreeSet(); + for (String curr : val) + m_at.add(Integer.valueOf(curr)); + } + + public AttributSet(AttributSet inAttr) { + this.m_count = inAttr.m_count; + this.m_at = (TreeSet) inAttr.m_at.clone(); + } + + public void clear() { + m_at.clear(); + } + + public void insert(int x) { + m_at.add(x); + } + + public boolean empty() { + return m_at.isEmpty(); + } + + public int size() { + return m_at.size(); + } + + public boolean find(int valeur) { + return (m_at.contains(valeur)); + } + + public void erase(int v) { + m_at.remove(v); + } + + public void incr() { + m_count++; + } + + @Override + public String toString() { + StringBuilder tmp = new StringBuilder("{"); + int size = m_at.size(); + if (size > 0) { + /* + * for (int i=0; i iter = m_at.iterator(); + while (iter.hasNext()) + tmp.append(iter.next()).append(","); + tmp.replace(tmp.length() - 1, tmp.length(), "}, "); + } else + tmp.append("}, "); + + tmp.append(this.m_count); + return tmp.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof AttributSet) { + AttributSet var = (AttributSet) obj; + return this.is_equal(var); + } + return false; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 17 * hash + (this.m_at != null ? this.m_at.hashCode() : 0); + hash = 17 * hash + this.m_count; + return hash; + } + + /******** + * Renvoie true si l'attributSet X est un sous-ensemble strict Y + ********/ + boolean is_strictsubset(AttributSet Y) { + if ((m_at.size()) >= Y.size()) + return false; + else + return (Y.m_at.containsAll(this.m_at)); + } + + /******** Renvoie true si l'attributSet X est inclus dans Y ********/ + boolean is_subset(AttributSet Y) { + return (Y.m_at.containsAll(this.m_at)); + } + + int containsSubSet(AttributSet Y) { + // int curAttr=0; + Iterator iter = m_at.iterator(); + Iterator iterY = Y.m_at.iterator(); + int curr = -1, currY = iterY.next(); + while (iterY.hasNext()) { + while (iter.hasNext() && ((curr = iter.next()) < currY)) { + } + + if (currY != curr) + return 0; + else + iterY.next(); + } + return 1; + } + + /* don't use, prefer the function based on the std methods, below */ + int containsSubSetAndRightPart(AttributSet Y, int rhs, MutableInt countRightPart) { + boolean foundRightPart = false; + Iterator iter = m_at.iterator(); + Iterator iterY = Y.m_at.iterator(); + int curr = -1, currY; + while (iterY.hasNext()) { + currY = iterY.next(); + + while (iter.hasNext() && ((curr = iter.next()) < currY)) + if (curr == rhs) + foundRightPart = true; + + if (currY != curr) + return 0; + else if (curr == rhs) + foundRightPart = true; + } + if (foundRightPart) + countRightPart.add(this.m_count); // update of right part cpt if + // found + else // if not found maybe the right part is greater than the last value + // checked in the loop + { + while (iter.hasNext() && ((curr = iter.next()) < rhs)) { + } // so check the rest + if (curr == rhs) + countRightPart.add(this.m_count); + } + + return m_count; + } + + /* + * Check that the attribuSet contains or not the attributset Y. Return m_count + * if it contains it nor 0 + */ + int containsSubSetAndRightPartStd(AttributSet Y, int rhs, MutableInt countRightPart) { + boolean foundleftPart = this.m_at.containsAll(Y.m_at); + if (foundleftPart) { + if (this.m_at.contains(rhs)) + countRightPart.add(this.m_count); + return m_count; + } + + return 0; + } + + /******** Renvoie true si l'attributSet X contient Y ********/ + boolean is_superset(AttributSet Y) { + return (this.m_at.containsAll(Y.m_at)); + } + + /******** Renvoie true si l'attributSet X égal Y ********/ + boolean is_equal(AttributSet Y) { + int size = 0; + if ((size = this.m_at.size()) == Y.size()) { + /* + * for (int i=0; i iter = m_at.iterator(); + while (iter.hasNext()) + if (!Y.m_at.contains(iter.next())) + return false; + } else + return false; + + return true; + } + + /*** GETTERS AND SETTERS ***/ + public int getM_count() { + return m_count; + } + + public void setM_count(int m_count) { + this.m_count = m_count; + } + + public TreeSet getM_at() { + return m_at; + } + + public void setM_at(TreeSet m_at) { + this.m_at = m_at; + } + +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/AttributeCalculation.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/AttributeCalculation.java new file mode 100644 index 0000000..0c3525c --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/AttributeCalculation.java @@ -0,0 +1,489 @@ +package fr.ensma.lias.rql.dfg; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.TreeSet; + +import fr.ensma.lias.rql.dfg.KnownException; +import fr.ensma.lias.rql.dfg.Set_AttributSet; +import fr.ensma.lias.rql.dfg.ThreadRunException; + +/** + * @author Benjamin GOURIOU + */ +public class AttributeCalculation implements Runnable { + + private Set_AttributSet m_inf; // Inf + + private Set_AttributSet m_cinf; // Complementaires de Inf + + private Set_AttributSet m_lhs; // lhs + + private AttributSet m_rhs; // rhs + + private Dfg m_appli; + + private int m_supp[]; + + private Set_AttributSet m_base; + + private int m_A; + + private File m_fileCinf = null; + + private File m_fileRet = null; + + private BufferedReader m_reader = null; + + private BufferedWriter m_writer = null; + + private Process m_process = null; + + private long calculInfTime = 0; + + private long concatRulesCGLTime = 0; + + private long calculCInfTime = 0; + + private long calculLhsUnoTime = 0; + + private long writeRulesCCTime = 0; + + private double supportSeuil = 0; + + private double confidenceSeuil = 0; + + public AttributeCalculation(Dfg appli, int A, double support, double confidence) { + m_inf = new Set_AttributSet(); + m_cinf = new Set_AttributSet(); + m_lhs = new Set_AttributSet(); + this.supportSeuil = support; + this.confidenceSeuil = confidence; + m_appli = appli; + m_supp = appli.m_supp; + m_base = appli.m_base; + m_A = A; + } + + @Override + public void run() { + try { + CalculRegles(); + m_appli.addTimes(calculInfTime, concatRulesCGLTime, calculCInfTime, calculLhsUnoTime, writeRulesCCTime); + } catch (Exception ex) { + ex.printStackTrace(); + ThreadRunException exception = new ThreadRunException(ex, this.m_A); + this.m_appli.setThreadException(exception); + throw exception; + } + } + + /** + * Calcul des regles pour chaque attribut central A + * + * @throws Exception + */ + void CalculRegles() throws Exception { + long start = System.currentTimeMillis(); + calculInf(); + long end = System.currentTimeMillis(); + calculInfTime = end - start; + start = end; + + // insertion des regles approximatives + StringBuilder builder = concatRulesCGL(); + m_appli.writeInStream(builder); + builder = null; + end = System.currentTimeMillis(); + concatRulesCGLTime = end - start; + start = end; + + // System.out.println("Calcul de CInf(A) : complémentaires de Inf(A)"); + StringBuilder sbCinf = calculCInf(); + m_inf.clear(); + end = System.currentTimeMillis(); + calculCInfTime = end - start; + start = end; + + // System.out.println("Calcul de lhs(A) : transmin, parties gauches des + // règles"); + /* + * double t1 = System.currentTimeMillis(); + */ + try { + this.calculLhsUnoTakeaki(sbCinf); + } catch (KnownException ex) { + throw ex; + } catch (Exception ex) { + throw new Exception("Lhs_Uno : Unknown exception caught caused the fail of left parts rules generation."); + } + end = System.currentTimeMillis(); + calculLhsUnoTime = end - start; + start = end; + this.writeRulesCC(); + end = System.currentTimeMillis(); + writeRulesCCTime = end - start; + start = end; + + } + + /******** + * Calcul de Inf(A) : plus grds elements de "m_base" ne contenant pas A + ********/ + void calculInf() { + ArrayList tmpArray = m_base.getM_sos(); + for (int i = 0; i < tmpArray.size(); i++) { + AttributSet current = tmpArray.get(i); + if (!current.find(m_A)) + m_inf.InsertIfThisSetMaximal(current); + } + } + + /******** FIN ********/ + + /******** Calcul de CInf(A) : complémentaires de Inf(A) ********/ + private StringBuilder calculCInf() { + + StringBuilder builder = new StringBuilder(""); + + ArrayList complementaire = new ArrayList(); + int nbattr = m_appli.getM_nbattr(); + for (int i = 0; i < nbattr; i++) { + complementaire.add(i); + } + + // R1 : RESTRICTION pour éviter les règles du type A -> A + complementaire.remove(new Integer(m_A)); + + // Pour tout élément de m_inf + for (int i = 0; i < m_inf.size(); i++) { + TreeSet tmpAl = new TreeSet(); + TreeSet current = m_inf.getM_sos().get(i).getM_at(); + + for (int iComp = 0; iComp < complementaire.size(); iComp++) { + Integer curr = complementaire.get(iComp); + if (!current.contains(curr)) + tmpAl.add(curr); + } + + Iterator iter = tmpAl.iterator(); + while (iter.hasNext()) + builder.append(iter.next()).append(' '); + builder.append('\n'); + } + + return builder; + } + + /******** FIN ********/ + + /******** Calcul de lhs(A) : transmin, parties gauches des règles ********/ + void calculLhsUnoTakeaki(StringBuilder sbuild) throws Exception { + + AttributSet transversal; + + m_lhs.clear(); + + if (sbuild.length() != 0) { + long thread = Thread.currentThread().getId(); + + m_fileCinf = new File(new File(m_appli.getM_fileOut()).getParentFile().getCanonicalPath() + File.separator + + "temp_mcinf_" + thread + ".dat"); + String fileOut = new File(m_appli.getM_fileOut()).getParentFile().getCanonicalPath() + File.separator + + "retLHS_" + thread + ".txt"; + + m_fileRet = new File(fileOut); + FileWriter fwrit = null; + try { + fwrit = new FileWriter(m_fileCinf, false); + m_writer = new BufferedWriter(fwrit); + } catch (IOException ex) { + throw new KnownException("Lhs_Uno : Impossible to create the cinf file, incorrect path."); + } + + try { + m_writer.write(sbuild.toString()); + m_writer.flush(); + m_writer.close(); + fwrit.close(); + } catch (IOException ex) { + m_fileCinf.delete(); + throw new KnownException("Lhs_Uno : Error during the writing of cinf data in the file."); + } + + try { + String params[] = { m_appli.getM_exePath(), "0", m_fileCinf.getAbsolutePath(), fileOut, "base", + m_appli.getM_fileIn(), (m_appli.isM_lineNbInFile() ? "" : ("" + m_appli.getM_nbligne())) }; + + System.out.println(params); + m_process = Runtime.getRuntime().exec(params); + + m_process.waitFor(); + + } catch (IOException ex) { + throw new KnownException("shd : Execution of shd has failed, error during the execution."); + } + + FileReader fread = null; + try { + fread = new FileReader(fileOut); + m_reader = new BufferedReader(fread); + + String line; + while ((line = m_reader.readLine()) != null) { + AttributSet atr = new AttributSet(line); + m_lhs.push_back(atr); + } + + m_reader.close(); + fread.close(); + m_fileRet.delete(); + m_fileCinf.delete(); + + } catch (IOException ex) { + throw new KnownException("Lhs_Uno : Error during the reading of shd's left parts rules."); + } + + } else { + transversal = new AttributSet(new TreeSet()); + m_lhs.push_back(transversal); + } + + } + + /******** Calcul de rhs(A) : parties droites des règles ********/ + void calculRhs() { + // Intersection des éléments de la base qui contiennent A + // this.m_rhs.clear(); + boolean first = true; + + for (int it1 = 0; it1 < m_base.getM_sos().size(); it1++) { + AttributSet curIt1 = m_base.getM_sos().get(it1); + // Si l'attribut A est inclu dans l'element de la base + if (curIt1.find(m_A)) { + // Premier élément trouvé + if (first == true) { + Iterator iter = curIt1.getM_at().iterator(); + while (iter.hasNext()) { + Integer val = iter.next(); + // si l'attribut n'a pas déjà été traité + if (!(m_appli.m_centr[val] == true)) + m_rhs.insert(val); + } + first = false; + } else { + // On insert l'element de la base, dans m_union_rhs + TreeSet tmpArray = new TreeSet(); + for (Integer currentInt : m_rhs.getM_at()) { + if (curIt1.getM_at().contains(currentInt)) + tmpArray.add(currentInt); + } + m_rhs.clear(); + for (Integer currentInt : tmpArray) + m_rhs.insert(currentInt); + } + } + } + // R2 : RESTRICTION pour éviter les règles du type A -> A + m_rhs.erase(m_A); + } + + public StringBuilder concatRulesCGL() { + // CGL + StringBuilder sbRules = new StringBuilder(""); + int supA = m_supp[m_A]; + int nbligne = m_appli.getM_nbligne(); + int taille_max = m_appli.getM_taille_max(); + + for (int iMinf = 0; iMinf < m_inf.size(); iMinf++) { + AttributSet curMinf = m_inf.getM_sos().get(iMinf); + if (curMinf.size() == 0) { + // sbRules.append("-1\t").append(m_A).append('\t'); + sbRules.append("-1 =>\t").append(m_A).append('\t'); + sbRules.append(nbligne).append('\t').append(nbligne).append('\t'); + sbRules.append(supA).append('\t').append(supA).append('\n'); + } else if (curMinf.size() <= taille_max) { + AttributSet lhs_rhs = new AttributSet(curMinf); + lhs_rhs.insert(m_A); + + int supXY = m_base.comptage(lhs_rhs); + int supX = m_base.comptage(curMinf); + double confidenceXY; + if (supX != 0) { + confidenceXY = (double) supXY / (double) supX; + } else { + confidenceXY = 0; + } + System.out.println("confidence:" + confidenceXY); + + // R4 : RESTRICTION aux parties gauches telles que suppX > 0 // supX != 0 + if (supXY != 0 && ((double) supXY / nbligne) >= supportSeuil && confidenceXY != 0 + && confidenceXY >= confidenceSeuil) { + for (Integer curVal : curMinf.getM_at()) + sbRules.append(curVal).append(' '); + sbRules.append("=>\t").append(m_A).append('\t').append(nbligne).append('\t'); + sbRules.append(supX).append('\t').append(supA).append('\t').append(supXY).append('\n'); + } + } + } + + return sbRules; + } + + public void writeRulesCC() throws Exception { + // CC + // lhs => A + StringBuilder sbRules = new StringBuilder(""); + int supA = m_supp[m_A]; + int cpt = 50000; + int nbligne = m_appli.getM_nbligne(); + int taille_max = m_appli.getM_taille_max(); + + for (int iMlhs = 0; iMlhs < m_lhs.size(); iMlhs++) { + AttributSet curMlhs = m_lhs.getM_sos().get(iMlhs); + if (curMlhs.size() == 0) { + // sbRules.append("-1\t").append(m_A).append('\t'); + sbRules.append("-1 =>\t").append(m_A).append('\t'); + sbRules.append(nbligne).append('\t').append(nbligne).append('\t'); + sbRules.append(supA).append('\t').append(supA).append('\n'); + cpt--; + } else if (curMlhs.size() <= taille_max) { + /* + * avec calcul du support + */ + MutableInt supXY = new MutableInt(); + int supX = m_base.new_comptage(curMlhs, m_A, supXY); + double confidenceXY; + if (supX != 0) { + confidenceXY = (double) supXY.getValue() / (double) supX; + } else { + confidenceXY = 0; + } + System.out.println("confidenceExact:" + confidenceXY); + /* + * sans calcul du support int supXY = 2; int supX = 2; + */ + // R4 : RESTRICTION aux parties gauches telles que suppX > 0 + if (supXY.getValue() != 0 && (double) supXY.getValue() / nbligne >= supportSeuil && confidenceXY != 0 + && confidenceXY >= confidenceSeuil) { + for (Integer curVal : curMlhs.getM_at()) + sbRules.append(curVal).append(' '); + // sbRules.append('\t').append(m_A).append('\t').append(nbligne).append('\t'); + sbRules.append("=>\t").append(m_A).append('\t').append(nbligne).append('\t'); + sbRules.append(supX).append('\t').append(supA).append('\t').append(supXY).append('\n'); + cpt--; + } + } + + if (cpt <= 0) { + m_appli.writeInStream(sbRules); + cpt = 50000; + sbRules = new StringBuilder(""); + } + + } + + // A => rhs + // Calculs inutiles si tous les attributs sont centraux + if (m_appli.getM_nbcentral() < m_appli.getM_nbattr()) { + // for (int iMrhs=0; iMrhs it = m_rhs.getM_at().iterator(); + while (it.hasNext()) { + Integer curVal = it.next(); + TreeSet tmpArray = new TreeSet(); + tmpArray.add(m_A); + tmpArray.add(curVal); + AttributSet lhs_rhs = new AttributSet(tmpArray); + int supXY = m_base.comptage(lhs_rhs); // supXY : support partie + // gauche + partie droite + + int supY = m_supp[curVal]; // supX : support partie gauche + // sbRules.append(m_A).append('\t').append(curVal).append('\t'); + sbRules.append(m_A).append(" =>\t").append(curVal).append('\t'); + sbRules.append(nbligne).append('\t').append(supA).append('\t').append(supY); + sbRules.append('\t').append(supXY).append('\n'); + cpt--; + } + } + + if (cpt < 50000) + m_appli.writeInStream(sbRules); + + } + + /******** FIN ********/ + + /******** Renvoie true si l'intersection est vide ********/ + boolean is_intersection_empty(AttributSet F, AttributSet E) { + if (F.size() < E.size()) { + for (Integer curVal : F.getM_at()) + if (E.find(curVal)) + return false; + return true; + } else { + for (Integer curVal : E.getM_at()) + if (F.find(curVal)) + return false; + return true; + } + } + + /******** FIN ********/ + + /******** + * Permet de supprimer les fichiers textes utiles pour UNOLHS + ********/ + void cleanUnoTempFiles() { + if (m_process != null) { + m_process.destroy(); + } + + try { + Thread.sleep(200); + } catch (InterruptedException ex) { + /* ignore exception */ + ex.printStackTrace(); + } + + try { + if (m_reader != null) { + m_reader.close(); + } + if (m_writer != null) { + m_writer.close(); + } + if (this.m_fileCinf != null && this.m_fileCinf.exists()) { + m_fileCinf.delete(); + } + if (this.m_fileRet != null && this.m_fileRet.exists()) { + m_fileRet.delete(); + } + } catch (IOException ex) { + /* ignore exception */ + ex.printStackTrace(); + } + } + + public Set_AttributSet getM_inf() { + return m_inf; + } + + public Set_AttributSet getM_cinf() { + return m_cinf; + } + + public Set_AttributSet getM_lhs() { + return m_lhs; + } + + public AttributSet getM_rhs() { + return m_rhs; + } + +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/Dfg.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/Dfg.java new file mode 100644 index 0000000..499baa0 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/Dfg.java @@ -0,0 +1,418 @@ +package fr.ensma.lias.rql.dfg; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.TreeSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.logging.Level; +import java.util.logging.Logger; + +import fr.ensma.lias.rql.dfg.MyUncaughtExceptionHandler; +import fr.ensma.lias.rql.dfg.NotifyingBlockingThreadPoolExecutor; +import fr.ensma.lias.rql.dfg.Set_AttributSet; +import fr.ensma.lias.rql.dfg.ThreadRunException; + +/** + * @author Gouriou Benjamin + */ +public class Dfg { + + private int m_progress = 0; + + private int m_taille_max; // taille maximale de la partie gauche + + private int m_nbattr; // nb d'attributs dans le trie + + private int m_nbligne = 0; // nb de lignes + + private int m_nbcentral; // nb d'attributs centraux + + private ArrayList m_central; // Attributs centraux + + boolean m_centr[]; // pour chaque attribut, true si il est central + + int m_supp[]; // Supports des attributs + + Set_AttributSet m_base; // Base du système de fermeture + + private String m_fileIn; + + private String m_fileOut; + + private String m_execpath; + + private BufferedWriter m_buffer = null; + + private FileWriter m_writer = null; + + private boolean m_lineNbInFile = false; + + private final Lock m_lock = new ReentrantLock(); + + private ThreadRunException _threadException = null; + + static final int THREAD_POOL_SIZE = 4; + + static final int THREAD_QUEUE_SIZE = 8; + + static final int THREAD_KEEPALIVE = 15; + + static final TimeUnit THREAD_KEEPALIVE_UNIT = TimeUnit.SECONDS; + + public long loadTime = 0; + + public long calculInfTime = 0; + + public long concatRulesCGLTime = 0; + + public long calculCInfTime = 0; + + public long calculLhsUnoTime = 0; + + public long writeRulesCCTime = 0; + + public long writeTime = 0; + + public double supportSeuil = 0; + public double confidenceSeuil = 0; + + public Dfg(String fileIn, String fileOut, double support, double confidence, int tailleMax, String m_execpath) { + m_base = new Set_AttributSet(); + // ******************************* + this.m_taille_max = tailleMax; + this.m_fileOut = fileOut; + this.m_fileIn = fileIn; + this.m_execpath = m_execpath; + this.supportSeuil = support; + this.confidenceSeuil = confidence; + } + + /* + * void init(int nbOcc, int[] agr) { TreeSet tmpArray = new + * TreeSet(); for (int cur : agr) { tmpArray.add(cur); } AttributSet ag + * = new AttributSet(); ag.setM_count(nbOcc); ag.setM_at(tmpArray); + * m_base.push_back(ag); } + */ + + /******** Chargement de m_base, m_central et m_supp ********/ + int charger() throws Exception { + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(m_fileIn)); + } catch (FileNotFoundException ex) { + throw new Exception("DFGApp : Specified entry base file does not exist."); + } + + String line = ""; + try { + line = reader.readLine(); + m_nbcentral = Integer.valueOf(line); + System.out.println("m_nbcentral : " + m_nbcentral); + m_central = new ArrayList(m_nbcentral); + } catch (IOException ex) { + reader.close(); + throw new Exception("DFGApp : Can't get central genes number. File format is incorrect."); + } + + try { + line = reader.readLine(); + String tmp[] = line.split(" "); + for (String curr : tmp) + m_central.add(Integer.valueOf(curr)); + } catch (NumberFormatException e) { + reader.close(); + throw new Exception("DFGApp : Invalide caracter in the list of central gene."); + } catch (IOException e) { + reader.close(); + throw new Exception("DFGApp : Error during the reading of central genes list."); + } + + try { + line = reader.readLine(); + String tmp[] = line.split(" "); + m_nbattr = Integer.valueOf(tmp[0]); + m_nbligne = Integer.valueOf(tmp[1]); + } catch (IOException ex) { + reader.close(); + throw new Exception("DFGApp : Error during the reading of attributes and lines number."); + } + + m_centr = new boolean[m_nbattr]; + m_supp = new int[m_nbattr]; + System.out.println("Nombre d'attributs : " + m_nbattr); + + if (m_nbligne != 0) + m_lineNbInFile = true; + + for (int i = 0; i < m_nbcentral; i++) + m_centr[m_central.get(i)] = true; + + // Chargement de la base (a partir de la 3eme ligne) + int numAttribut; + int countElt; + AttributSet ag = null; + TreeSet tmpArray; + try { + while ((line = reader.readLine()) != null) { + ag = new AttributSet(); + tmpArray = new TreeSet(); + String tmp[] = line.split(" ", 2); + countElt = Integer.parseInt(tmp[0]); + if (!m_lineNbInFile) + m_nbligne += countElt; + ag.setM_count(countElt); + if (tmp.length == 2) { + String val[] = tmp[1].split(" "); + for (String curr : val) { + numAttribut = Integer.parseInt(curr); + tmpArray.add(numAttribut); + m_supp[numAttribut] += countElt; + } + } + ag.setM_at(tmpArray); + m_base.push_back(ag); + } + for (int i = 0; i < m_supp.length; i++) { + System.out.println(m_supp[i]); + } + } catch (IOException ex) { + throw new Exception("DFGApp : Error during the reading of base lines in the file."); + } + + System.out.println("Nombre de lignes : " + m_nbligne); + + reader.close(); + + return 0; + } + + public int execute() throws Exception { + /* + * double t1, t2; t1=System.currentTimeMillis(); + */ + Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler()); + File file = new File(m_fileIn); + + if (!file.exists() || m_taille_max <= 0) + throw new Exception("DFGApp: Error in entry parameters. Rules generation aborted."); + + if (charger() != 0) + throw new Exception("DFGApp: Error during the reading of the file. Rules generation aborted."); + + /* + * String path = System.getenv("WebNetwork"); //Windows if + * (System.getProperty("os.name").contains("Windows")) m_exePath = path + + * "\\shd.exe"; else m_exePath = path + "shd"; + */ + + // Mac + // m_exePath = path + "shd"; + + // System.out.println("execution: "+m_exePath); + + // ***************************************************************** + // ***************************************** Parallel calculation + // ***************************************************************** + + // ----------------------------------------------------------------- + // NotifyingBlockingThreadPoolExecutor initialization parameters + + // ----------------------------------------------------------------- + // Create the NotifyingBlockingThreadPoolExecutor + NotifyingBlockingThreadPoolExecutor m_threadPoolExecutor = new NotifyingBlockingThreadPoolExecutor( + THREAD_POOL_SIZE, THREAD_QUEUE_SIZE, THREAD_KEEPALIVE, THREAD_KEEPALIVE_UNIT); + + // ----------------------------------------------------------------- + // Stack and execute the tasks + for (int i = 0; i < this.m_nbcentral && _threadException == null; i++) { + AttributeCalculation currentAttr = new AttributeCalculation(this, m_central.get(i), supportSeuil, + confidenceSeuil); + System.out.println("checkpoint"); + m_threadPoolExecutor.execute(currentAttr); + // this.m_progress=m_threadPoolExecutor.getTasksCompleted(); + this.m_progress = i; + System.out.println((i * 100 / this.m_nbcentral) + "%"); + } + + if (_threadException != null) { + this.closeStream(); + throw _threadException; + } + + // ----------------------------------------------------------------- + // Wait for the last tasks to be done + try { + boolean done = false; + do { + // System.out.println("waiting for the last tasks to finish"); + if (!m_threadPoolExecutor.isShutdown()) + done = m_threadPoolExecutor.await(5, TimeUnit.SECONDS); + else + done = true; + // this.m_progress=m_threadPoolExecutor.getTasksCompleted(); + } while (!done); + } catch (InterruptedException e) { + throw new Exception("DFGApp : Unknown error during the execution of the process!"); + } + + if (_threadException != null) { + this.closeStream(); + throw _threadException; + } + + m_threadPoolExecutor.shutdown(); + /* + * t2 = System.currentTimeMillis(); System.out.println("Temps d'execution : "+ + * (t2 - t1)); + */ + this.closeStream(); + + return 0; + } + + /* + * public static void main(String[] args) { if (args.length<3) { + * System.err.println("Erreur nombre de paramètres incorrects"); return; } + * + * Dfg app = new Dfg(args[0],args[1],Integer.valueOf(args[2])); try { + * app.execute(); } catch (Exception ex) { + * //Logger.getLogger(Appli.class.getName()).log(Level.SEVERE, null, ex); + * System.err.println(ex.getMessage()); } } + */ + + public BufferedWriter getStream() { + if (m_buffer == null) { + File fOut = new File(this.m_fileOut); + if (fOut.exists()) + fOut.delete(); + try { + this.m_writer = new FileWriter(m_fileOut, true); + this.m_buffer = new BufferedWriter(m_writer); + } catch (IOException ex) { + ex.printStackTrace(); + Logger.getLogger(Dfg.class.getName()).log(Level.SEVERE, null, ex); + } + } + return m_buffer; + } + + public synchronized void writeInStream(StringBuilder builder) throws Exception { + m_lock.lock(); + BufferedWriter wr = this.getStream(); + try { + wr.write(builder.toString()); + wr.flush(); + } catch (IOException ex) { + throw new Exception("DFGApp : Error during rules writing in file."); + } finally { + m_lock.unlock(); + } + + } + + public synchronized void closeStream() { + try { + m_buffer.close(); + m_writer.close(); + } catch (IOException ex) { + ex.printStackTrace(); + System.err.println("Erreur à la fermeture du fichier de regles."); + } + } + + public int getProgress() { + return (int) Math.ceil((this.m_progress / ((float) this.m_nbcentral)) * 100); + } + + /* + * public int killExecution() { try { + * m_threadPoolExecutor.setExecutionKilled(true); this.setThreadException(new + * ThreadRunException(new Exception("User killed execution"),-1)); + * m_threadPoolExecutor.shutdownNow(); if + * (!m_threadPoolExecutor.awaitTermination(3, TimeUnit.SECONDS)) + * System.err.println("Pool did not terminate"); } catch (InterruptedException + * ex) { ex.printStackTrace(); + * Logger.getLogger(Dfg.class.getName()).log(Level.SEVERE, null, ex); return -1; + * } return 0; } + */ + + /***** GETTERS AND SETTERS *****/ + + public int getM_taille_max() { + return m_taille_max; + } + + public void setM_taille_max(int m_taille_max) { + this.m_taille_max = m_taille_max; + } + + public int getM_nbattr() { + return m_nbattr; + } + + public int getM_nbligne() { + return m_nbligne; + } + + public int getM_nbcentral() { + return m_nbcentral; + } + + public ArrayList getM_central() { + return m_central; + } + + public Set_AttributSet getM_base() { + return m_base; + } + + public boolean[] getM_centr() { + return m_centr; + } + + public int[] getM_supp() { + return m_supp; + } + + public String getM_fileIn() { + return m_fileIn; + } + + public String getM_fileOut() { + return m_fileOut; + } + + public String getM_exePath() { + return m_execpath; + } + + public boolean isM_lineNbInFile() { + return m_lineNbInFile; + } + + public Exception getThreadException() { + return _threadException; + } + + public synchronized void setThreadException(ThreadRunException threadException) { + this._threadException = threadException; + } + + public synchronized void addTimes(long calculInf, long concatRulesCGL, long calculCInf, long calculLhsUno, + long writeRulesCC) { + calculInfTime += calculInf; + concatRulesCGLTime += concatRulesCGL; + calculCInfTime += calculCInf; + calculLhsUnoTime += calculLhsUno; + writeRulesCCTime += writeRulesCC; + } + +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/KilledProcessException.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/KilledProcessException.java new file mode 100644 index 0000000..f44398c --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/KilledProcessException.java @@ -0,0 +1,15 @@ +package fr.ensma.lias.rql.dfg; + +import java.util.concurrent.RejectedExecutionException; + +/** + * @author Gouriou Benjamin + */ +public class KilledProcessException extends RejectedExecutionException { + + private static final long serialVersionUID = -6689075757022563066L; + + KilledProcessException(String details) { + super(details); + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/KnownException.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/KnownException.java new file mode 100644 index 0000000..e25716a --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/KnownException.java @@ -0,0 +1,18 @@ +package fr.ensma.lias.rql.dfg; + +/** + * @author Gouriou Benjamin + */ +public class KnownException extends Exception { + + private static final long serialVersionUID = -1052570947087566045L; + + KnownException(String details) { + super(details); + } + + KnownException(Exception exception) { + super(exception); + } + +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/MutableInt.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/MutableInt.java new file mode 100644 index 0000000..9bc3ab6 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/MutableInt.java @@ -0,0 +1,46 @@ +package fr.ensma.lias.rql.dfg; + +/** + * @author Gouriou Benjamin + */ +public class MutableInt { + + private int value; + + public MutableInt() { + value = 0; + } + + public MutableInt(int val) { + value = val; + } + + public void increment() { + value++; + } + + public void decrement() { + value--; + } + + public void add(int delta) { + value += delta; + } + + public void minus(int delta) { + value -= delta; + } + + public int getValue() { + return value; + } + + public boolean estEgal(int val) { + return val == value; + } + + @Override + public String toString() { + return Integer.toString(value); + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/MyUncaughtExceptionHandler.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/MyUncaughtExceptionHandler.java new file mode 100644 index 0000000..b0171de --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/MyUncaughtExceptionHandler.java @@ -0,0 +1,11 @@ +package fr.ensma.lias.rql.dfg; + +/** + * @author Gouriou Benjamin + */ +public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { + + @Override + public void uncaughtException(Thread t, Throwable e) { + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/NotifyingBlockingThreadPoolExecutor.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/NotifyingBlockingThreadPoolExecutor.java new file mode 100644 index 0000000..cacabbc --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/NotifyingBlockingThreadPoolExecutor.java @@ -0,0 +1,317 @@ +package fr.ensma.lias.rql.dfg; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.Semaphore; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * This class is a specialized extension of the ThreadPoolExecutor class. + * + * Two functionalities had been added to this subclass. 1) The execute method of + * the ThreadPoolExecutor will block in case the queue is full and only unblock + * when the queue is dequeued - that is a task that is currently in the queue is + * removed and handled by the ThreadPoolExecutor. 2) Client code can await for + * the event of all tasks beeing run to conclusion. Client code which actively + * chose to wait for this occurrence should call await on the instance of his + * ThreadPoolExecutor. This differs from awaitTermination as it does not require + * any call to shutdown. + * + * Code example: + * + * NotifyingBlockingThreadPoolExecutor threadPoolExecutor = new + * NotifyingBlockingThreadPoolExecutor(5, ,10, 15, TimeUnit.SECONDS); + * + * for (int i = 0; i < 5000; i++) { threadPoolExecutor.execute(...) } + * + * try { threadPoolExecutor.await(); } catch (InterruptedException e) { // + * Handle error } + * + * System.out.println("Done!"); + * + * The example above shows how 5000 tasks are run within 5 threads. The line + * with 'System.out.println("Done!");' will not run until such a time when all + * the tasks given to the thread pool have concluded. their run. + * + * This subclass of ThreadPoolExecutor also takes away the max threads + * capabilities of the ThreadPoolExecutor superclass and internally sets the + * amount of maximum threads to be the size of the core threads. This is done + * since threads over the core size and under the max are instantiated only once + * the queue is full, but the NotifyingBlockingThreadPoolExecutor will block + * once the queue is full. + * + * @author Yaneeve Shekel & Amir Kirsh + */ +public class NotifyingBlockingThreadPoolExecutor extends ThreadPoolExecutor { + + /** + * Counts the number of current tasks in process + */ + private AtomicInteger tasksInProcess = new AtomicInteger(); + + /** + * This is the Synchronizer instance that is used in order to notify all + * interested code of when all the tasks that have been submitted to the + * execute() method have run to conclusion. This notification can occur a + * numerous amount of times. It is all up to the client code. Whenever the + * ThreadPoolExecutor concludes to run all the tasks the Synchronizer object + * will be notified and will in turn notify the code which is waiting on it. + */ + private Synchronizer synchronizer = new Synchronizer(); + + private final Semaphore semaphore; + + /** + * This constructor is used in order to maintain the first functionality + * specified above. It does so by using an ArrayBlockingQueue and the + * BlockThenRunPolicy that is defined in this class. Using this constructor, + * waiting time on new task insertion is unlimited. + * + * @param poolSize is the amount of threads that this pool may have alive + * at any given time. + * @param queueSize is the size of the queue. This number should be at least + * as the pool size to make sense (otherwise there are + * unused threads), thus if the number sent is smaller, the + * poolSize is used for the size of the queue. Recommended + * value is twice the poolSize. + * @param keepAliveTime is the amount of time after which an inactive thread is + * terminated. + * @param unit is the unit of time to use with the previous parameter. + */ + public NotifyingBlockingThreadPoolExecutor(int poolSize, int queueSize, long keepAliveTime, TimeUnit unit) { + + super(poolSize, // Core size + poolSize, // Max size + keepAliveTime, unit, new ArrayBlockingQueue(Math.max(poolSize, queueSize)) // not + // smaller + // than + // the + // poolSize + // (to + // avoid + // redundant + // threads) + ); + this.semaphore = new Semaphore(Math.max(poolSize, queueSize), true); + super.allowCoreThreadTimeOut(true); // Time out the core threads. + } + + /** + * Before calling super's version of this method, the amount of tasks which are + * currently in process is first incremented. + * + * @see java.util.concurrent.ThreadPoolExecutor#execute(Runnable) + */ + @Override + public void execute(Runnable task) { + // count a new task in process + tasksInProcess.incrementAndGet(); + boolean acquired = false; + do { + try { + semaphore.acquire(); + acquired = true; + } catch (InterruptedException e) { + // e.printStackTrace(); + } + } while (!acquired); + + try { + super.execute(task); + } catch (RuntimeException e) { // specifically handle + // RejectedExecutionException + tasksInProcess.decrementAndGet(); + e.printStackTrace(); + semaphore.release(); + throw e; + } catch (Error e) { + tasksInProcess.decrementAndGet(); + e.printStackTrace(); + semaphore.release(); + throw e; + } + } + + /** + * After calling super's implementation of this method, the amount of tasks + * which are currently in process is decremented. Finally, if the amount of + * tasks currently running is zero the synchronizer's signallAll() method is + * invoked, thus anyone awaiting on this instance of ThreadPoolExecutor is + * released. + * + * @see java.util.concurrent.ThreadPoolExecutor#afterExecute(Runnable, + * Throwable) + */ + @Override + protected void afterExecute(Runnable r, Throwable t) { + + super.afterExecute(r, t); + + // synchronizing on the pool (and actually all its threads) + // the synchronization is needed to avoid more than one signal if two or + // more + // threads decrement almost together and come to the if with 0 tasks + // together + synchronized (this) { + tasksInProcess.decrementAndGet(); + if (tasksInProcess.intValue() == 0) { + synchronizer.signalAll(); + } + } + semaphore.release(); + } + + /** + * Internally calls on super's setCorePoolSize and setMaximumPoolSize methods + * with the given method argument. + * + * @see java.util.concurrent.ThreadPoolExecutor#setCorePoolSize(int) + */ + @Override + public void setCorePoolSize(int corePoolSize) { + super.setCorePoolSize(corePoolSize); + super.setMaximumPoolSize(corePoolSize); + } + + /** + * Does Nothing! + * + * @throws UnsupportedOperationException in any event + * @see java.util.concurrent.ThreadPoolExecutor#setMaximumPoolSize(int) + */ + @Override + public void setMaximumPoolSize(int maximumPoolSize) { + throw new UnsupportedOperationException("setMaximumPoolSize is not supported."); + } + + /** + * Does Nothing! MUST NOT CHANGE OUR BUILT IN RejectedExecutionHandler + * + * @throws UnsupportedOperationException in any event + * @see java.util.concurrent.ThreadPoolExecutor#setRejectedExecutionHandler(RejectedExecutionHandler) + */ + @Override + public void setRejectedExecutionHandler(RejectedExecutionHandler handler) { + throw new UnsupportedOperationException("setRejectedExecutionHandler is not allowed on this class."); + } + + /** + * A blocking wait for this ThreadPool to be in idle state, which means that + * there are no more tasks in the Queue or currently executed by one of the + * threads. BE AWARE that this method may get out from blocking state when a + * task is currently sent to the ThreadPool not from this thread context. Thus + * it is not safe to call this method in case there are several threads feeding + * the TreadPool with tasks (calling execute). The safe way to call this method + * is from the thread that is calling execute and when there is only one such + * thread. Note that this method differs from awaitTemination, as it can be + * called without shutting down the ThreadPoolExecuter. + * + * @throws InterruptedException when the internal condition throws it. + */ + public void await() throws InterruptedException { + synchronizer.await(); + } + + /** + * A blocking wait for this ThreadPool to be in idle state or a certain timeout + * to elapse. Works the same as the await() method, except for adding the + * timeout condition. + * + * @see NotifyingBlockingThreadPoolExecutor#await() for more details. + * @return false if the timeout elapsed, true if the synch event we are waiting + * for had happened. + * @throws InterruptedException when the internal condition throws it. + */ + public boolean await(long timeout, TimeUnit timeUnit) throws InterruptedException { + return synchronizer.await(timeout, timeUnit); + } + + // ==================================================================== + // start of inner private class Synchronizer + // ==================================================================== + + /** + * This inner class serves to notify all interested parties that the + * ThreadPoolExecutor has finished running all the tasks given to its execute + * method. + */ + private class Synchronizer { + + private final Lock lock = new ReentrantLock(); + private final Condition done = lock.newCondition(); + private boolean isDone = false; + + /** + * This PRIVATE method allows the ThreadPoolExecutor to notify all interested + * parties that all tasks given to the execute method have run to conclusion. + */ + private void signalAll() { + + lock.lock(); // MUST lock! + try { + isDone = true; // To help the await method ascertain that it has + // not waken up 'spuriously' + done.signalAll(); + } finally { + lock.unlock(); // Make sure to unlock even in case of an + // exception + } + } + + /** + * This is the inner implementation for supporting the + * NotifyingBlockingThreadPoolExecutor.await(). + * + * @see NotifyingBlockingThreadPoolExecutor#await() for details. + * @throws InterruptedException when the internal condition throws it. + */ + public void await() throws InterruptedException { + + lock.lock(); // MUST lock! + try { + while (!isDone) { // Ascertain that this is not a 'spurious + // wake-up' + done.await(); + } + } finally { + isDone = false; // for next time + lock.unlock(); // Make sure to unlock even in case of an + // exception + } + } + + /** + * This is the inner implementation for supporting the + * NotifyingBlockingThreadPoolExecutor.await(timeout, timeUnit). + * + * @see NotifyingBlockingThreadPoolExecutor#await(long, TimeUnit) for details. + * @throws InterruptedException when the internal condition throws it. + */ + public boolean await(long timeout, TimeUnit timeUnit) throws InterruptedException { + + boolean await_result = false; + lock.lock(); // MUST lock! + boolean localIsDone; + try { + await_result = done.await(timeout, timeUnit); + } finally { + localIsDone = isDone; + isDone = false; // for next time + lock.unlock(); // Make sure to unlock even in case of an + // exception + } + // make sure we return true only if done! + return await_result && localIsDone; + } + } + + // ==================================================================== + // end of inner class Synchronizer + // ==================================================================== + +} \ No newline at end of file diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/Set_AttributSet.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/Set_AttributSet.java new file mode 100644 index 0000000..dce06e5 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/Set_AttributSet.java @@ -0,0 +1,138 @@ +package fr.ensma.lias.rql.dfg; + +import java.util.ArrayList; +import java.util.Iterator; + +/** + * @author Gouriou Benjamin + */ +public class Set_AttributSet { + + private ArrayList m_sos; + + public Set_AttributSet() { + m_sos = new ArrayList(); + } + + public Set_AttributSet(Set_AttributSet inSet) { + this.clone(inSet); + } + + public final void clone(Object o) { + if (o instanceof Set_AttributSet) { + Set_AttributSet obj = (Set_AttributSet) o; + this.m_sos.clear(); + Iterator iter = obj.m_sos.iterator(); + while (iter.hasNext()) + this.m_sos.add(new AttributSet(iter.next())); + } + } + + public void clear() { + m_sos.clear(); + } + + boolean empty() { + return m_sos.isEmpty(); + } + + int size() { + return m_sos.size(); + } + + void push_back(AttributSet elt) { + m_sos.add(elt); + } + + void eraseElmtAt(int index) { + m_sos.remove(index); + /* + * Iterator iter = m_sos.iterator(); int icpt=0; while(icpt<=index) + * { iter.next(); icpt++; } + * + * iter.remove(); + */ + } + + @Override + public String toString() { + StringBuilder tmp = new StringBuilder("{"); + Iterator iter = this.m_sos.iterator(); + while (iter.hasNext()) { + tmp.append("(").append(iter.next().toString()).append(") "); + } + tmp.append("}\n"); + return tmp.toString(); + } + + /******** Insert un attribut maximal ********/ + void InsertIfThisSetMaximal(AttributSet X) { + boolean encore = true; + boolean premier = true; + int size = m_sos.size(); + for (int i = 0; i < size; i++) { + AttributSet current = m_sos.get(i); + if (X.is_subset(current)) { + encore = false; + return; + } else { + if (current.is_strictsubset(X)) { + if (premier) { + m_sos.set(i, X); + premier = false; + } else { + eraseElmtAt(i); + i--; + size--; + } + } + } + } + + if (encore && premier) { + m_sos.add(X); + } + } + + /******** + * Renvoie true si l'attributSet S est inclus dans un élément du setofSet + ********/ + boolean est_inclus(AttributSet S) { + for (int i = 0; i < m_sos.size(); i++) { + if (S.is_subset(m_sos.get(i))) { + return true; + } + } + return false; + } + + /******** + * Compte le nb de fois qu'apparait un attributSet S dans le setofSet + ********/ + // A REFAIRE EN NE FAISANT QU'UN SEUL PARCOURS DE M_SOS + int comptage(AttributSet S) { + int cpt = 0; + for (int i = 0; i < m_sos.size(); i++) { + AttributSet current = m_sos.get(i); + if (S.is_subset(current)) + cpt += current.getM_count(); + } + return cpt; + } + + int new_comptage(AttributSet S, int rightPart, MutableInt cptRightPart) { + int cpt = 0; + for (int i = 0; i < m_sos.size(); i++) { + AttributSet current = m_sos.get(i); + // cpt+=current.containsSubSetAndRightPart(S,rightPart,cptRightPart); + cpt += current.containsSubSetAndRightPartStd(S, rightPart, cptRightPart); + } + return cpt; + } + + /**** GETTERS AND SETTERS ****/ + public ArrayList getM_sos() { + return m_sos; + } + +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/ThreadRunException.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/ThreadRunException.java new file mode 100644 index 0000000..58e8ada --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/dfg/ThreadRunException.java @@ -0,0 +1,29 @@ +package fr.ensma.lias.rql.dfg; + +/** + * @author Gouriou Benjamin + */ +public class ThreadRunException extends RuntimeException { + + private static final long serialVersionUID = 5598083182705789448L; + + private final Exception _parentException; + + private final int _centralGene; + + ThreadRunException(Exception ex, int gene) { + super("DFGApp : Execution has failed for gene " + gene + "--> Generation Process aborted. Details:\n\t" + + ex.getMessage()); + _parentException = ex; + _centralGene = gene; + } + + public Exception getParentException() { + return _parentException; + } + + public int getCentralGene() { + return _centralGene; + } + +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/queryconstruction/QueryConstructor.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/queryconstruction/QueryConstructor.java new file mode 100644 index 0000000..6c33cfa --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/queryconstruction/QueryConstructor.java @@ -0,0 +1,94 @@ +package fr.ensma.lias.rql.queryconstruction; + +/** + * @author Bilal REZKELLAH + */ +public class QueryConstructor { + + static final String FINDRULES = "FINDRULES"; + static final String OVER = "OVER"; + static final String SCOPE = "SCOPE"; + static final String WHERE = "WHERE"; + static final String CONDITION_ON_A_IS = "CONDITION ON A IS"; + static final String NULL = " NULL"; + static final String FD = "Functional Dependencies"; + static final String SFD = "Sequential Functional Dependencies"; + static final String MFD = "Metric Functional Dependencies"; + static final String CAR = "Classic Association Rules"; + static final String NV = "Null Values"; + + String constructedQuery = ""; + String attributesList = "[ATTRIBUTES LIST]"; + String dataSet = "[TABLE NAME]"; + String tableName = "[TABLE NAME]"; + String whereScope = "[CONDITION]"; + String conditionalWhere = "[CONDITION]"; + + public QueryConstructor() { + + } + + public String constructquery(String QueryType, String isTable, String isALLData, String sqlQuerie, String tableName, + String subsetWhere, String attributesList, boolean isConditional, String conditionalWhere, + String tolerence) { + + constructedQuery = FINDRULES + "\n" + OVER + " "; + + if (!attributesList.equals("")) { + this.attributesList = attributesList; + } + + constructedQuery += this.attributesList; + constructedQuery += "\n"; + constructedQuery += SCOPE; + if (isTable.equals("table")) { + if (isALLData.equals("Subset")) { + if (!tableName.equals("")) { + this.tableName = tableName; + } + if (!subsetWhere.equals("")) { + this.whereScope = subsetWhere; + } + dataSet = " ( SELECT * FROM " + this.tableName + " " + WHERE + " " + this.whereScope.toUpperCase() + + " )"; + } else if (isALLData.equals("All")) { + if (!tableName.equals("")) { + this.tableName = tableName; + } + dataSet = this.tableName; + } + } else { + dataSet = "( " + sqlQuerie + " )"; + } + if (QueryType.equals(NV)) { + + constructedQuery += " t1 " + this.dataSet + "\n"; + } else { + constructedQuery += " t1, t2 " + this.dataSet + "\n"; + } + + if (isConditional) { + if (!conditionalWhere.equals("")) { + this.conditionalWhere = conditionalWhere; + } + + constructedQuery += WHERE + " " + this.conditionalWhere.toUpperCase() + "\n"; + + } + constructedQuery += CONDITION_ON_A_IS; + if (QueryType.equals(NV)) { + + constructedQuery += " t1.A is " + NULL; + } else if (QueryType.equals(FD)) { + constructedQuery += " t1.A = t2.A"; + } else if (QueryType.equals(SFD)) { + constructedQuery += " t1.A > t2.A"; + } else if (QueryType.equals(MFD)) { + constructedQuery += " 2 * ABS(t1.A - t2.A) / (t1.A + t2.A) < " + tolerence; + } else if (QueryType.equals(CAR)) { + constructedQuery += " t1.A = 1 "; + } + return constructedQuery; + + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/rulecheck/CheckResult.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/rulecheck/CheckResult.java new file mode 100644 index 0000000..b99fe57 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/rulecheck/CheckResult.java @@ -0,0 +1,95 @@ +package fr.ensma.lias.rql.rulecheck; + +import fr.ensma.lias.rql.sql.SQLResultsRow; + +/** + * @author Bilal REZKELLAH + */ +public class CheckResult { + + private String isTrue; + + private String support; + + private String confidence; + + private int counterExamplesNB; + + public SQLResultsRow counterExamples; + + public SQLResultsRow counterExamples2; + + public SQLResultsRow counterExamples3; + + public String getSupport() { + return support; + } + + public void setSupport(String support) { + this.support = support; + } + + public String getConfidence() { + return confidence; + } + + public int getCounterExamplesNB() { + return counterExamplesNB; + } + + public void setCounterExamplesNB(int counterExamplesNB) { + this.counterExamplesNB = counterExamplesNB; + } + + public void setConfidence(String confidence) { + this.confidence = confidence; + } + + public CheckResult(String isTrue, String support, String confidence, int counterExamplesNB, + SQLResultsRow counterExamples, SQLResultsRow counterExamples2, SQLResultsRow counterExamples3) { + super(); + this.isTrue = isTrue; + this.support = support; + this.confidence = confidence; + this.counterExamplesNB = counterExamplesNB; + this.counterExamples = counterExamples; + this.counterExamples2 = counterExamples2; + this.counterExamples3 = counterExamples3; + + } + + public SQLResultsRow getCounterExamples2() { + return counterExamples2; + } + + public void setCounterExamples2(SQLResultsRow counterExamples2) { + this.counterExamples2 = counterExamples2; + } + + public SQLResultsRow getCounterExamples3() { + return counterExamples3; + } + + public void setCounterExamples3(SQLResultsRow counterExamples3) { + this.counterExamples3 = counterExamples3; + } + + public String getIsTrue() { + return isTrue; + } + + public void setIsTrue(String isTrue) { + this.isTrue = isTrue; + } + + public SQLResultsRow getCounterExamples() { + return counterExamples; + } + + public void setCounterExamples(SQLResultsRow counterExamples) { + this.counterExamples = counterExamples; + } + + public CheckResult() { + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/rulecheck/RuleChecker.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/rulecheck/RuleChecker.java new file mode 100644 index 0000000..8ffc53d --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/rulecheck/RuleChecker.java @@ -0,0 +1,514 @@ +package fr.ensma.lias.rql.rulecheck; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; + +import fr.ensma.lias.rql.cfg.SqlCoreConf; +import fr.ensma.lias.rql.database.Database; +import fr.ensma.lias.rql.database.MysqlDB; +import fr.ensma.lias.rql.database.OracleDB; +import fr.ensma.lias.rql.database.PostgresqlDB; +import fr.ensma.lias.rql.rqlgrammar.RQLParser; +import fr.ensma.lias.rql.sql.SQLResultsRow; +import fr.ensma.lias.rql.sql.SQLRow; + +/** + * @author Bilal REZKELLAH + */ +public class RuleChecker { + + private String rqlQuery; + + private String leftAttributes; + + private String rightAttribute; + + private String isTrue; + + private String query1 = ""; + + private String query2 = ""; + + private String query3 = ""; + + private String querySupportX = ""; + + private String querySupportXYBar = ""; + + private SqlCoreConf sqlCoreConf; + + private Database db = null; + + public CheckResult CheckRule(RQLParser parse, String rqlQuery, String leftAttributes, String rightAttribute, + double support, double confidence) { + List listEntetes = new ArrayList(); + List recurentList = new ArrayList(); + List counterExp = new ArrayList(); + List counterExp2 = new ArrayList(); + List counterExp3 = new ArrayList(); + List separated = new ArrayList(); + List separated2 = new ArrayList(); + List separated3 = new ArrayList(); + SQLRow sqlRow; + List rows = new ArrayList(); + ; + SQLResultsRow sqlResults = new SQLResultsRow(listEntetes, rows, true); + SQLResultsRow sqlResults2 = new SQLResultsRow(listEntetes, rows, true); + SQLResultsRow sqlResults3 = new SQLResultsRow(listEntetes, rows, true); + + try { + System.out.println(leftAttributes); + ArrayList leftAttributesList = parseAttributeList(leftAttributes); + ArrayList rightAttributesList = parseAttributeList(rightAttribute); + RQLParser parser = parse; + parser.improve(); + if (this.sqlCoreConf.getRqlDbType().equals("oracle")) { + db = new OracleDB(); + } else if (this.sqlCoreConf.getRqlDbType().equals("postgresql")) { + db = new PostgresqlDB(); + } else if (this.sqlCoreConf.getRqlDbType().equals("mysql")) { + db = new MysqlDB(); + } + db.open(this.sqlCoreConf.getRqlDbHost(), this.sqlCoreConf.getRqlDbPort(), this.sqlCoreConf.getRqlDbName(), + this.sqlCoreConf.getRqlDbAdminLogin(), this.sqlCoreConf.getRqlDbAdminPwd()); + System.out.println("\nconnexion etablie \n"); + + /* this QUERY is used to get the support of the lhs of the checked rule */ + querySupportX = "SELECT count(*)"; + querySupportX += "\nFROM " + parser.getSqlStatement() + "\nWHERE "; + if (parser.getSqlConditions() != null) { + querySupportX += parser.getSqlConditions() + "\nAND "; + } + // (conditions[left]) AND NOT (conditions[right]) + querySupportX += "("; + for (int i = 0; i < leftAttributesList.size(); i++) { + if (i > 0) { + querySupportX += " AND "; + } + querySupportX += "(" + parser.sqlCondition(leftAttributesList.get(i)) + ")"; + } + + querySupportX += ")"; + System.out.println("querySupportX" + querySupportX); + /* this QUERY is used to get the support the checked rule */ + querySupportXYBar = "SELECT count(*)"; + querySupportXYBar += "\nFROM " + parser.getSqlStatement() + "\nWHERE "; + if (parser.getSqlConditions() != null) { + querySupportXYBar += parser.getSqlConditions() + "\nAND "; + } + // (conditions[left]) AND NOT (conditions[right]) + querySupportXYBar += "("; + for (int i = 0; i < leftAttributesList.size(); i++) { + if (i > 0) { + querySupportXYBar += " AND "; + } + querySupportXYBar += "(" + parser.sqlCondition(leftAttributesList.get(i)) + ")"; + } + + querySupportXYBar += ")\nAND CASE WHEN ("; + for (int i = 0; i < rightAttributesList.size(); i++) { + if (i > 0) { + querySupportXYBar += " AND "; + } + querySupportXYBar += "(" + parser.sqlCondition(rightAttributesList.get(i)) + ")"; + } + querySupportXYBar += ") THEN 1 ELSE 0 END = 0"; + /* end of query generation */ + ResultSet supXSet = db.executeQuery(querySupportX); + supXSet.next(); + double supX = supXSet.getInt(1); + ResultSet supXYBarSet = db.executeQuery(querySupportXYBar); + supXYBarSet.next(); + double supXYBar = supXYBarSet.getInt(1); + /* this query is used to get the nbligne of the sql statement from */ + String queryNBLigne = "select count(*) from " + parser.getSqlStatement(); + if (parser.getSqlConditions() != null) { + queryNBLigne += " where " + parser.getSqlConditions(); + } + ResultSet NBLigneSet = db.executeQuery(queryNBLigne); + NBLigneSet.next(); + double NBLigne = NBLigneSet.getInt(1); + System.out.println(NBLigne); + DecimalFormat df = new DecimalFormat("#.###"); + double supportXY = (supX - supXYBar) / NBLigne; + double supportX = supX / NBLigne; + double confidenceXY = (supportXY / supportX); + System.out.println("2"); + + if (supportXY != 0 && supportXY >= support && confidenceXY != 0 && confidenceXY >= confidence) { + return new CheckResult("true", df.format(supportXY).replace(',', '.'), + df.format(confidenceXY).replace(',', '.'), (int) supXYBar, sqlResults, sqlResults2, + sqlResults3); + } else { + query1 = "SELECT "; + // SELECT t1.att1, t1.att2, ... , t2.att1, t2.att2, ... , tn.attm + List tupVarList = parser.getTupVarList(); + for (int i = 0; i < tupVarList.size(); i++) { + if (i != 0) { + query1 += ", "; + } + + for (int j = 0; j < parser.getAttributeList().size(); j++) { + if (j != 0) { + query1 += ", "; + } + query1 += tupVarList.get(i) + "." + parser.getAttributeList().get(j); + } + } + query1 += "\nFROM " + parser.getSqlStatement() + "\nWHERE "; + + // WHERE [sqlConditions AND] + if (parser.getSqlConditions() != null) { + query1 += parser.getSqlConditions() + "\nAND "; + } + + // (conditions[left]) AND NOT (conditions[right]) + query1 += "("; + for (int i = 0; i < leftAttributesList.size(); i++) { + if (i > 0) { + query1 += " AND "; + } + query1 += "(" + parser.sqlCondition(leftAttributesList.get(i)) + ")"; + } + + query1 += ")\nAND CASE WHEN ("; + for (int i = 0; i < rightAttributesList.size(); i++) { + if (i > 0) { + query1 += " AND "; + } + query1 += "(" + parser.sqlCondition(rightAttributesList.get(i)) + ")"; + } + // AND rownum <= 10 + if (this.sqlCoreConf.getRqlDbType().equals("oracle")) { + query1 += ") THEN 1 ELSE 0 END = 0 \nAND rownum <= 10"; + } else if (this.sqlCoreConf.getRqlDbType().equals("postgresql")) { + query1 += ") THEN 1 ELSE 0 END = 0 Limit 10"; + } else if (this.sqlCoreConf.getRqlDbType().equals("mysql")) { + query1 += ") THEN 1 ELSE 0 END = 0 Limit 10"; + } + /* end of query generation */ + + /* query generation without attributs projection */ + query2 = "SELECT "; + // SELECT t1.att1, t1.att2, ... , t2.att1, t2.att2, ... , tn.attm + for (int i = 0; i < tupVarList.size(); i++) { + if (i != 0) { + query2 += ", "; + } + query2 += tupVarList.get(i) + ".*"; + } + query2 += "\nFROM " + parser.getSqlStatement() + "\nWHERE "; + + // WHERE [sqlConditions AND] + if (parser.getSqlConditions() != null) { + query2 += parser.getSqlConditions() + "\nAND "; + } + + // (conditions[left]) AND NOT (conditions[right]) + query2 += "("; + for (int i = 0; i < leftAttributesList.size(); i++) { + if (i > 0) { + query2 += " AND "; + } + query2 += "(" + parser.sqlCondition(leftAttributesList.get(i)) + ")"; + } + + query2 += ")\nAND CASE WHEN ("; + for (int i = 0; i < rightAttributesList.size(); i++) { + if (i > 0) { + query2 += " AND "; + } + query2 += "(" + parser.sqlCondition(rightAttributesList.get(i)) + ")"; + } + // AND rownum <= 1 + if (this.sqlCoreConf.getRqlDbType().equals("oracle")) { + query2 += ") THEN 1 ELSE 0 END = 0 \nAND rownum <= 10"; + } else if (this.sqlCoreConf.getRqlDbType().equals("postgresql")) { + query2 += ") THEN 1 ELSE 0 END = 0 Limit 10"; + } else if (this.sqlCoreConf.getRqlDbType().equals("mysql")) { + query2 += ") THEN 1 ELSE 0 END = 0 Limit 10"; + } + /* end of query generation */ + + /* query generation with attributs projection on left and right */ + query3 = "SELECT "; + // SELECT t1.att1, t1.att2, ... , t2.att1, t2.att2, ... , tn.attm + for (int i = 0; i < tupVarList.size(); i++) { + if (i != 0) { + query3 += ", "; + } + int k = 0; + for (int j = 0; j < leftAttributesList.size() + rightAttributesList.size(); j++) { + if (j != 0) { + query3 += ", "; + } + if (j < leftAttributesList.size()) { + query3 += tupVarList.get(i) + "." + leftAttributesList.get(j); + } else { + query3 += tupVarList.get(i) + "." + rightAttributesList.get(k); + k++; + } + } + } + query3 += "\nFROM " + parser.getSqlStatement() + "\nWHERE "; + + // WHERE [sqlConditions AND] + if (parser.getSqlConditions() != null) { + query3 += parser.getSqlConditions() + "\nAND "; + } + + // (conditions[left]) AND NOT (conditions[right]) + query3 += "("; + for (int i = 0; i < leftAttributesList.size(); i++) { + if (i > 0) { + query3 += " AND "; + } + query3 += "(" + parser.sqlCondition(leftAttributesList.get(i)) + ")"; + } + + query3 += ")\nAND CASE WHEN ("; + for (int i = 0; i < rightAttributesList.size(); i++) { + if (i > 0) { + query3 += " AND "; + } + query3 += "(" + parser.sqlCondition(rightAttributesList.get(i)) + ")"; + } + // AND rownum <= 1 + if (this.sqlCoreConf.getRqlDbType().equals("oracle")) { + query3 += ") THEN 1 ELSE 0 END = 0 \nAND rownum <= 10"; + } else if (this.sqlCoreConf.getRqlDbType().equals("postgresql")) { + query3 += ") THEN 1 ELSE 0 END = 0 Limit 10"; + } else if (this.sqlCoreConf.getRqlDbType().equals("mysql")) { + query3 += ") THEN 1 ELSE 0 END = 0 Limit 10"; + } + /* end of query generation */ + + ResultSet resultsSql = db.executeQuery(query1); + ResultSetMetaData rsmd = resultsSql.getMetaData(); + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + listEntetes.add(rsmd.getColumnName(i)); + } + sqlRow = new SQLRow(listEntetes); + counterExp.add(sqlRow); + while (resultsSql.next()) { + recurentList = new ArrayList(); + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + recurentList.add(resultsSql.getString(i)); + } + sqlRow = new SQLRow(recurentList); + counterExp.add(sqlRow); + } + if (counterExp.size() <= 1) { + isTrue = "false"; + } else { + isTrue = "false"; + + List recurent1 = new ArrayList(); + List recurent2 = new ArrayList(); + recurent1 = counterExp.get(0).getCels(); + int size = recurent1.size() / parser.getTupVarList().size(); + for (int i = 0; i < size; i++) { + recurent2.add(recurent1.get(i)); + } + sqlRow = new SQLRow(recurent2); + separated.add(sqlRow); + int size2; + + size2 = counterExp.size(); + + for (int i = 1; i < size2; i++) { + recurent1 = new ArrayList(counterExp.get(i).getCels()); + recurent2 = new ArrayList(); + for (int k = 0; k < parser.getTupVarList().size(); k++) { + recurent2 = new ArrayList(); + for (int j = k * size; j < k * size + size; j++) { + recurent2.add(recurent1.get(j)); + } + sqlRow = new SQLRow(recurent2); + separated.add(sqlRow); + } + } + rows = new ArrayList(); + for (int i = 1; i < separated.size(); i++) { + rows.add(separated.get(i)); + } + sqlResults = new SQLResultsRow(separated.get(0).getCels(), rows, true); + } + + ResultSet resultsSql2 = db.executeQuery(query2); + ResultSetMetaData rsmd2 = resultsSql2.getMetaData(); + listEntetes = new ArrayList(); + for (int i = 1; i <= rsmd2.getColumnCount(); i++) { + listEntetes.add(rsmd2.getColumnName(i)); + } + sqlRow = new SQLRow(listEntetes); + counterExp2.add(sqlRow); + while (resultsSql2.next()) { + recurentList = new ArrayList(); + for (int i = 1; i <= rsmd2.getColumnCount(); i++) { + recurentList.add(resultsSql2.getString(i)); + } + sqlRow = new SQLRow(recurentList); + counterExp2.add(sqlRow); + } + if (counterExp2.size() <= 1) { + } else { + List recurent1 = new ArrayList(); + List recurent2 = new ArrayList(); + if (counterExp.size() != 0) { + recurent1 = counterExp2.get(0).getCels(); + int size = recurent1.size() / parser.getTupVarList().size(); + for (int i = 0; i < size; i++) { + recurent2.add(recurent1.get(i)); + } + sqlRow = new SQLRow(recurent2); + separated2.add(sqlRow); + int size2; + + size2 = counterExp2.size(); + + for (int i = 1; i < size2; i++) { + recurent1 = new ArrayList(counterExp2.get(i).getCels()); + recurent2 = new ArrayList(); + for (int k = 0; k < parser.getTupVarList().size(); k++) { + recurent2 = new ArrayList(); + for (int j = k * size; j < k * size + size; j++) { + recurent2.add(recurent1.get(j)); + } + sqlRow = new SQLRow(recurent2); + separated2.add(sqlRow); + } + + } + } + rows = new ArrayList(); + for (int i = 1; i < separated2.size(); i++) { + rows.add(separated2.get(i)); + } + sqlResults2 = new SQLResultsRow(separated2.get(0).getCels(), rows, true); + } + + ResultSet resultsSql3 = db.executeQuery(query3); + ResultSetMetaData rsmd3 = resultsSql3.getMetaData(); + listEntetes = new ArrayList(); + for (int i = 1; i <= rsmd3.getColumnCount(); i++) { + listEntetes.add(rsmd3.getColumnName(i)); + } + sqlRow = new SQLRow(listEntetes); + counterExp3.add(sqlRow); + while (resultsSql3.next()) { + recurentList = new ArrayList(); + for (int i = 1; i <= rsmd3.getColumnCount(); i++) { + recurentList.add(resultsSql3.getString(i)); + } + sqlRow = new SQLRow(recurentList); + counterExp3.add(sqlRow); + } + if (counterExp3.size() <= 1) { + } else { + List recurent1 = new ArrayList(); + List recurent2 = new ArrayList(); + if (counterExp3.size() != 0) { + recurent1 = counterExp3.get(0).getCels(); + int size = recurent1.size() / parser.getTupVarList().size(); + for (int i = 0; i < size; i++) { + recurent2.add(recurent1.get(i)); + } + sqlRow = new SQLRow(recurent2); + separated3.add(sqlRow); + int size2; + + size2 = counterExp3.size(); + + for (int i = 1; i < size2; i++) { + recurent1 = new ArrayList(counterExp3.get(i).getCels()); + recurent2 = new ArrayList(); + for (int k = 0; k < parser.getTupVarList().size(); k++) { + recurent2 = new ArrayList(); + for (int j = k * size; j < k * size + size; j++) { + recurent2.add(recurent1.get(j)); + } + sqlRow = new SQLRow(recurent2); + separated3.add(sqlRow); + } + + } + } + rows = new ArrayList(); + for (int i = 1; i < separated3.size(); i++) { + rows.add(separated3.get(i)); + } + sqlResults3 = new SQLResultsRow(separated3.get(0).getCels(), rows, true); + System.out.println(sqlResults3.getHeader()); + for (int i = 0; i < sqlResults3.getRows().size(); i++) { + System.out.println(sqlResults3.getRows().get(i).getCels()); + } + } + System.out.println("3"); + return new CheckResult(isTrue, df.format(supportXY).replace(',', '.'), + df.format(confidenceXY).replace(',', '.'), (int) supXYBar, sqlResults, sqlResults2, + sqlResults3); + } + } catch (Exception e) { + e.printStackTrace(); + return new CheckResult("NoValideAttributes", null, null, 0, sqlResults, sqlResults2, sqlResults3); + } + + } + + public RuleChecker(SqlCoreConf sqlConf) { + super(); + this.sqlCoreConf = sqlConf; + } + + public String getRqlQuery() { + return rqlQuery; + } + + public void setRqlQuery(String rqlQuery) { + this.rqlQuery = rqlQuery; + } + + public String getLeftAttributes() { + return leftAttributes; + } + + public void setLeftAttributes(String leftAttributes) { + this.leftAttributes = leftAttributes; + } + + public String getRightAttribute() { + return rightAttribute; + } + + public void setRightAttribute(String rightAttribute) { + this.rightAttribute = rightAttribute; + } + + private static ArrayList parseAttributeList(String attributes) { + ArrayList result = new ArrayList(); + String attribute = new String(attributes); + + attribute += ' '; + + if (attribute.indexOf(' ') == -1) { + result.add(attribute); + } else { + String tempAttribute = attribute.substring(0, attribute.indexOf(' ')); + + while (attribute.length() > 0) { + result.add(tempAttribute); + attribute = attribute.replace(tempAttribute + ' ', ""); + + if (attribute.length() > 0) { + tempAttribute = attribute.substring(0, attribute.indexOf(' ')); + } + } + } + + return result; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLManager.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLManager.java new file mode 100644 index 0000000..dc52772 --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLManager.java @@ -0,0 +1,346 @@ +package fr.ensma.lias.rql.sql; + +import java.io.IOException; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.ListIterator; +import java.util.Set; + +import org.json.JSONObject; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import fr.ensma.lias.rql.cfg.SqlCoreConf; +import fr.ensma.lias.rql.database.Column; +import fr.ensma.lias.rql.database.DataBaseSchema; +import fr.ensma.lias.rql.database.Database; +import fr.ensma.lias.rql.database.MysqlDB; +import fr.ensma.lias.rql.database.OracleDB; +import fr.ensma.lias.rql.database.PostgresqlDB; +import fr.ensma.lias.rql.database.Table; + +/** + * @author Bilal REZKELLAH + */ +public class SQLManager { + + private String sqlQuery; + + private SqlCoreConf sqlCoreConf; + + private Database db = null; + + private List finalList = new ArrayList(); + + private List recurentList = new ArrayList(); + + private List listEntete = new ArrayList(); + + public List getListEntete() { + return listEntete; + } + + public void setListEntete(List listEntete) { + this.listEntete = listEntete; + } + + public String getSqlQuery() { + return sqlQuery; + } + + public void setSqlQuery(String sqlQuery) { + this.sqlQuery = sqlQuery; + } + + public List getFinalList() { + return finalList; + } + + public void setFinalList(List finalList) { + this.finalList = finalList; + } + + public List getRecurentList() { + return recurentList; + } + + public void setRecurentList(List recurentList) { + this.recurentList = recurentList; + } + + public SQLManager(SqlCoreConf sqlCoreConf) { + this.sqlCoreConf = sqlCoreConf; + } + + public void openDB() throws SQLException { + if (sqlCoreConf.getRqlDbType().equals("oracle")) { + db = new OracleDB(); + } else if (sqlCoreConf.getRqlDbType().equals("postgresql")) { + db = new PostgresqlDB(); + } else if (sqlCoreConf.getRqlDbType().equals("mysql")) { + db = new MysqlDB(); + } + db.open(sqlCoreConf.getRqlDbHost(), sqlCoreConf.getRqlDbPort(), sqlCoreConf.getRqlDbName(), + sqlCoreConf.getRqlDbAdminLogin(), sqlCoreConf.getRqlDbAdminPwd()); + System.out.println("\nconnexion etablie \n"); + } + + public void closeDB() throws IOException { + db.close(); + } + + public DataBaseSchema getDataBaseSchema() throws SQLException { + List
tables = new ArrayList
(); + Table myTable; + List tablesName = new ArrayList(); + List colTabName = new ArrayList(); + String tablesNameQuery = ""; + if (sqlCoreConf.getRqlDbType().equals("oracle")) { + db = new OracleDB(); + tablesNameQuery = "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER =" + "'" + + sqlCoreConf.getRqlDbAdminLogin().toUpperCase() + "'" + " order by TABLE_NAME asc"; + } else if (sqlCoreConf.getRqlDbType().equals("postgresql")) { + db = new PostgresqlDB(); + tablesNameQuery = "SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'public' order by TABLE_NAME asc"; + } else if (sqlCoreConf.getRqlDbType().equals("mysql")) { + db = new MysqlDB(); + tablesNameQuery = "SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'public' order by TABLE_NAME asc"; + } + db.open(sqlCoreConf.getRqlDbHost(), sqlCoreConf.getRqlDbPort(), sqlCoreConf.getRqlDbName(), + sqlCoreConf.getRqlDbAdminLogin(), sqlCoreConf.getRqlDbAdminPwd()); + + ResultSet resultsName = db.executeQuery(tablesNameQuery); + while (resultsName.next()) { + if (!resultsName.getString(1).contains("$")) { + System.out.println(resultsName.getString(1)); + tablesName.add(resultsName.getString(1)); + } + } + ListIterator it = tablesName.listIterator(); + String colNameQuery = ""; + String actualTab = ""; + ResultSet resultCol = null; + while (it.hasNext()) { + myTable = new Table(); + colTabName = new ArrayList(); + actualTab = it.next(); + Column column = null; + System.out.println(actualTab); + if (sqlCoreConf.getRqlDbType().equals("oracle")) { + colNameQuery = "SELECT column_name, data_type column_type FROM user_tab_cols WHERE table_name =" + "'" + + actualTab + "'"; + } else if (sqlCoreConf.getRqlDbType().equals("postgresql")) { + colNameQuery = "SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' and table_name =" + + "'" + actualTab + "'"; + } else if (sqlCoreConf.getRqlDbType().equals("mysql")) { + colNameQuery = "SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' and table_name =" + + "'" + actualTab + "'"; + } + resultCol = db.executeQuery(colNameQuery); + while (resultCol.next()) { + column = new Column(resultCol.getString(1), resultCol.getString(2)); + colTabName.add(column); + } + myTable.setTableName(actualTab); + myTable.setColumnsName(colTabName); + tables.add(myTable); + } + return new DataBaseSchema(tables); + } + + public List getDataBaseTablesHeader() throws SQLException { + List tablesName = new ArrayList(); + String tablesNameQuery = ""; + if (sqlCoreConf.getRqlDbType().equals("oracle")) { + db = new OracleDB(); + tablesNameQuery = "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER =" + "'" + + sqlCoreConf.getRqlDbAdminLogin().toUpperCase() + "'" + " order by TABLE_NAME asc"; + } else if (sqlCoreConf.getRqlDbType().equals("postgresql")) { + db = new PostgresqlDB(); + tablesNameQuery = "SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'public' order by TABLE_NAME asc"; + } else if (sqlCoreConf.getRqlDbType().equals("mysql")) { + db = new MysqlDB(); + tablesNameQuery = "SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'public' order by TABLE_NAME asc"; + } + db.open(sqlCoreConf.getRqlDbHost(), sqlCoreConf.getRqlDbPort(), sqlCoreConf.getRqlDbName(), + sqlCoreConf.getRqlDbAdminLogin(), sqlCoreConf.getRqlDbAdminPwd()); + ResultSet resultsName = db.executeQuery(tablesNameQuery); + while (resultsName.next()) { + if (!resultsName.getString(1).contains("$")) { + System.out.println(resultsName.getString(1)); + tablesName.add(resultsName.getString(1)); + } + } + return tablesName; + } + + public ResultSet execute(String query) throws Exception { + if (sqlCoreConf.getRqlDbType().equals("oracle")) { + db = new OracleDB(); + } else if (sqlCoreConf.getRqlDbType().equals("postgresql")) { + db = new PostgresqlDB(); + } else if (sqlCoreConf.getRqlDbType().equals("mysql")) { + db = new MysqlDB(); + } else { + throw new Exception(); + } + db.open(sqlCoreConf.getRqlDbHost(), sqlCoreConf.getRqlDbPort(), sqlCoreConf.getRqlDbName(), + sqlCoreConf.getRqlDbAdminLogin(), sqlCoreConf.getRqlDbAdminPwd()); + + return db.executeQuery(query); + } + + public List getAttributesList(String id, String queryType) throws SQLException { + List colTabName = new ArrayList(); + String colNameQuery = ""; + System.out.println("queryType:" + queryType); + if (!queryType.equals("Metric Functional Dependencies")) { + if (sqlCoreConf.getRqlDbType().equals("oracle")) { + db = new OracleDB(); + colNameQuery = "SELECT column_name FROM user_tab_cols WHERE table_name =" + "'" + id + "'"; + + } else if (sqlCoreConf.getRqlDbType().equals("postgresql")) { + db = new PostgresqlDB(); + colNameQuery = "SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' and table_name =" + + "'" + id + "'"; + } else if (sqlCoreConf.getRqlDbType().equals("mysql")) { + db = new MysqlDB(); + colNameQuery = "SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' and table_name =" + + "'" + id + "'"; + } + } else { + if (sqlCoreConf.getRqlDbType().equals("oracle")) { + db = new OracleDB(); + colNameQuery = "SELECT column_name FROM user_tab_cols WHERE table_name =" + "'" + id + + "' and (data_type LIKE '%NUMBER%' or data_type LIKE '%FLOAT%' or data_type LIKE '%DOUBLE%')"; + + } else if (sqlCoreConf.getRqlDbType().equals("postgresql")) { + db = new PostgresqlDB(); + colNameQuery = "SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' and table_name =" + + "'" + id + "'" + + " and (data_type = 'integer' or data_type = 'smallint' or data_type = 'bigint' or data_type = 'serial' or data_type = 'bigserial' or data_type LIKE 'number%' or data_type LIKE 'decimal%' or\r\n" + + "data_type LIKE 'real%' or data_type LIKE 'double precision%')"; + } else if (sqlCoreConf.getRqlDbType().equals("mysql")) { + db = new MysqlDB(); + colNameQuery = "SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' and table_name =" + + "'" + id + "'" + + " and (data_type LIKE '%int%' or data_type = 'serial' or data_type = 'bigserial' or data_type LIKE 'number%' or data_type LIKE 'double%' or data_type LIKE 'float%' or data_type LIKE 'decimal%' or\r\n" + + "data_type LIKE 'real%' or data_type LIKE 'double precision%')"; + } + } + db.open(sqlCoreConf.getRqlDbHost(), sqlCoreConf.getRqlDbPort(), sqlCoreConf.getRqlDbName(), + sqlCoreConf.getRqlDbAdminLogin(), sqlCoreConf.getRqlDbAdminPwd()); + + ResultSet resultCol = db.executeQuery(colNameQuery); + while (resultCol.next()) { + colTabName.add(resultCol.getString(1)); + } + return colTabName; + } + + public SQLResultsObject executeQuery(String sqlQuery) + throws SQLException, JsonParseException, JsonMappingException, IOException { + Boolean isSelect = false; + this.sqlQuery = sqlQuery; + if (sqlCoreConf.getRqlDbType().equals("oracle")) { + db = new OracleDB(); + } else if (sqlCoreConf.getRqlDbType().equals("postgresql")) { + db = new PostgresqlDB(); + } else if (sqlCoreConf.getRqlDbType().equals("mysql")) { + db = new MysqlDB(); + } + db.open(sqlCoreConf.getRqlDbHost(), sqlCoreConf.getRqlDbPort(), sqlCoreConf.getRqlDbName(), + sqlCoreConf.getRqlDbAdminLogin(), sqlCoreConf.getRqlDbAdminPwd()); + System.out.println("\nconnexion etablie \n"); + System.out.println(sqlQuery); + ResultSet resultsSql = db.executeQuery(sqlQuery); + List rows = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + + if (resultsSql != null) { + isSelect = true; + ResultSetMetaData resultMeta = resultsSql.getMetaData(); + List header = new ArrayList(); + for (int i = 1; i <= resultMeta.getColumnCount(); i++) { + header.add(resultMeta.getColumnName(i)); + } + Set set = new LinkedHashSet<>(); + for (String str : header) { + if (!str.equals("")) { + String value = str; + for (int i1 = 1; !set.add(value); i1++) { + value = str + i1; + } + } + } + header = new ArrayList(); + header.addAll(set); + + while (resultsSql.next()) { + JSONObject json = new JSONObject(); + + for (int i = 1; i <= resultMeta.getColumnCount(); i++) { + Object obj = resultsSql.getObject(i); + if (obj == null) { + + json.put(resultMeta.getColumnName(i), ""); + } else { + + json.put(header.get(i - 1), obj.toString()); + } + + } + Object obj = mapper.readValue(json.toString(), Object.class); + rows.add(obj); + } + for (int i = 1; i <= resultMeta.getColumnCount(); i++) { + listEntete.add(header.get(i - 1)); + } + } + return new SQLResultsObject(listEntete, rows, isSelect); + } + + public void insertRow(String query) throws SQLException { + ResultSet resultsSql = db.executeQuery(query); + } + + public SQLResultsRow executeQuery2(String sqlQuery) throws SQLException { + SQLRow sqlRow; + Boolean isSelect = false; + this.sqlQuery = sqlQuery; + if (sqlCoreConf.getRqlDbType().equals("oracle")) { + db = new OracleDB(); + } else if (sqlCoreConf.getRqlDbType().equals("postgresql")) { + db = new PostgresqlDB(); + } else if (sqlCoreConf.getRqlDbType().equals("mysql")) { + db = new MysqlDB(); + } + db.open(sqlCoreConf.getRqlDbHost(), sqlCoreConf.getRqlDbPort(), sqlCoreConf.getRqlDbName(), + sqlCoreConf.getRqlDbAdminLogin(), sqlCoreConf.getRqlDbAdminPwd()); + System.out.println("\nconnexion etablie \n"); + System.out.println(sqlQuery); + ResultSet resultsSql = db.executeQuery(sqlQuery); + if (resultsSql != null) { + isSelect = true; + ResultSetMetaData rsmd = resultsSql.getMetaData(); + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + listEntete.add(rsmd.getColumnName(i)); + } + while (resultsSql.next()) { + recurentList = new ArrayList(); + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + recurentList.add(resultsSql.getString(i)); + } + sqlRow = new SQLRow(recurentList); + finalList.add(sqlRow); + } + } + return new SQLResultsRow(listEntete, finalList, isSelect); + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResults.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResults.java new file mode 100644 index 0000000..6913eec --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResults.java @@ -0,0 +1,36 @@ +package fr.ensma.lias.rql.sql; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class SQLResults { + + public List header = new ArrayList(); + + private Boolean isSelect; + + public SQLResults(List header, Boolean isSelect) { + this.header = header; + this.isSelect = isSelect; + } + + public Boolean getIsSelect() { + return isSelect; + } + + public void setIsSelect(Boolean isSelect) { + this.isSelect = isSelect; + } + + public List getHeader() { + return header; + } + + public void setHeader(List header) { + this.header = header; + } + +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResultsObject.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResultsObject.java new file mode 100644 index 0000000..002a6eb --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResultsObject.java @@ -0,0 +1,25 @@ +package fr.ensma.lias.rql.sql; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class SQLResultsObject extends SQLResults { + + public SQLResultsObject(List header, List rows, Boolean isSelect) { + super(header, isSelect); + this.rows = rows; + } + + public List rows = new ArrayList(); + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResultsRow.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResultsRow.java new file mode 100644 index 0000000..035e7cc --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLResultsRow.java @@ -0,0 +1,25 @@ +package fr.ensma.lias.rql.sql; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class SQLResultsRow extends SQLResults { + + public SQLResultsRow(List header, List rows, Boolean isSelect) { + super(header, isSelect); + this.rows = rows; + } + + private List rows = new ArrayList(); + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } +} diff --git a/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLRow.java b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLRow.java new file mode 100644 index 0000000..74cdddb --- /dev/null +++ b/rql-backend/rql-core/src/main/java/fr/ensma/lias/rql/sql/SQLRow.java @@ -0,0 +1,23 @@ +package fr.ensma.lias.rql.sql; + +import java.util.List; + +/** + * @author Bilal REZKELLAH + */ +public class SQLRow { + + private List cels; + + public List getCels() { + return cels; + } + + public void setCels(List cels) { + this.cels = cels; + } + + public SQLRow(List cels) { + this.cels = cels; + } +} diff --git a/rql-backend/rql-core/src/main/resources/fr/ensma/lias/rql/rqlgrammar/RQL.jj b/rql-backend/rql-core/src/main/resources/fr/ensma/lias/rql/rqlgrammar/RQL.jj new file mode 100644 index 0000000..eb95597 --- /dev/null +++ b/rql-backend/rql-core/src/main/resources/fr/ensma/lias/rql/rqlgrammar/RQL.jj @@ -0,0 +1,418 @@ +options +{ + static = false; + SUPPORT_CLASS_VISIBILITY_PUBLIC = false; +} + +PARSER_BEGIN(RQLParser) +package fr.ensma.lias.rql.rqlgrammar; +import java.io.StringReader; +import java.io.Reader; +import java.util.Collections; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + + +public class RQLParser { + private List attributes; + private List tupVarList = new ArrayList(); + private String sqlStatement; + private String rqlVar; + private String rqlConditions; + private String sqlConditions; + + public List getTupVarList() { + return tupVarList; + } + + public String getSqlStatement() { + return sqlStatement; + } + + public String getSqlConditions() { + return sqlConditions; + } + + public List getAttributeList() { + return Collections.unmodifiableList(attributes); + } + + public RQLParser(String s) { + this((Reader)(new StringReader(s))); + } + + public String sqlCondition(String attributeName) throws ParseException { + //return rqlConditions.replace(rqlVar, attributeName); + Pattern regex = Pattern.compile("(^|[^0-9a-zA-Z])" + rqlVar.replace("$", "\\$") + + "($|[^0-9a-zA-Z])"); + Matcher matcher = regex.matcher(rqlConditions); + if (matcher.find() == false) { + throw new ParseException("Attribute Variable (" + rqlVar + + ") not found in condition (" + rqlConditions + ")"); + } + StringBuffer buf = new StringBuffer(); + matcher.reset(); + while (matcher.find()) { + matcher.appendReplacement(buf, + matcher.group().replace(rqlVar, attributeName)); + } + matcher.appendTail(buf); + return buf.toString(); + } + + public static RQLParser parse(String rqlQuery) + throws ParseException { + RQLParser parser = new RQLParser(rqlQuery); + try { + parser.rqlQuery(); + } catch (TokenMgrError e) { + e.printStackTrace(); + throw new ParseException(e.getMessage()); + } + return(parser); + } + + public void improve() { + /* purely cosmetic part */ + /* trim sqlQuery */ + if (sqlStatement.charAt(sqlStatement.length() - 1) == '\n') { + sqlStatement = sqlStatement.substring(0, sqlStatement.length() - 1); + } + sqlStatement = sqlStatement.trim(); + /* trim rqlConditions */ + while (rqlConditions.charAt(rqlConditions.length() - 1) == '\n') { + rqlConditions = + rqlConditions.substring(0, rqlConditions.length() - 1); + } + rqlConditions = rqlConditions.trim(); + /* trim sqlConditions */ + if (sqlConditions != null) { + while (sqlConditions.charAt(sqlConditions.length() - 1) == '\n') { + sqlConditions = + sqlConditions.substring(0, sqlConditions.length() - 1); + } + sqlConditions = sqlConditions.trim(); + } + } + + public String oracleQuery() throws ParseException { + improve(); + /* Oracle syntax */ + StringBuffer query = new StringBuffer(); + query.append("SELECT count(*), ag FROM (\n"); + query.append("SELECT\n("); + for (int i = 0; i < attributes.size(); i++) { + if (i > 0) { + query.append(" ||"); + } + query.append("\n CASE WHEN "); + query.append(sqlCondition(attributes.get(i))); + query.append(" THEN '"); + query.append(Integer.toString(i)); + query.append(" ' END"); + } + query.append("\n) as ag\nFROM "); + query.append(sqlStatement); + if (sqlConditions != null) { + query.append("\nWHERE "); + query.append(sqlConditions); + } + query.append("\n)\nGROUP BY ag\nORDER BY ag ASC"); + return query.toString(); + } + + public String mysqlQuery() throws ParseException { + improve(); + /* MySQL syntax */ + StringBuffer query = new StringBuffer(); + query.append("SELECT count(*), ag FROM (\n"); + query.append("SELECT\n(\n CONCAT("); + for (int i = 0; i < attributes.size(); i++) { + if (i > 0) { + query.append(","); + } + query.append("\n CASE WHEN "); + query.append(sqlCondition(attributes.get(i))); + query.append(" THEN '"); + query.append(Integer.toString(i)); + query.append(" ' ELSE '' END"); + } + query.append("\n )\n) as ag\nFROM "); + query.append(sqlStatement); + if (sqlConditions != null) { + query.append("\nWHERE "); + query.append(sqlConditions); + } + query.append("\n) t1\nGROUP BY ag\nORDER BY ag ASC"); + return query.toString(); + } + public String postgresQuery() throws ParseException { + improve(); + /* Postgresql syntax */ + StringBuffer query = new StringBuffer(); + query.append("SELECT count(*), ag FROM (\n"); + query.append("SELECT\n(\n CONCAT("); + for (int i = 0; i < attributes.size(); i++) { + if (i > 0) { + query.append(","); + } + query.append("\n CASE WHEN "); + query.append(sqlCondition(attributes.get(i))); + query.append(" THEN '"); + query.append(Integer.toString(i)); + query.append(" ' ELSE '' END"); + } + query.append("\n )\n) as ag\nFROM "); + query.append(sqlStatement); + if (sqlConditions != null) { + query.append("\nWHERE "); + query.append(sqlConditions); + } + query.append("\n) as Base\nGROUP BY ag\nORDER BY ag ASC"); + return query.toString(); + } +} +PARSER_END(RQLParser) + +SKIP : +{ + " " +| "\t" +| "\n" +| "\r" +| "\r\n" +} + +TOKEN : +{ + < LEFT_PAR : "(" > +| < RIGHT_PAR : ")" > +| < COMMA : "," > +| < CONDITION : "CONDITION" | "condition" > +| < FINDRULES : "FINDRULES" | "findrules" > +| < IS : "IS" | "is" > +| < ON : "ON" | "on" > +| < OVER : "OVER" | "over" > +| < SCOPE : "SCOPE" | "scope" > +| < WHERE : "WHERE" | "where" > +| < WORD : ( | "_" | "$" ) ( | | "_" )* > +| < #LETTER : ["a"-"z","A"-"Z"] > +| < #DIGIT : ["0"-"9"] > +| < OTHER : ~[] > +} + + SKIP: +{ + "" +} + + TOKEN: +{ + < SQL_LEFT_PAR : "(" > +| < SQL_RIGHT_PAR : ")" > +| < SQL_OTHER : ~[] > +} + + SKIP: +{ + "" +} + + TOKEN: +{ + < SQLCOND_CONDITION : "CONDITION" | "condition" > +| < SQLCOND_OTHER : ~[] > +} + + SKIP: +{ + "" +} + + TOKEN: +{ + < SQLFORM_OTHER : ~[] > +} + +void rqlQuery() : +{} +{ + + attributeList() + + this.sqlStatement = tupleVariableList() + ( + + this.sqlConditions = sqlCondition() + // in sqlCondition() + | + + ) + + attributeVariable() + + miningFormula() + +} + +void attributeList() : +{} +{ + this.attributes = idList() +} + +List idList() : +{ + List list = new ArrayList(); + Token t; +} +{ + t = + { list.add(t.image); } + ( + + t = + { list.add(t.image); } + )* + { return list; } +} + +String tupleVariableList() : +{ + List tupVarList; + Token t; + StringBuilder buf = new StringBuilder(); + String query = null; +} +{ + tupVarList = idList() + { this.tupVarList.addAll(tupVarList); } + ( + + query = sqlStatement() + // in sqlStatement() + { + for (int i = 0; i < tupVarList.size(); i++) { + if (i > 0) { + buf.append(", "); + } + buf.append("("); + buf.append(query); + buf.append(") "); + buf.append(tupVarList.get(i)); + } + } + | + t = + { + for (int i = 0; i < tupVarList.size(); i++) { + if (i > 0) { + buf.append(", "); + } + buf.append(t.image); + buf.append(" "); + buf.append(tupVarList.get(i)); + } + } + ) + ( + + query = tupleVariableList() + { buf.append(", "); } + { buf.append(query); } + )? + { return buf.toString(); } +} + +void attributeVariable() : +{ + Token t; +} +{ + t = + { this.rqlVar = t.image; } +} + +void miningFormula() : +{} +{ + this.rqlConditions = sql() +} + +String sqlStatement() : +{ + Token t; + StringBuffer buf = new StringBuffer(); + String subStatement; +} +{ + { token_source.SwitchTo(SQL); } + ( + t = + { buf.append(t.image); } + | + t = + { buf.append(t.image); } + subStatement = sqlSubStatement() + { buf.append(subStatement); } + t = + { buf.append(t.image); } + )* + + { token_source.SwitchTo(DEFAULT); } + { return buf.toString(); } +} + +String sqlSubStatement() : +{ + Token t; + StringBuffer buf = new StringBuffer(); + String subStatement; +} +{ + ( + t = + { buf.append(t.image); } + | + t = + { buf.append(t.image); } + subStatement = sqlSubStatement() + { buf.append(subStatement); } + t = + { buf.append(t.image); } + )* + { return buf.toString(); } +} + +String sqlCondition() : +{ + Token t; + StringBuffer buf = new StringBuffer(); +} +{ + { token_source.SwitchTo(SQLCOND); } + ( + t = + { buf.append(t.image); } + )* + + { token_source.SwitchTo(DEFAULT); } + { return buf.toString(); } +} + +String sql() : +{ + Token t; + StringBuffer buf = new StringBuffer(); +} +{ + { token_source.SwitchTo(SQLFORM); } + ( + t = + { buf.append(t.image); } + )* + { token_source.SwitchTo(DEFAULT); } + { return buf.toString(); } +} diff --git a/rql-backend/rql-core/src/main/resources/fr/ensma/lias/rql/rulesgrammar/Rules.jj b/rql-backend/rql-core/src/main/resources/fr/ensma/lias/rql/rulesgrammar/Rules.jj new file mode 100644 index 0000000..67bf479 --- /dev/null +++ b/rql-backend/rql-core/src/main/resources/fr/ensma/lias/rql/rulesgrammar/Rules.jj @@ -0,0 +1,158 @@ +options +{ + static = false; + SUPPORT_CLASS_VISIBILITY_PUBLIC = false; +} + +PARSER_BEGIN(RulesParser) +package fr.ensma.lias.rql.rulesgrammar; + +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Reader; +import java.util.List; +import java.io.OutputStream; + +public class RulesParser implements Closeable { + private OutputStream out; + private List atts; + + public RulesParser(String inFile, OutputStream outStream, + List attributeList) throws IOException { + this((Reader)(new FileReader(inFile))); + out = outStream; + atts = attributeList; + } + + public void close() throws IOException { + out.flush(); + out.close(); + } + + public static void translate(String inFile, OutputStream outStream, List attributeList) throws ParseException, IOException { + RulesParser parser = new RulesParser(inFile,outStream, attributeList); + parser.rules(null, 0, null); + parser.close(); + } + + public static void translate(String inFile, OutputStream outStream, List attributeList, List previewExact, int previewSize, int[] counts) throws ParseException, IOException { + RulesParser parser = new RulesParser(inFile,outStream, attributeList); + parser.rules(previewExact, previewSize, counts); + parser.close(); + } +} + +PARSER_END(RulesParser) + +SKIP : +{ + " " +| "\t" +| "\n" +| "\r" +| "\r\n" +} + +TOKEN : +{ + < IMPLICATION : "=>" > +| < EMPTY : "-1" > +| < INTEGER : ( )* > +| < #DIGIT : ["0"-"9"] > +| < OTHER : ~[] > +} + +void rules(List previewExact, int previewSize, int[] counts) throws IOException : +{ + String rl; +} +{ + ( + rl = rule() + { + if (previewExact != null) + { + if ( previewExact.size() < previewSize) + { + previewExact.add(rl); + counts[0]++; + } + } + } + )* + +} + +String rule() throws IOException : +{ + Token t; + StringBuilder rule = new StringBuilder(); +} +{ + + /* left member: list of attributes or empty */ + ( + ( + t = + { rule.append(atts.get(Integer.parseInt(t.image)) + " "); + } + )+ + | + ( + + { rule.append("empty "); } + ) + ) + + { rule.append("=>"); } + /* right member: single attribute */ + t = + { rule.append(" " + atts.get(Integer.parseInt(t.image)));} + t = + { rule.append(" " + Integer.parseInt(t.image));} + t = + { rule.append(" " + Integer.parseInt(t.image));} + t = + { rule.append(" " + Integer.parseInt(t.image));} + t = + { rule.append(" " + Integer.parseInt(t.image) + "\n");} + { out.write(rule.toString().getBytes()); } + { return rule.toString(); } +} + +boolean metadata() throws IOException : +{ + Token t; + int nX; + int nXY; +} +{ + /* tuples */ + t = + // { out.write("\t" + t.image);} + /* nX */ + t = + // { out.write("\t" + t.image); } + { nX = Integer.parseInt(t.image); } + /* nY */ + t = + // { out.write("\t" + t.image); } + /* nXY */ + t = + { + // out.write("\t" + t.image + "\n"); + nXY = Integer.parseInt(t.image); + if (nX == nXY) + { + out.write("\t(exact)\n".getBytes()); + } + else + { + out.write("\t(G&L cover)\n".getBytes()); + } + return (nX == nXY); + } +} diff --git a/rql-backend/rql-core/src/test/java/DELETE.me b/rql-backend/rql-core/src/test/java/DELETE.me new file mode 100644 index 0000000..e69de29 diff --git a/rql-backend/rql-core/src/test/resources/DELETE.me b/rql-backend/rql-core/src/test/resources/DELETE.me new file mode 100644 index 0000000..e69de29 diff --git a/rql-backend/rql-server/pom.xml b/rql-backend/rql-server/pom.xml new file mode 100644 index 0000000..71041a9 --- /dev/null +++ b/rql-backend/rql-server/pom.xml @@ -0,0 +1,98 @@ + + 4.0.0 + rql-server + + fr.ensma.lias + rql-backend + 1.1.0-SNAPSHOT + + + + ${project.groupId} + rql-api + ${project.version} + + + javax.ws.rs + jsr311-api + + + + + org.glassfish.jersey.containers + jersey-container-servlet-core + + + + org.glassfish.jersey.containers + jersey-container-grizzly2-http + + + org.glassfish.jersey.media + jersey-media-multipart + + + + org.glassfish.jersey.media + jersey-media-json-jackson + + + + org.glassfish.jersey.ext.cdi + jersey-weld2-se + + + + org.apache.poi + poi-ooxml + + + + org.aeonbits.owner + owner + + + + org.slf4j + slf4j-api + + + + org.slf4j + slf4j-log4j12 + + + + org.mindrot + jbcrypt + + + fr.ensma.lias + rql-core + + + org.jasypt + jasypt + 1.9.2 + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + package + + copy-dependencies + + + + + + + \ No newline at end of file diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/AuthToken.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/AuthToken.java new file mode 100644 index 0000000..e60a3bd --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/AuthToken.java @@ -0,0 +1,39 @@ +package fr.ensma.lias.rql; + +import java.util.Date; + +/** + * @author Bilal REZKELLAH + */ +public class AuthToken { + + protected String identifiant; + + protected Date startDate; + + public AuthToken(String pIdentifiant, Date pStartDate) { + this.identifiant = pIdentifiant; + this.startDate = pStartDate; + } + + public boolean isValid() { + return identifiant != null && startDate != null; + } + + public String getIdentifiant() { + return identifiant; + } + + public String getStartDateValue() { + return Long.toString(startDate.getTime()); + } + + public Date getStartDate() { + return startDate; + } + + @Override + public String toString() { + return "AuthToken [identifiant=" + identifiant + ", startDate=" + startDate + "]"; + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/CrossDomainFilter.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/CrossDomainFilter.java new file mode 100644 index 0000000..148414c --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/CrossDomainFilter.java @@ -0,0 +1,21 @@ +package fr.ensma.lias.rql; + +import java.io.IOException; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; + +/** + * @author Bilal REZKELLAH + */ +public class CrossDomainFilter implements ContainerResponseFilter { + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext cresp) throws IOException { + cresp.getHeaders().add("Access-Control-Allow-Origin", "http://localhost:8080"); + cresp.getHeaders().add("Access-Control-Allow-Credentials", "true"); + cresp.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); + cresp.getHeaders().add("Allow", "GET, POST, DELETE, PUT"); + cresp.getHeaders().add("Access-Control-Allow-Headers", "Content-Type, Accept, authorization"); + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlConstant.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlConstant.java new file mode 100644 index 0000000..4ff08b2 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlConstant.java @@ -0,0 +1,13 @@ +package fr.ensma.lias.rql; + +/** + * @author Bilal REZKELLAH + */ +public interface RqlConstant { + + static final int WORKLOAD = 12; + + static final String AUTH_TOKEN_SEPARATOR = "#"; + + static final int SESSION_TIMEOUT_DEFAULT = 300; +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlLauncher.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlLauncher.java new file mode 100644 index 0000000..a9f2bab --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlLauncher.java @@ -0,0 +1,61 @@ +package fr.ensma.lias.rql; + +import java.net.URI; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.ws.rs.core.UriBuilder; + +import org.glassfish.grizzly.http.server.HttpServer; +import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.glassfish.jersey.server.ResourceConfig; +import org.jboss.weld.environment.se.Weld; +import org.jboss.weld.environment.se.WeldContainer; + +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.service.AuthenticationResourceImpl; +import fr.ensma.lias.rql.service.DataBaseImportImp; +import fr.ensma.lias.rql.service.ProjectResourceImp; +import fr.ensma.lias.rql.service.QueryConstructionImp; +import fr.ensma.lias.rql.service.QueryResourceImp; +import fr.ensma.lias.rql.service.SchemaResourceImp; +import fr.ensma.lias.rql.service.UserResourceImp; +import fr.ensma.lias.rql.service.XlsxResourceImp; + +/** + * @author Bilal REZKELLAH + */ +public class RqlLauncher { + + private static URI getBaseURI(Integer value) { + return UriBuilder.fromUri("http://0.0.0.0/").port(value).build(); + } + + public static void main(String[] args) { + Logger l = Logger.getLogger("org.glassfish.grizzly.http.server.HttpHandler"); + l.setLevel(Level.FINE); + l.setUseParentHandlers(false); + ConsoleHandler ch = new ConsoleHandler(); + ch.setLevel(Level.ALL); + l.addHandler(ch); + + ResourceConfig rc = new ResourceConfig(); + rc.registerClasses(UserResourceImp.class, ProjectResourceImp.class, AuthenticationResourceImpl.class, + MultiPartFeature.class, DataBaseImportImp.class, QueryResourceImp.class, SchemaResourceImp.class, + XlsxResourceImp.class, QueryConstructionImp.class, CrossDomainFilter.class); + rc.property("jersey.config.server.wadl.disableWadl", "false"); + + Weld weld = new Weld(); + final WeldContainer initialize = weld.initialize(); + final IConfiguration refRQLConfiguration = initialize.instance().select(IConfiguration.class).get(); + try { + HttpServer server = GrizzlyHttpServerFactory.createHttpServer( + getBaseURI(Integer.parseInt(refRQLConfiguration.getConfiguration().rqlServerPort())), rc); + server.start(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlUtil.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlUtil.java new file mode 100644 index 0000000..1480644 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/RqlUtil.java @@ -0,0 +1,81 @@ +package fr.ensma.lias.rql; + +import java.util.Date; + +import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; +import org.mindrot.jbcrypt.BCrypt; + +/** + * @author Bilal REZKELLAH + */ +public class RqlUtil { + + public static String hashPassword(String password_plaintext) { + String salt = BCrypt.gensalt(RqlConstant.WORKLOAD); + String hashed_password = BCrypt.hashpw(password_plaintext, salt); + + return (hashed_password); + } + + public static boolean checkPassword(String newPassword, String old) { + return BCrypt.checkpw(newPassword, old); + } + + public static String encryptToken(AuthToken currentToken, String password, String noise) { + if (currentToken != null && !currentToken.isValid()) { + return null; + } + + return RqlUtil.encrypt(currentToken.getIdentifiant() + RqlConstant.AUTH_TOKEN_SEPARATOR + + currentToken.getStartDateValue() + RqlConstant.AUTH_TOKEN_SEPARATOR + noise, password); + } + + public static AuthToken decryptToken(String value, String password, String noise) { + if (value == null) { + return null; + } + + AuthToken currentToken = null; + try { + final String decrypt = RqlUtil.decrypt(value, password); + + if (decrypt == null) { + return null; + } + + final String[] split = decrypt.split(RqlConstant.AUTH_TOKEN_SEPARATOR); + + if (split == null || split.length != 3) { + return null; + } + + String previousIdentifiant = split[0]; + Date previousStartDate = new Date(Long.parseLong(split[1])); + String previousNoise = split[2]; + + if (!noise.equals(previousNoise)) { + return null; + } + + currentToken = new AuthToken(previousIdentifiant, previousStartDate); + return currentToken; + } catch (Exception e) { + return null; + } + } + + public static String encrypt(String content, String password) { + return RqlUtil.getEncryptor(password).encrypt(content); + } + + public static String decrypt(String content, String password) { + return RqlUtil.getEncryptor(password).decrypt(content); + } + + private static StandardPBEStringEncryptor getEncryptor(String password) { + StandardPBEStringEncryptor cookieEncryptor = new StandardPBEStringEncryptor(); + cookieEncryptor.setStringOutputType("hexadecimal"); + cookieEncryptor.setPassword(password); + return cookieEncryptor; + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/Configuration.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/Configuration.java new file mode 100644 index 0000000..fac47a1 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/Configuration.java @@ -0,0 +1,23 @@ +package fr.ensma.lias.rql.cfg; + +import javax.inject.Singleton; + +import org.aeonbits.owner.ConfigFactory; + +/** + * @author Bilal REZKELLAH + */ +@Singleton +public class Configuration implements IConfiguration { + + protected RqlConfig config; + + public Configuration() { + config = ConfigFactory.create(RqlConfig.class); + } + + @Override + public RqlConfig getConfiguration() { + return config; + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/IConfiguration.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/IConfiguration.java new file mode 100644 index 0000000..de9a1f2 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/IConfiguration.java @@ -0,0 +1,9 @@ +package fr.ensma.lias.rql.cfg; + +/** + * @author Bilal REZKELLAH + */ +public interface IConfiguration { + + RqlConfig getConfiguration(); +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/RqlConfig.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/RqlConfig.java new file mode 100644 index 0000000..349ba26 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/cfg/RqlConfig.java @@ -0,0 +1,61 @@ +package fr.ensma.lias.rql.cfg; + +import org.aeonbits.owner.Config; + +/** + * @author Bilal REZKELLAH + */ +public interface RqlConfig extends Config { + + @DefaultValue("postgres") + String rqlDbName(); + + @DefaultValue("db") + String rqlDbHost(); + + @DefaultValue("business_db") + String rqlDbHostMetier(); + + @DefaultValue("5432") + Integer rqlDbPort(); + + @DefaultValue("postgresql") + String rqlDbType(); + + @DefaultValue("postgres") + String rqlDbAdminLogin(); + + @DefaultValue("postgres") + String rqlDbAdminPwd(); + + @Key("rql.identification.user") + @DefaultValue("admin") + String identificationUser(); + + @Key("rql.identification.password") + @DefaultValue("adminadmin") + String identificationPassword(); + + @Key("rql.encrypt.password") + @DefaultValue("!thisismypassword!") + String encryptPassword(); + + @Key("rql.encrypt.noise") + @DefaultValue("@BCDEFGHIJKLMNPQRSTUVWXZ&bcdefghijklmnopqrstuvwxyz0123456789") + String encryptNoise(); + + @Key("rql.session.timeout") + @DefaultValue("60") + String sessionTimeout(); + + @DefaultValue("../shd31/shd") + String pathToShd(); + + @DefaultValue("./target/tmpFiles") + String tmpResultsDir(); + + @Key("rql.server.port") + @DefaultValue("9992") + String rqlServerPort(); + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/IRql.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/IRql.java new file mode 100644 index 0000000..3b38280 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/IRql.java @@ -0,0 +1,50 @@ +package fr.ensma.lias.rql.core; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import fr.ensma.lias.rql.dto.CheckRuleResult; +import fr.ensma.lias.rql.dto.RQLResult; +import fr.ensma.lias.rql.dto.SQLResult; +import fr.ensma.lias.rql.dto.SchemaResult; +import fr.ensma.lias.rql.model.DataBaseConfig; +import fr.ensma.lias.rql.rqlgrammar.ParseException; +import fr.ensma.lias.rql.sql.SQLResultsRow; + +/** + * @author Bilal REZKELLAH + */ +public interface IRql { + + SQLResult executeSqlQuery(String sqlquery, DataBaseConfig dbc) + throws SQLException, JsonParseException, JsonMappingException, IOException; + + SQLResultsRow executeSqlQuery2(String sqlquery, DataBaseConfig dbc) throws SQLException; + + Boolean isRqlQuery(String query); + + RQLResult executeRqlQuery(String id, double support, double confidence) throws Exception; + + SchemaResult getDataBaseSchema(DataBaseConfig dbc) throws SQLException, IOException; + + List getDataBaseTablesHeader(DataBaseConfig dbc) throws SQLException, IOException; + + List getTableAttributesList(String id, String queryType, DataBaseConfig dbc) + throws SQLException, IOException; + + String constructQuery(String QueryType, String isTable, String isALLData, String sqlQuerie, String tableName, + String subsetWhere, String attributesList, boolean isConditional, String conditionalWhere, + String tolerence); + + CheckRuleResult checkRule(long debut, DataBaseConfig dbc, String query, String leftAttributes, + String rightAttribute, double support, double confidence) throws ParseException; + + void testQuery(String query) throws ParseException; + + String normalizeName(String source, String dbt); + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/RqlConstant.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/RqlConstant.java new file mode 100644 index 0000000..03c36ef --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/RqlConstant.java @@ -0,0 +1,9 @@ +package fr.ensma.lias.rql.core; + +/** + * @author Bilal REZKELLAH + */ +public class RqlConstant { + + static final String FIND_RULES = "FINDRULES"; +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/RqlImp.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/RqlImp.java new file mode 100644 index 0000000..987f5b8 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/core/RqlImp.java @@ -0,0 +1,204 @@ +package fr.ensma.lias.rql.core; + +import java.io.File; +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import javax.inject.Inject; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import fr.ensma.lias.rql.RQLManager; +import fr.ensma.lias.rql.RQLResults; +import fr.ensma.lias.rql.Rule; +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.cfg.SqlCoreConf; +import fr.ensma.lias.rql.dao.query.IQueryDAO; +import fr.ensma.lias.rql.database.DataBaseSchema; +import fr.ensma.lias.rql.database.Table; +import fr.ensma.lias.rql.dbimport.MySqlNameNormalizer; +import fr.ensma.lias.rql.dbimport.NameNormalizer; +import fr.ensma.lias.rql.dbimport.OracleNameNormalizer; +import fr.ensma.lias.rql.dbimport.PostgresNameNormalizer; +import fr.ensma.lias.rql.dto.CheckRuleResult; +import fr.ensma.lias.rql.dto.CheckRuleSummary; +import fr.ensma.lias.rql.dto.RQLResult; +import fr.ensma.lias.rql.dto.RQLRow; +import fr.ensma.lias.rql.dto.RuleGenerationSummary; +import fr.ensma.lias.rql.dto.SQLResult; +import fr.ensma.lias.rql.dto.SchemaResult; +import fr.ensma.lias.rql.model.DataBaseConfig; +import fr.ensma.lias.rql.queryconstruction.QueryConstructor; +import fr.ensma.lias.rql.rqlgrammar.ParseException; +import fr.ensma.lias.rql.rqlgrammar.RQLParser; +import fr.ensma.lias.rql.rulecheck.CheckResult; +import fr.ensma.lias.rql.rulecheck.RuleChecker; +import fr.ensma.lias.rql.sql.SQLManager; +import fr.ensma.lias.rql.sql.SQLResultsObject; +import fr.ensma.lias.rql.sql.SQLResultsRow; + +/** + * @author Bilal REZKELLAH + */ +public class RqlImp implements IRql { + + Properties props = new Properties(); + + @Inject + IConfiguration cfg; + + @Inject + IQueryDAO iquery; + + @Override + public SQLResult executeSqlQuery(String sqlquery, DataBaseConfig dbc) + throws SQLException, JsonParseException, JsonMappingException, IOException { + + SQLManager sql = new SQLManager(new SqlCoreConf(dbc.getDataBaseName(), dbc.getDataBaseHost(), + dbc.getDataBasePort(), dbc.getDataBaseType(), dbc.getDataBaseUser(), dbc.getDataBasePassword())); + SQLResultsObject sqlResults = sql.executeQuery(sqlquery); + SQLResult sqlResult = new SQLResult(); + sqlResult.setHeader(sqlResults.getHeader()); + sqlResult.setIsSelect(sqlResults.getIsSelect()); + for (int i = 0; i < sqlResults.getRows().size(); i++) { + Object sqlRow = new Object(); + sqlRow = sqlResults.getRows().get(i); + sqlResult.getRows().add(sqlRow); + } + return sqlResult; + } + + @Override + public Boolean isRqlQuery(String query) { + return (query.contains(RqlConstant.FIND_RULES) || query.contains("FINDRULE")); + } + + @Override + public RQLResult executeRqlQuery(String id, double support, double confidence) throws Exception { + long debut = System.currentTimeMillis(); + RuleGenerationSummary summ; + RQLResults rqlResults = new RQLResults(); + RQLRow row; + List exact = new ArrayList(); + RQLParser parse = iquery.getParserByID(id); + File resultDir = new File(cfg.getConfiguration().tmpResultsDir()); + resultDir.mkdir(); + String agFile = resultDir.getCanonicalPath() + File.separator + id + "rql_agree_set.txt"; + RQLManager rql = new RQLManager(agFile); + rql.resultsToFile2(iquery.getBaseByID(id).getContent(), parse.getAttributeList().size()); + rql.executeDFG(agFile, agFile + "_rules.txt", parse.getAttributeList().size(), support, confidence, + cfg.getConfiguration().pathToShd()); + rqlResults = rql.translate(resultDir.getCanonicalPath() + File.separator + id + "rules.txt", + agFile + "_rules.txt", parse.getAttributeList()); + + for (Rule currentRules : rqlResults.getExactRules()) { + row = new RQLRow(); + row.setLeftAttributes(String.join(" ", currentRules.getLeftAttributes())); + row.setRightAttribute(currentRules.getRightAttributes()); + row.setSupport(currentRules.getSupport() * 100); + row.setConfidence(currentRules.getConfidence() * 100); + row.setLift(currentRules.getLift()); + exact.add(row); + } + + summ = new RuleGenerationSummary(System.currentTimeMillis() - debut, parse.getAttributeList(), + parse.getTupVarList()); + RQLResult rqlResult = new RQLResult(exact, summ); + return rqlResult; + } + + @Override + public SchemaResult getDataBaseSchema(DataBaseConfig dbc) throws SQLException, IOException { + List
tables = new ArrayList
(); + SQLManager sql = new SQLManager(new SqlCoreConf(dbc.getDataBaseName(), dbc.getDataBaseHost(), + dbc.getDataBasePort(), dbc.getDataBaseType(), dbc.getDataBaseUser(), dbc.getDataBasePassword())); + DataBaseSchema schema = sql.getDataBaseSchema(); + sql.closeDB(); + tables = schema.getTables(); + SchemaResult tablesResults = new SchemaResult(tables); + + return tablesResults; + } + + @Override + public CheckRuleResult checkRule(long debut, DataBaseConfig dbc, String id, String leftAttributes, + String rightAttribute, double support, double confidence) throws ParseException { + String query = iquery.getQueryByID(id); + RQLParser parser = iquery.getParserByID(id); + RuleChecker ruleChecker = new RuleChecker(new SqlCoreConf(dbc.getDataBaseName(), dbc.getDataBaseHost(), + dbc.getDataBasePort(), dbc.getDataBaseType(), dbc.getDataBaseUser(), dbc.getDataBasePassword())); + CheckResult checkResult = ruleChecker.CheckRule(parser, query, leftAttributes, rightAttribute, support, + confidence); + CheckRuleSummary summary = new CheckRuleSummary(System.currentTimeMillis() - debut, parser.getAttributeList(), + parser.getTupVarList(), checkResult.getCounterExamplesNB(), parser.getTupVarList().size(), + checkResult.getIsTrue(), checkResult.getSupport(), checkResult.getConfidence()); + return new CheckRuleResult(checkResult, summary); + } + + @Override + public List getDataBaseTablesHeader(DataBaseConfig dbc) throws SQLException, IOException { + List tablesHeader; + SQLManager sql = new SQLManager(new SqlCoreConf(dbc.getDataBaseName(), dbc.getDataBaseHost(), + dbc.getDataBasePort(), dbc.getDataBaseType(), dbc.getDataBaseUser(), dbc.getDataBasePassword())); + tablesHeader = sql.getDataBaseTablesHeader(); + sql.closeDB(); + return tablesHeader; + } + + @Override + public List getTableAttributesList(String id, String queryType, DataBaseConfig dbc) + throws SQLException, IOException { + List attributesList; + SQLManager sql = new SQLManager(new SqlCoreConf(dbc.getDataBaseName(), dbc.getDataBaseHost(), + dbc.getDataBasePort(), dbc.getDataBaseType(), dbc.getDataBaseUser(), dbc.getDataBasePassword())); + attributesList = sql.getAttributesList(id, queryType); + sql.closeDB(); + return attributesList; + } + + @Override + public String constructQuery(String QueryType, String isTable, String isALLData, String sqlQuerie, String tableName, + String subsetWhere, String attributesList, boolean isConditional, String conditionalWhere, + String tolerence) { + String rqlQuery; + QueryConstructor queryConstructor = new QueryConstructor(); + rqlQuery = queryConstructor.constructquery(QueryType, isTable, isALLData, sqlQuerie, tableName, subsetWhere, + attributesList, isConditional, conditionalWhere, tolerence); + return rqlQuery; + } + + @Override + public void testQuery(String query) throws ParseException { + RQLParser parse = RQLParser.parse(query); + System.out.println(parse.postgresQuery()); + } + + @Override + public SQLResultsRow executeSqlQuery2(String sqlquery, DataBaseConfig dbc) throws SQLException { + SQLManager sql = new SQLManager(new SqlCoreConf(dbc.getDataBaseName(), dbc.getDataBaseHost(), + dbc.getDataBasePort(), dbc.getDataBaseType(), dbc.getDataBaseUser(), dbc.getDataBasePassword())); + SQLResultsRow sqlResults = sql.executeQuery2(sqlquery); + return sqlResults; + } + + @Override + public String normalizeName(String source, String dbType) { + NameNormalizer nNormalizer = null; + if (dbType.equals("postgresql")) { + nNormalizer = new PostgresNameNormalizer(); + source = nNormalizer.colNameNormalizer(source); + } else if (dbType.equals("oracle")) { + nNormalizer = new OracleNameNormalizer(); + source = nNormalizer.colNameNormalizer(source); + } else if (dbType.equals("mysql")) { + nNormalizer = new MySqlNameNormalizer(); + source = nNormalizer.colNameNormalizer(source); + } else { + } + return source; + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbconfiguration/ConfigurationDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbconfiguration/ConfigurationDAO.java new file mode 100644 index 0000000..422c893 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbconfiguration/ConfigurationDAO.java @@ -0,0 +1,68 @@ +package fr.ensma.lias.rql.dao.dbconfiguration; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.inject.Inject; + +import fr.ensma.lias.rql.dao.postgressession.IPostgresSession; +import fr.ensma.lias.rql.model.DataBaseConfig; + +/** + * @author Bilal REZKELLAH + */ +public class ConfigurationDAO implements IConfigurationDAO { + + @Inject + IPostgresSession ips; + + @Override + public DataBaseConfig getConfigByID(String id) throws SQLException, IOException { + Connection conn = ips.getConnection(); + Statement stmt = conn.createStatement(); + String query = "SELECT * FROM DATABASE WHERE projectid = " + "'" + Integer.valueOf(id) + "'"; + System.out.println(query); + ResultSet rs = stmt.executeQuery(query); + rs.next(); + DataBaseConfig dbc = new DataBaseConfig(); + dbc.setDataBaseHost(rs.getString("host")); + dbc.setDataBaseName(rs.getString("name")); + dbc.setDataBasePassword(rs.getString("password")); + dbc.setDataBasePort(rs.getInt("port")); + dbc.setDataBaseType(rs.getString("type")); + dbc.setDataBaseUser(rs.getString("userid")); + return dbc; + } + + @Override + public String createConfig(DataBaseConfig dbc) throws SQLException { + String SQL = "INSERT INTO DATABASE (projectid,host,name,password,port,type,userid) " + "VALUES(?,?,?,?,?,?,?)"; + long id = 0; + Connection conn = ips.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS); + pstmt.setInt(1, Integer.valueOf(dbc.getProjectid())); + pstmt.setString(2, dbc.getDataBaseHost()); + pstmt.setString(3, dbc.getDataBaseName()); + pstmt.setString(4, dbc.getDataBasePassword()); + pstmt.setInt(5, dbc.getDataBasePort()); + pstmt.setString(6, dbc.getDataBaseType()); + pstmt.setString(7, dbc.getDataBaseUser()); + + int affectedRows = pstmt.executeUpdate(); + // check the affected rows + if (affectedRows > 0) { + // get the ID back + ResultSet rs = pstmt.getGeneratedKeys(); + if (rs.next()) { + id = rs.getLong(1); + } + } + + return Long.toString(id); + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbconfiguration/IConfigurationDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbconfiguration/IConfigurationDAO.java new file mode 100644 index 0000000..f6b0768 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbconfiguration/IConfigurationDAO.java @@ -0,0 +1,17 @@ +package fr.ensma.lias.rql.dao.dbconfiguration; + +import java.io.IOException; +import java.sql.SQLException; + +import fr.ensma.lias.rql.model.DataBaseConfig; + +/** + * @author Bilal REZKELLAH + */ +public interface IConfigurationDAO { + + DataBaseConfig getConfigByID(String ProjectID) throws SQLException, IOException; + + String createConfig(DataBaseConfig dbc) throws SQLException; + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/AbstractSchemaDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/AbstractSchemaDAO.java new file mode 100644 index 0000000..026e2bf --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/AbstractSchemaDAO.java @@ -0,0 +1,67 @@ +package fr.ensma.lias.rql.dao.dbschema; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.xssf.usermodel.XSSFSheet; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import fr.ensma.lias.rql.core.IRql; + +/** + * @author Bilal REZKELLAH + */ +public class AbstractSchemaDAO implements ISchemaDAO { + + @Inject + IRql irql; + + public CellType getColType(XSSFSheet sheet, Integer index) { + Row rowi = sheet.getRow(1); + CellType cellType = null; + int rowIndex = 1; + cellType = rowi.getCell(index).getCellTypeEnum(); + if (cellType == CellType.BLANK) { + while (cellType == CellType.BLANK && rowIndex < sheet.getPhysicalNumberOfRows() - 1) { + rowi = sheet.getRow(++rowIndex); + cellType = rowi.getCell(index).getCellTypeEnum(); + } + if (rowIndex == sheet.getPhysicalNumberOfRows() - 1) { + cellType = CellType.STRING; + } + } + if (cellType == CellType.NUMERIC) { + rowIndex = 1; + while ((cellType == CellType.NUMERIC || cellType == CellType.BLANK) + && rowIndex < sheet.getPhysicalNumberOfRows() - 1) { + rowi = sheet.getRow(++rowIndex); + cellType = rowi.getCell(index).getCellTypeEnum(); + } + if (cellType != CellType.NUMERIC && cellType != CellType.BLANK) { + cellType = CellType.STRING; + } else { + + cellType = CellType.NUMERIC; + } + } + return cellType; + } + + public String cellTypeMap(CellType cellType) { + return null; + } + + @Override + public String createTable(XSSFSheet sheet, List intList, String tableName) + throws SQLException, JsonParseException, JsonMappingException, IOException { + return null; + }; + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/ISchemaDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/ISchemaDAO.java new file mode 100644 index 0000000..a4d2dfc --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/ISchemaDAO.java @@ -0,0 +1,19 @@ +package fr.ensma.lias.rql.dao.dbschema; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +import org.apache.poi.xssf.usermodel.XSSFSheet; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +/** + * @author Bilal REZKELLAH + */ +public interface ISchemaDAO { + + String createTable(XSSFSheet sheet, List intList, String tableName) + throws SQLException, JsonParseException, JsonMappingException, IOException; +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/MySqlSchemaDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/MySqlSchemaDAO.java new file mode 100644 index 0000000..5a9963d --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/MySqlSchemaDAO.java @@ -0,0 +1,20 @@ +package fr.ensma.lias.rql.dao.dbschema; + +import org.apache.poi.ss.usermodel.CellType; + +/** + * @author Bilal REZKELLAH + */ +public class MySqlSchemaDAO extends AbstractSchemaDAO { + public String cellTypeMap(CellType cellType) { + if (cellType == CellType.STRING) { + return "TEXT"; + } else if (cellType == CellType.NUMERIC) { + return "BIGINT"; + } else if (cellType == CellType.BOOLEAN) { + return "BOOLEAN"; + } else { + return null; + } + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/OracleSchemaDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/OracleSchemaDAO.java new file mode 100644 index 0000000..c79ba2f --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/OracleSchemaDAO.java @@ -0,0 +1,21 @@ +package fr.ensma.lias.rql.dao.dbschema; + +import org.apache.poi.ss.usermodel.CellType; + +/** + * @author Bilal REZKELLAH + */ +public class OracleSchemaDAO extends AbstractSchemaDAO { + + public String cellTypeMap(CellType cellType) { + if (cellType == CellType.STRING) { + return "VARCHAR2(200)"; + } else if (cellType == CellType.NUMERIC) { + return "NUMBER(20)"; + } else if (cellType == CellType.BOOLEAN) { + return "BOOLEAN"; + } else { + return null; + } + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/PostgresSchemaDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/PostgresSchemaDAO.java new file mode 100644 index 0000000..9d4ab41 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/PostgresSchemaDAO.java @@ -0,0 +1,151 @@ +package fr.ensma.lias.rql.dao.dbschema; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; + +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.xssf.usermodel.XSSFSheet; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.cfg.SqlCoreConf; +import fr.ensma.lias.rql.dao.dbconfiguration.IConfigurationDAO; +import fr.ensma.lias.rql.dbimport.NameNormalizer; +import fr.ensma.lias.rql.dbimport.PostgresNameNormalizer; +import fr.ensma.lias.rql.sql.SQLManager; + + +/** + * @author Bilal REZKELLAH + */ +public class PostgresSchemaDAO extends AbstractSchemaDAO { + + @Inject + IConfiguration cfg; + + @Inject + IConfigurationDAO iconfig; + + public String cellTypeMap(CellType cellType) { + if (cellType == CellType.STRING) { + return "TEXT"; + } else if (cellType == CellType.NUMERIC) { + return "BIGINT"; + } else if (cellType == CellType.BOOLEAN) { + return "BOOLEAN"; + } else { + return null; + } + } + + public String importTable(XSSFSheet sheet, List intList, String tableName, String projectID) + throws SQLException, JsonParseException, JsonMappingException, IOException { + String scriptSQL = ""; + String createTable = null; + List colTypeList = new ArrayList(); + System.out.println(cfg.getConfiguration().rqlDbName()); + + NameNormalizer nNormalizer = new PostgresNameNormalizer(); + + SQLManager sql = new SQLManager( + new SqlCoreConf(cfg.getConfiguration().rqlDbName(), cfg.getConfiguration().rqlDbHost(), + cfg.getConfiguration().rqlDbPort(), cfg.getConfiguration().rqlDbType(), + cfg.getConfiguration().rqlDbAdminLogin(), cfg.getConfiguration().rqlDbAdminPwd())); + + sql.openDB(); + Row titleRow = sheet.getRow(0); + createTable = "CREATE TABLE " + nNormalizer.colNameNormalizer(tableName) + " ("; + + List header = new ArrayList(); + DataFormatter formatter = new DataFormatter(); + for (int j = 0; j < titleRow.getLastCellNum(); j++) { + String val = formatter.formatCellValue(titleRow.getCell(j)); + header.add(val); + } + Set set = new LinkedHashSet<>(); + for (String str : header) { + if (!str.equals("")) { + String value = str; + for (int i1 = 1; !set.add(value); i1++) { + value = str + i1; + } + } + } + header = new ArrayList(); + header.addAll(set); + for (int i = 0; i < intList.size(); i++) { + if (i == 0) { + createTable += nNormalizer.colNameNormalizer(header.get(intList.get(i))) + " " + + cellTypeMap(getColType(sheet, intList.get(i))); + } else { + createTable += ", " + nNormalizer.colNameNormalizer(header.get(intList.get(i))) + " " + + cellTypeMap(colTypeList.get(i)); + + } + } + createTable += ")"; + scriptSQL += createTable; + irql.executeSqlQuery(createTable, iconfig.getConfigByID(projectID)); + String insertRow = ""; + insertRow = "INSERT INTO " + nNormalizer.colNameNormalizer(tableName) + " ("; + for (int i = 0; i < intList.size(); i++) { + if (i == 0) { + insertRow += nNormalizer.colNameNormalizer(header.get(intList.get(i))); + } else { + insertRow += ", " + nNormalizer.colNameNormalizer(header.get(intList.get(i))); + } + } + insertRow += ") "; + String values = ""; + Iterator iteratorRow = sheet.iterator(); + if (iteratorRow.hasNext()) + iteratorRow.next(); + while (iteratorRow.hasNext()) { + values = insertRow + "VALUES("; + Row row = iteratorRow.next(); + for (int i = 0; i < intList.size(); i++) { + if (colTypeList.get(i) == CellType.STRING) { + String val = formatter.formatCellValue(row.getCell(intList.get(i))); + if (i == 0) { + values += "'" + val.replace("'", "") + "'"; + } else { + values += ", " + "'" + val.replace("'", "") + "'"; + } + } else if (colTypeList.get(i) == CellType.NUMERIC) { + Integer val = -1; + val = (int) row.getCell(intList.get(i)).getNumericCellValue(); + if (i == 0) { + values += val; + } else { + values += ", " + val; + } + } else if (colTypeList.get(i) == CellType.BOOLEAN) { + + } else { + boolean val = (boolean) row.getCell(intList.get(i)).getBooleanCellValue(); + if (i == 0) { + values += val; + } else { + values += ", " + val; + } + } + } + values += ")"; + scriptSQL += values; + sql.insertRow(values); + } + sql.closeDB(); + return scriptSQL; + }; +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/favorite/FavoriteDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/favorite/FavoriteDAO.java new file mode 100644 index 0000000..96dce6a --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/favorite/FavoriteDAO.java @@ -0,0 +1,105 @@ +package fr.ensma.lias.rql.dao.dbschema.favorite; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import fr.ensma.lias.rql.dao.postgressession.IPostgresSession; +import fr.ensma.lias.rql.dto.Favorite; + +/** + * @author Bilal REZKELLAH + */ +public class FavoriteDAO implements IFavoriteDAO { + + @Inject + IPostgresSession ips; + + @Override + public String createFavorite(Favorite favorite) throws SQLException { + String SQL = "INSERT INTO favorite (query,creationdate,description,projectID,favoritename,type) " + + "VALUES(?,?,?,?,?,?)"; + long id = 0; + Connection conn = ips.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS); + pstmt.setString(1, favorite.getQuery()); + pstmt.setString(2, favorite.getCreationDate()); + pstmt.setString(3, favorite.getDescription()); + pstmt.setInt(4, Integer.valueOf(favorite.getProjectID())); + pstmt.setString(5, favorite.getName()); + pstmt.setString(6, favorite.getType()); + int affectedRows = pstmt.executeUpdate(); + // check the affected rows + if (affectedRows > 0) { + // get the ID back + ResultSet rs = pstmt.getGeneratedKeys(); + if (rs.next()) { + id = rs.getLong(1); + } + } + return Long.toString(id); + } + + @Override + public boolean deleteFavorite(String favoriteID) throws SQLException { + String SQL = "DELETE FROM FAVORITE WHERE favoriteid = ? "; + Connection conn = ips.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS); + pstmt.setInt(1, Integer.valueOf(favoriteID)); + pstmt.execute(); + return pstmt.execute(); + } + + @Override + public List getAllFavoriteByProject(String projectID) throws SQLException { + Favorite favorite; + List favoriteList = new ArrayList(); + Connection conn = ips.getConnection(); + String query = "SELECT * FROM FAVORITE WHERE projectid = ? "; + PreparedStatement pstmt = conn.prepareStatement(query); + pstmt.setInt(1, Integer.valueOf(projectID)); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + favorite = new Favorite(); + favorite.setQuery(rs.getString("query")); + favorite.setCreationDate(rs.getString("creationdate")); + favorite.setProjectID(String.valueOf(rs.getInt("projectid"))); + favorite.setId(rs.getString("favoriteid")); + favorite.setDescription(rs.getString("description")); + favorite.setName(rs.getString("favoritename")); + favorite.setType(rs.getString("type")); + favoriteList.add(favorite); + } + return favoriteList; + } + + @Override + public List getAllFavoriteSQLQueries(String projectID) throws SQLException { + Favorite favorite; + List favoriteList = new ArrayList(); + Connection conn = ips.getConnection(); + String query = "SELECT * FROM FAVORITE WHERE projectid = ? and type = 'SQL' "; + PreparedStatement pstmt = conn.prepareStatement(query); + pstmt.setInt(1, Integer.valueOf(projectID)); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + favorite = new Favorite(); + favorite.setQuery(rs.getString("query")); + favorite.setCreationDate(rs.getString("creationdate")); + favorite.setProjectID(String.valueOf(rs.getInt("projectid"))); + favorite.setId(rs.getString("favoriteid")); + favorite.setDescription(rs.getString("description")); + favorite.setName(rs.getString("favoritename")); + favorite.setType(rs.getString("type")); + favoriteList.add(favorite); + } + return favoriteList; + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/favorite/IFavoriteDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/favorite/IFavoriteDAO.java new file mode 100644 index 0000000..917a74b --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/dbschema/favorite/IFavoriteDAO.java @@ -0,0 +1,20 @@ +package fr.ensma.lias.rql.dao.dbschema.favorite; + +import java.sql.SQLException; +import java.util.List; + +import fr.ensma.lias.rql.dto.Favorite; + +/** + * @author Bilal REZKELLAH + */ +public interface IFavoriteDAO { + + String createFavorite(Favorite favorite) throws SQLException; + + boolean deleteFavorite(String favoriteID) throws SQLException; + + List getAllFavoriteByProject(String projectID) throws SQLException; + + List getAllFavoriteSQLQueries(String projectID) throws SQLException; +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/inmemory/InMemory.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/inmemory/InMemory.java new file mode 100644 index 0000000..f1af1ec --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/inmemory/InMemory.java @@ -0,0 +1,63 @@ +package fr.ensma.lias.rql.dao.inmemory; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Singleton; + +import fr.ensma.lias.rql.baseresults.BaseResult; +import fr.ensma.lias.rql.rqlgrammar.RQLParser; + +/** + * @author Bilal REZKELLAH + */ +@Singleton +public class InMemory { + + private Map RqlQueryDB; + + private Map SqlQueryDB; + + private Map RqlBaseDB; + + private Map rqlParserDB; + + public Map getRqlParserDB() { + return rqlParserDB; + } + + public void setRqlParserDB(Map rqlParserDB) { + this.rqlParserDB = rqlParserDB; + } + + public Map getRqlQueryDB() { + return RqlQueryDB; + } + + public void setRqlQueryDB(Map rqlQueryDB) { + RqlQueryDB = rqlQueryDB; + } + + public Map getRqlBaseDB() { + return RqlBaseDB; + } + + public void setRqlBaseDB(Map rqlBaseDB) { + RqlBaseDB = rqlBaseDB; + } + + public InMemory() { + RqlQueryDB = new HashMap(); + SqlQueryDB = new HashMap(); + RqlBaseDB = new HashMap(); + rqlParserDB = new HashMap(); + } + + public Map getSqlQueryDB() { + return SqlQueryDB; + } + + public void setSqlQueryDB(Map sqlQueryDB) { + SqlQueryDB = sqlQueryDB; + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/postgressession/IPostgresSession.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/postgressession/IPostgresSession.java new file mode 100644 index 0000000..ac7ad1f --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/postgressession/IPostgresSession.java @@ -0,0 +1,12 @@ +package fr.ensma.lias.rql.dao.postgressession; + +import java.sql.Connection; + +/** + * @author Bilal REZKELLAH + */ +public interface IPostgresSession { + + Connection getConnection(); + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/postgressession/PostgresSession.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/postgressession/PostgresSession.java new file mode 100644 index 0000000..4da6202 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/postgressession/PostgresSession.java @@ -0,0 +1,42 @@ +package fr.ensma.lias.rql.dao.postgressession; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +import javax.inject.Singleton; + +import fr.ensma.lias.rql.cfg.Configuration; + + +/** + * @author Bilal REZKELLAH + */ +@Singleton +public class PostgresSession implements IPostgresSession { + + Configuration cfg = new Configuration(); + private Connection cx; + + public PostgresSession() throws SQLException { + System.out.println(cfg.getConfiguration().rqlDbAdminLogin()); + cx = DriverManager.getConnection( + "jdbc:postgresql://" + cfg.getConfiguration().rqlDbHost() + ":" + cfg.getConfiguration().rqlDbPort() + + "/" + "rql", + cfg.getConfiguration().rqlDbAdminLogin(), cfg.getConfiguration().rqlDbAdminPwd()); + } + + @Override + public Connection getConnection() { + return cx; + } + + public Connection getCx() { + return cx; + } + + public void setCx(Connection cx) { + this.cx = cx; + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/project/IProjectDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/project/IProjectDAO.java new file mode 100644 index 0000000..f56f11e --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/project/IProjectDAO.java @@ -0,0 +1,23 @@ +package fr.ensma.lias.rql.dao.project; + +import java.sql.SQLException; +import java.util.List; + +import fr.ensma.lias.rql.dto.Project; + +/** + * @author Bilal REZKELLAH + */ +public interface IProjectDAO { + + List getAllProjectByUser(String UserID) throws SQLException; + + String createProject(Project project) throws SQLException; + + Project getProjectById(String projectID) throws SQLException; + + boolean deleteProjectbyId(String projectID) throws SQLException; + + boolean updateProject(Project project) throws SQLException; + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/project/ProjectDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/project/ProjectDAO.java new file mode 100644 index 0000000..909da13 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/project/ProjectDAO.java @@ -0,0 +1,128 @@ +package fr.ensma.lias.rql.dao.project; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.dao.postgressession.IPostgresSession; +import fr.ensma.lias.rql.dao.userdao.IUserDAO; +import fr.ensma.lias.rql.dto.Project; + +/** + * @author Bilal REZKELLAH + */ +public class ProjectDAO implements IProjectDAO { + + @Inject + IConfiguration cfg; + + @Inject + IPostgresSession ips; + + @Inject + IUserDAO iuser; + + @Override + public List getAllProjectByUser(String UserID) throws SQLException { + Project project; + List projectList = new ArrayList(); + Connection conn = ips.getConnection(); + String query = "SELECT * FROM PROJECT WHERE userid = ? union select p.* from project p,collaborator c where c.userid = ? and c.projectid = p.projectid "; + PreparedStatement pstmt = conn.prepareStatement(query); + pstmt.setString(1, UserID); + pstmt.setString(2, UserID); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + project = new Project(); + project.setName(rs.getString("projectname")); + project.setCreationDate(rs.getString("creationdate")); + project.setId(rs.getString("projectid")); + project.setCollaborators(iuser.getCollaborators(rs.getString("projectid"), UserID)); + project.setUserid(rs.getString("userid")); + project.setDescription(rs.getString("description")); + projectList.add(project); + } + return projectList; + } + + @Override + public String createProject(Project project) throws SQLException { + String SQL = "INSERT INTO PROJECT (projectname,creationdate,userid,description) " + "VALUES(?,?,?,?)"; + long id = 0; + Connection conn = ips.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS); + pstmt.setString(1, project.getName()); + pstmt.setString(2, project.getCreationDate()); + pstmt.setString(3, project.getUserid()); + pstmt.setString(4, project.getDescription()); + int affectedRows = pstmt.executeUpdate(); + // check the affected rows + if (affectedRows > 0) { + // get the ID back + ResultSet rs = pstmt.getGeneratedKeys(); + if (rs.next()) { + id = rs.getLong(1); + } + } + return Long.toString(id); + } + + @Override + public Project getProjectById(String projectID) throws SQLException { + Project project; + Connection conn = ips.getConnection(); + String query = "SELECT * FROM PROJECT WHERE projectid = ? "; + PreparedStatement pstmt = conn.prepareStatement(query); + pstmt.setInt(1, Integer.valueOf(projectID)); + ResultSet rs = pstmt.executeQuery(); + rs.next(); + project = new Project(); + project.setName(rs.getString("projectname")); + project.setCreationDate(rs.getString("creationdate")); + project.setId(rs.getString("projectid")); + project.setUserid(rs.getString("userid")); + project.setDescription(rs.getString("description")); + + return project; + } + + @Override + public boolean deleteProjectbyId(String projectID) throws SQLException { + String SQL = "DELETE FROM PROJECT WHERE projectid = ? "; + String SQL2 = "DELETE FROM DATABASE WHERE projectid = ? "; + String SQL3 = "DELETE FROM collaborator WHERE projectid = ? "; + String SQL4 = "DELETE FROM favorite WHERE projectid = ? "; + + Connection conn = ips.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(SQL2); + pstmt.setInt(1, Integer.valueOf(projectID)); + pstmt.execute(); + pstmt = conn.prepareStatement(SQL3); + pstmt.setInt(1, Integer.valueOf(projectID)); + pstmt.execute(); + pstmt = conn.prepareStatement(SQL4); + pstmt.setInt(1, Integer.valueOf(projectID)); + pstmt.execute(); + pstmt = conn.prepareStatement(SQL); + pstmt.setInt(1, Integer.valueOf(projectID)); + return pstmt.execute(); + } + + @Override + public boolean updateProject(Project project) throws SQLException { + String SQL = "UPDATE PROJECT SET projectname = ?, description = ? WHERE projectid = ? "; + Connection conn = ips.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(SQL); + pstmt.setString(1, project.getName()); + pstmt.setInt(3, Integer.valueOf(project.getId())); + pstmt.setString(2, project.getDescription()); + return pstmt.execute(); + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/query/IQueryDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/query/IQueryDAO.java new file mode 100644 index 0000000..1cca2d3 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/query/IQueryDAO.java @@ -0,0 +1,23 @@ +package fr.ensma.lias.rql.dao.query; + +import fr.ensma.lias.rql.baseresults.BaseResult; +import fr.ensma.lias.rql.dto.TypeQuery; +import fr.ensma.lias.rql.model.DataBaseConfig; +import fr.ensma.lias.rql.rqlgrammar.RQLParser; + +/** + * @author Bilal REZKELLAH + */ +public interface IQueryDAO { + + TypeQuery createRQLQuery(String query, DataBaseConfig dbc) throws Exception; + + String getQueryByID(String id); + + BaseResult getBaseByID(String id); + + TypeQuery createSQLQuery(String query) throws Exception; + + RQLParser getParserByID(String id); + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/query/QueryDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/query/QueryDAO.java new file mode 100644 index 0000000..6b630cd --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/query/QueryDAO.java @@ -0,0 +1,84 @@ +package fr.ensma.lias.rql.dao.query; + +import java.sql.ResultSet; + +import javax.inject.Inject; + +import fr.ensma.lias.rql.baseresults.BaseResult; +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.cfg.SqlCoreConf; +import fr.ensma.lias.rql.dao.inmemory.InMemory; +import fr.ensma.lias.rql.dto.QueryEnumType; +import fr.ensma.lias.rql.dto.TypeQuery; +import fr.ensma.lias.rql.model.DataBaseConfig; +import fr.ensma.lias.rql.rqlgrammar.RQLParser; +import fr.ensma.lias.rql.sql.SQLManager; + +/** + * @author Bilal REZKELLAH + */ +public class QueryDAO implements IQueryDAO { + + @Inject + InMemory myInstance; + + @Inject + IConfiguration cfg; + + @Override + public TypeQuery createRQLQuery(String query, DataBaseConfig dbc) throws Exception { + RQLParser parse = RQLParser.parse(query); + SQLManager sql = new SQLManager(new SqlCoreConf(dbc.getDataBaseName(), dbc.getDataBaseHost(), + dbc.getDataBasePort(), dbc.getDataBaseType(), dbc.getDataBaseUser(), dbc.getDataBasePassword())); + System.out.println(parse.mysqlQuery()); + System.out.println(parse.oracleQuery()); + String myQuery = ""; + if (dbc.getDataBaseType().equals("oracle")) { + myQuery = parse.oracleQuery(); + } else if (dbc.getDataBaseType().equals("postgresql")) { + myQuery = parse.postgresQuery(); + } else if (dbc.getDataBaseType().equals("mysql")) { + myQuery = parse.oracleQuery(); + } else { + } + ResultSet result = sql.execute(myQuery); + BaseResult base = new BaseResult(); + base.resultsToList(result); + long start = System.currentTimeMillis(); + String queryKey = Long.toString(start); + System.out.println(queryKey); + myInstance.getRqlParserDB().put(queryKey, parse); + myInstance.getRqlQueryDB().put(queryKey, query); + myInstance.getRqlBaseDB().put(queryKey, base); + sql.closeDB(); + return new TypeQuery(QueryEnumType.RQL, myQuery, queryKey, base.getContent(), parse.getAttributeList()); + } + + @Override + public TypeQuery createSQLQuery(String query) throws Exception { + long start = System.currentTimeMillis(); + String queryKey = Long.toString(start); + System.out.println(queryKey); + System.out.println(myInstance.getSqlQueryDB().size()); + myInstance.getSqlQueryDB().put(queryKey, query); + return new TypeQuery(QueryEnumType.SQL, null, queryKey, null, null); + } + + @Override + public String getQueryByID(String id) { + String query = myInstance.getRqlQueryDB().get(id); + return query; + } + + @Override + public BaseResult getBaseByID(String id) { + BaseResult base = myInstance.getRqlBaseDB().get(id); + return base; + } + + @Override + public RQLParser getParserByID(String id) { + return myInstance.getRqlParserDB().get(id); + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/userdao/IUserDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/userdao/IUserDAO.java new file mode 100644 index 0000000..b0b858d --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/userdao/IUserDAO.java @@ -0,0 +1,25 @@ +package fr.ensma.lias.rql.dao.userdao; + +import java.sql.SQLException; +import java.util.List; + +import fr.ensma.lias.rql.dto.User; + +/** + * @author Bilal REZKELLAH + */ +public interface IUserDAO { + + boolean ifUserNameExist(String userName) throws SQLException; + + String getPasswordHash(String userName) throws SQLException; + + List getAllUsers(String userid) throws SQLException; + + String createCollaborator(String projectID, String userID) throws SQLException; + + boolean deleteCollabortor(String projectID, String userID) throws SQLException; + + List getCollaborators(String projectID, String userID) throws SQLException; + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/userdao/UserDAO.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/userdao/UserDAO.java new file mode 100644 index 0000000..85abe1f --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dao/userdao/UserDAO.java @@ -0,0 +1,113 @@ +package fr.ensma.lias.rql.dao.userdao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import fr.ensma.lias.rql.dao.postgressession.IPostgresSession; +import fr.ensma.lias.rql.dto.User; + +/** + * @author Bilal REZKELLAH + */ +public class UserDAO implements IUserDAO { + + @Inject + IPostgresSession ips; + + @Override + public boolean ifUserNameExist(String userName) throws SQLException { + Connection conn = ips.getConnection(); + String query = "SELECT * FROM users WHERE username = ? "; + PreparedStatement pstmt = conn.prepareStatement(query); + pstmt.setString(1, userName); + ResultSet rs = pstmt.executeQuery(); + return rs.isBeforeFirst(); + } + + @Override + public String getPasswordHash(String userName) throws SQLException { + Connection conn = ips.getConnection(); + String query = "SELECT hashpassword FROM users WHERE username = ? "; + PreparedStatement pstmt = conn.prepareStatement(query); + pstmt.setString(1, userName); + ResultSet rs = pstmt.executeQuery(); + rs.next(); + return rs.getString("hashpassword"); + } + + @Override + public List getAllUsers(String userid) throws SQLException { + Connection conn = ips.getConnection(); + List userList = new ArrayList(); + User user; + String query = "SELECT username,Lastname,Firstname FROM users WHERE username != ?"; + PreparedStatement pstmt = conn.prepareStatement(query); + pstmt.setString(1, userid); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + user = new User(); + user.setUsername(rs.getString("username")); + user.setLastName(rs.getString("lastname")); + user.setFirstName(rs.getString("firstname")); + userList.add(user); + } + return userList; + } + + @Override + public String createCollaborator(String projectID, String userID) throws SQLException { + String SQL = "INSERT INTO collaborator (projectid,userid) " + "VALUES(?,?)"; + long id = 0; + Connection conn = ips.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS); + pstmt.setInt(1, Integer.valueOf(projectID)); + pstmt.setString(2, userID); + int affectedRows = pstmt.executeUpdate(); + // check the affected rows + if (affectedRows > 0) { + // get the ID back + ResultSet rs = pstmt.getGeneratedKeys(); + if (rs.next()) { + id = rs.getLong(1); + } + } + return Long.toString(id); + } + + @Override + public boolean deleteCollabortor(String projectID, String userID) throws SQLException { + String SQL = "DELETE FROM collaborator WHERE projectid = ? and userid = ?"; + Connection conn = ips.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(SQL); + pstmt.setInt(1, Integer.valueOf(projectID)); + pstmt.setString(2, userID); + return pstmt.execute(); + } + + @Override + public List getCollaborators(String projectID, String userID) throws SQLException { + Connection conn = ips.getConnection(); + User user; + List userList = new ArrayList(); + String query = "select username,lastname,firstname from collaborator c, users u where c.userid = u.username and c.userid != ? and c.projectid = ?"; + PreparedStatement pstmt = conn.prepareStatement(query); + pstmt.setString(1, userID); + pstmt.setInt(2, Integer.valueOf(projectID)); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + user = new User(); + user.setUsername(rs.getString("username")); + user.setFirstName(rs.getString("firstname")); + user.setLastName(rs.getString("lastname")); + userList.add(user); + } + return userList; + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/MySqlNameNormalizer.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/MySqlNameNormalizer.java new file mode 100644 index 0000000..9094f18 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/MySqlNameNormalizer.java @@ -0,0 +1,21 @@ +package fr.ensma.lias.rql.dbimport; + +/** + * @author Bilal REZKELLAH + */ +public class MySqlNameNormalizer extends NameNormalizer { + + @Override + public String colNameNormalizer(String source) { + source = withoutSpecialChar(withoutAccents(source)).replace(" ", "_"); + while (source.endsWith("_")) { + source = source.substring(0, source.length() - 1); + } + while (source.startsWith("_")) { + source = source.substring(1, source.length()); + } + source = source.substring(0, Math.min(source.length(), 64)); + return source; + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/NameNormalizer.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/NameNormalizer.java new file mode 100644 index 0000000..53021bf --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/NameNormalizer.java @@ -0,0 +1,20 @@ +package fr.ensma.lias.rql.dbimport; + +import java.text.Normalizer; + +/** + * @author Bilal REZKELLAH + */ +public abstract class NameNormalizer { + + public String withoutAccents(String source) { + String normalized = Normalizer.normalize(source, Normalizer.Form.NFD); + return normalized.replaceAll("[\u0300-\u036F]", ""); + } + + public String withoutSpecialChar(String source) { + return source.replaceAll("[^a-zA-Z0-9\\s]", "_"); + } + + public abstract String colNameNormalizer(String source); +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/OracleNameNormalizer.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/OracleNameNormalizer.java new file mode 100644 index 0000000..55965db --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/OracleNameNormalizer.java @@ -0,0 +1,21 @@ +package fr.ensma.lias.rql.dbimport; + +/** + * @author Bilal REZKELLAH + */ +public class OracleNameNormalizer extends NameNormalizer { + + @Override + public String colNameNormalizer(String source) { + source = withoutSpecialChar(withoutAccents(source)).replace(" ", ""); + while (source.endsWith("_")) { + source = source.substring(0, source.length() - 1); + } + while (source.startsWith("_")) { + source = source.substring(1, source.length()); + } + source = source.substring(0, Math.min(source.length(), 30)); + return source; + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/PostgresNameNormalizer.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/PostgresNameNormalizer.java new file mode 100644 index 0000000..37f5295 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/dbimport/PostgresNameNormalizer.java @@ -0,0 +1,22 @@ +package fr.ensma.lias.rql.dbimport; + +/** + * @author Bilal REZKELLAH + */ +public class PostgresNameNormalizer extends NameNormalizer { + + @Override + public String colNameNormalizer(String source) { + + source = withoutSpecialChar(withoutAccents(source)).replace(" ", ""); + while (source.endsWith("_")) { + source = source.substring(0, source.length() - 1); + } + while (source.startsWith("_")) { + source = source.substring(1, source.length()); + } + source = source.substring(0, Math.min(source.length(), 60)); + return source; + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/model/DataBaseConfig.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/model/DataBaseConfig.java new file mode 100644 index 0000000..3ed79c9 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/model/DataBaseConfig.java @@ -0,0 +1,93 @@ +package fr.ensma.lias.rql.model; + +/** + * @author Bilal REZKELLAH + */ +public class DataBaseConfig { + + private String projectid; + + private String dataBaseName; + + private String dataBaseHost; + + private Integer dataBasePort; + + private String dataBaseUser; + + private String dataBasePassword; + + private String dataBaseType; + + public String getDataBaseName() { + return dataBaseName; + } + + public void setDataBaseName(String dataBaseName) { + this.dataBaseName = dataBaseName; + } + + public DataBaseConfig(String projectid, String dataBaseName, String dataBaseHost, Integer dataBasePort, + String dataBaseUser, String dataBasePassword, String dataBaseType) { + super(); + this.projectid = projectid; + this.dataBaseName = dataBaseName; + this.dataBaseHost = dataBaseHost; + this.dataBasePort = dataBasePort; + this.dataBaseUser = dataBaseUser; + this.dataBasePassword = dataBasePassword; + this.dataBaseType = dataBaseType; + } + + public DataBaseConfig() { + } + + public String getDataBaseHost() { + return dataBaseHost; + } + + public void setDataBaseHost(String dataBaseHost) { + this.dataBaseHost = dataBaseHost; + } + + public Integer getDataBasePort() { + return dataBasePort; + } + + public void setDataBasePort(Integer dataBasePort) { + this.dataBasePort = dataBasePort; + } + + public String getDataBaseUser() { + return dataBaseUser; + } + + public void setDataBaseUser(String dataBaseUser) { + this.dataBaseUser = dataBaseUser; + } + + public String getDataBasePassword() { + return dataBasePassword; + } + + public void setDataBasePassword(String dataBasePassword) { + this.dataBasePassword = dataBasePassword; + } + + public String getDataBaseType() { + return dataBaseType; + } + + public void setDataBaseType(String dataBaseType) { + this.dataBaseType = dataBaseType; + } + + public String getProjectid() { + return projectid; + } + + public void setProjectid(String projectid) { + this.projectid = projectid; + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/AuthenticationResourceImpl.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/AuthenticationResourceImpl.java new file mode 100644 index 0000000..d2a3942 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/AuthenticationResourceImpl.java @@ -0,0 +1,73 @@ +package fr.ensma.lias.rql.service; + +import java.sql.SQLException; +import java.util.Date; + +import javax.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import fr.ensma.lias.rql.AuthToken; +import fr.ensma.lias.rql.RqlUtil; +import fr.ensma.lias.rql.api.AuthenticationResource; +import fr.ensma.lias.rql.api.NotYetImplementedException; +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.cfg.RqlConfig; +import fr.ensma.lias.rql.dao.userdao.IUserDAO; +import fr.ensma.lias.rql.dto.Credentials; + +/** + * @author Bilal REZKELLAH + */ +public class AuthenticationResourceImpl implements AuthenticationResource { + + @Inject + IUserDAO iuser; + + @Inject + IConfiguration refConfiguration; + + @Override + public Response login(Credentials credentials) { + if (credentials == null || credentials.getUsername() == null || credentials.getUsername().isEmpty() + || credentials.getPassword() == null || credentials.getPassword().isEmpty()) { + throw new WebApplicationException("Parameter is missing.", Status.BAD_REQUEST); + } + final RqlConfig configuration = refConfiguration.getConfiguration(); + try { + if (!iuser.ifUserNameExist(credentials.getUsername())) { + throw new WebApplicationException("User is not unauthorized.", Status.UNAUTHORIZED); + } + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + throw new WebApplicationException("Server Error.", Status.BAD_REQUEST); + + } + + String hashPassword = null; + try { + hashPassword = iuser.getPasswordHash(credentials.getUsername()); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + throw new WebApplicationException("Server Error.", Status.BAD_REQUEST); + + } + if (RqlUtil.checkPassword(credentials.getPassword(), hashPassword)) { + AuthToken currentToken = new AuthToken(credentials.getUsername(), new Date()); + final String encryptToken = RqlUtil.encryptToken(currentToken, configuration.encryptPassword(), + configuration.encryptNoise()); + return Response.ok(encryptToken).build(); + } else { + throw new WebApplicationException("Password doesn't not match.", Status.UNAUTHORIZED); + } + } + + @Override + public Response logout() { + System.out.println("AuthenticationResourceImpl.logout()"); + throw new NotYetImplementedException(); + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/BearerTokenFilter.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/BearerTokenFilter.java new file mode 100644 index 0000000..a932c26 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/BearerTokenFilter.java @@ -0,0 +1,65 @@ +package fr.ensma.lias.rql.service; + +import java.io.IOException; +import java.util.Date; + +import javax.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response.Status; + +import fr.ensma.lias.rql.AuthToken; +import fr.ensma.lias.rql.RqlConstant; +import fr.ensma.lias.rql.RqlUtil; +import fr.ensma.lias.rql.api.TokenAuthenticated; +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.cfg.RqlConfig; + +/** + * @author Bilal REZKELLAH + */ +@TokenAuthenticated +public class BearerTokenFilter implements ContainerRequestFilter { + + @Inject + IConfiguration refConfiguration; + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + String token = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); + + final RqlConfig configuration = refConfiguration.getConfiguration(); + + final AuthToken decryptToken = RqlUtil.decryptToken(token, configuration.encryptPassword(), + configuration.encryptNoise()); + + if (decryptToken != null) { + final Date startDate = decryptToken.getStartDate(); + + if (startDate != null) { + final long diff = new Date().getTime() - startDate.getTime(); + if ((diff / 1000) < getSessionTimeOut(configuration.sessionTimeout())) { + if (!(decryptToken.getIdentifiant().equals(configuration.identificationUser()))) { + throw new WebApplicationException("Token is wrong.", Status.UNAUTHORIZED); + } + } else { + throw new WebApplicationException("Session timeout.", Status.UNAUTHORIZED); + } + } else { + throw new WebApplicationException("Token is wrong.", Status.UNAUTHORIZED); + } + } else { + throw new WebApplicationException("User is not unauthorized.", Status.UNAUTHORIZED); + } + } + + public static int getSessionTimeOut(String configurationValue) { + try { + return 60 * Integer.parseInt(configurationValue); + } catch (NumberFormatException e) { + return RqlConstant.SESSION_TIMEOUT_DEFAULT; + } + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/DataBaseImportImp.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/DataBaseImportImp.java new file mode 100644 index 0000000..4c6f60d --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/DataBaseImportImp.java @@ -0,0 +1,377 @@ +package fr.ensma.lias.rql.service; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; + +import org.apache.poi.EncryptedDocumentException; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.json.JSONObject; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import fr.ensma.lias.rql.api.DataBaseImport; +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.cfg.SqlCoreConf; +import fr.ensma.lias.rql.core.IRql; +import fr.ensma.lias.rql.dao.dbconfiguration.IConfigurationDAO; +import fr.ensma.lias.rql.dto.FilePreview; +import fr.ensma.lias.rql.dto.SheetContent; +import fr.ensma.lias.rql.dto.TableImportResult; +import fr.ensma.lias.rql.model.DataBaseConfig; +import fr.ensma.lias.rql.sql.SQLManager; + +/** + * @author Bilal REZKELLAH + */ +public class DataBaseImportImp implements DataBaseImport { + + @Inject + IConfiguration cfg; + + @Inject + IRql irql; + + @Inject + IConfigurationDAO iconfig; + + private XSSFWorkbook workbook; + + @Override + public FilePreview uploadFile(InputStream file, FormDataContentDisposition fileDetail) { + FilePreview filePreview = new FilePreview(); + long key = 0; + File resultDir = new File(cfg.getConfiguration().tmpResultsDir()); + resultDir.mkdir(); + if (fileDetail == null || file == null) { + throw new WebApplicationException("Parameter is missing.", Status.NOT_FOUND); + } else { + Workbook workbook = null; + try { + key = System.currentTimeMillis(); + workbook = WorkbookFactory.create(file); + SheetContent sheeti = null; + for (int i = 0; i < workbook.getNumberOfSheets(); i++) { + sheeti = new SheetContent(); + sheeti.setRows(getXlsxToJsonarray(workbook, i)); + Sheet sheet = workbook.getSheetAt(i); + sheeti.setNbRow(sheet.getLastRowNum()); + Row titleRow = sheet.getRow(0); + List header = new ArrayList(); + DataFormatter formatter = new DataFormatter(); + for (int j = 0; j < titleRow.getLastCellNum(); j++) { + String val = formatter.formatCellValue(titleRow.getCell(j)); + header.add(val); + } + Set set = new LinkedHashSet<>(); + for (String str : header) { + if (!str.equals("")) { + String value = str; + // Iterate as long as you can't add the value indicating that we have + // already the value in the set + for (int i1 = 1; !set.add(value); i1++) { + value = str + i1; + } + } + } + header = new ArrayList(); + header.addAll(set); + System.out.println(set); + sheeti.setHeader(header); + sheeti.setTableName(workbook.getSheetName(i)); + filePreview.getSheetList().add(sheeti); + } + filePreview.setGoNext(true); + filePreview.setFileID(Long.toString(key)); + + } catch (EncryptedDocumentException | InvalidFormatException | IOException | NullPointerException e1) { + e1.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e1.getMessage()).build(); + throw new WebApplicationException(response); + } + FileOutputStream fileOut = null; + try { + fileOut = new FileOutputStream(cfg.getConfiguration().tmpResultsDir() + "/" + key + "tmpUpload.xlsx"); + workbook.write(fileOut); + fileOut.close(); + } catch (IOException e) { + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + return filePreview; + } + + public List getXlsxToJsonarray(Workbook wb, int sheetIndex) throws IOException, InvalidFormatException { + + Sheet sheet = wb.getSheetAt(sheetIndex); + Row titleRow = sheet.getRow(0); + Row dataRow = null; + List listObject = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + JSONObject jtmp = null; + List header = new ArrayList(); + DataFormatter formatter = new DataFormatter(); + for (int j = 0; j < titleRow.getLastCellNum(); j++) { + String val = formatter.formatCellValue(titleRow.getCell(j)); + header.add(val); + } + Set set = new LinkedHashSet<>(); + for (String str : header) { + if (!str.equals("")) { + String value = str; + // Iterate as long as you can't add the value indicating that we have + // already the value in the set + for (int i1 = 1; !set.add(value); i1++) { + value = str + i1; + } + } + } + header = new ArrayList(); + header.addAll(set); + for (int i = 1; i <= Math.min(sheet.getLastRowNum(), 100); i++) { + jtmp = new JSONObject(); + dataRow = sheet.getRow(i); + for (int j = 0; j < header.size(); j++) { + + if (formatter.formatCellValue(dataRow.getCell(j)) == null) { + } else { + String val = header.get(j); + String val2 = formatter.formatCellValue(dataRow.getCell(j)); + jtmp.put(val, val2); + } + } + Object obj = mapper.readValue(jtmp.toString(), Object.class); + listObject.add(obj); + } + return listObject; + } + + public CellType getColType(XSSFSheet sheet, Integer index) { + Row rowi = sheet.getRow(1); + CellType cellType = null; + int rowIndex = 1; + cellType = rowi.getCell(index).getCellTypeEnum(); + if (cellType == CellType.BLANK) { + while (cellType == CellType.BLANK && rowIndex < sheet.getPhysicalNumberOfRows() - 1) { + rowi = sheet.getRow(++rowIndex); + cellType = rowi.getCell(index).getCellTypeEnum(); + } + if (rowIndex == sheet.getPhysicalNumberOfRows() - 1) { + cellType = CellType.STRING; + } + } + if (cellType == CellType.NUMERIC) { + rowIndex = 1; + while ((cellType == CellType.NUMERIC || cellType == CellType.BLANK) + && rowIndex < sheet.getPhysicalNumberOfRows() - 1) { + rowi = sheet.getRow(++rowIndex); + cellType = rowi.getCell(index).getCellTypeEnum(); + } + if (cellType != CellType.NUMERIC && cellType != CellType.BLANK) { + cellType = CellType.STRING; + } else { + + cellType = CellType.NUMERIC; + } + } + return cellType; + } + + public String cellTypeMap(CellType cellType, String dbType) { + if (cellType == CellType.STRING && dbType.equals("oracle")) { + return "VARCHAR2(200)"; + } else if (cellType == CellType.STRING && dbType.equals("postgresql")) { + return "TEXT"; + } else if (cellType == CellType.NUMERIC && dbType.equals("oracle")) { + return "NUMBER(20)"; + } else if (cellType == CellType.NUMERIC && dbType.equals("postgresql")) { + return "BIGINT"; + } else if (cellType == CellType.BOOLEAN) { + return "BOOLEAN"; + } else { + return null; + } + } + + @Override + public TableImportResult tableImport(String id, Integer sheetIndex, String tableName, String projectID, + String columnList) { + if (columnList.equals("[]") || columnList == null) { + Response response = Response.status(Status.BAD_REQUEST).entity("Please select one attribut at less") + .build(); + throw new WebApplicationException(response); + } + TableImportResult tir = null; + DataBaseConfig dbc = null; + try { + System.out.println(projectID); + dbc = iconfig.getConfigByID(projectID); + } catch (SQLException | IOException e3) { + // TODO Auto-generated catch block + e3.printStackTrace(); + } + SQLManager sql = new SQLManager(new SqlCoreConf(dbc.getDataBaseName(), dbc.getDataBaseHost(), + dbc.getDataBasePort(), dbc.getDataBaseType(), dbc.getDataBaseUser(), dbc.getDataBasePassword())); + PrintWriter writer = null; + try { + writer = new PrintWriter(cfg.getConfiguration().tmpResultsDir() + "/" + id + "_Script.txt", "UTF-8"); + } catch (FileNotFoundException | UnsupportedEncodingException e2) { + // TODO Auto-generated catch block + e2.printStackTrace(); + } + try { + sql.openDB(); + } catch (SQLException e1) { + e1.printStackTrace(); + } + String createTable = null; + columnList = columnList.replace("[", "").replace("]", ""); + List columnRang = Arrays.asList(columnList.split(",")); + List intList = new ArrayList(); + List colTypeList = new ArrayList(); + if (columnRang.size() != 0) { + for (String s : columnRang) + if (!s.equals("")) + intList.add(Integer.valueOf(s)); + } + FileInputStream file; + try { + file = new FileInputStream(new File(cfg.getConfiguration().tmpResultsDir() + "/" + id + "tmpUpload.xlsx")); + workbook = new XSSFWorkbook(file); + XSSFSheet sheet = workbook.getSheetAt(sheetIndex); + tir = new TableImportResult(irql.normalizeName(tableName, dbc.getDataBaseType()), sheet.getLastRowNum(), + intList.size(), true); + for (int i = 0; i < intList.size(); i++) { + colTypeList.add(getColType(sheet, intList.get(i))); + } + Row titleRow = sheet.getRow(0); + createTable = "CREATE TABLE " + irql.normalizeName(tableName, dbc.getDataBaseType()) + " ("; + List header = new ArrayList(); + DataFormatter formatter = new DataFormatter(); + for (int j = 0; j < titleRow.getLastCellNum(); j++) { + String val = formatter.formatCellValue(titleRow.getCell(j)); + header.add(val); + } + Set set = new LinkedHashSet<>(); + for (String str : header) { + if (!str.equals("")) { + String value = str; + for (int i1 = 1; !set.add(value); i1++) { + value = str + i1; + } + } + } + header = new ArrayList(); + header.addAll(set); + for (int i = 0; i < intList.size(); i++) { + if (i == 0) { + createTable += irql.normalizeName(header.get(intList.get(i)), dbc.getDataBaseType()) + " " + + cellTypeMap(getColType(sheet, intList.get(i)), dbc.getDataBaseType()); + } else { + createTable += ", " + irql.normalizeName(header.get(intList.get(i)), dbc.getDataBaseType()) + " " + + cellTypeMap(colTypeList.get(i), dbc.getDataBaseType()); + + } + } + createTable += ")"; + writer.println(createTable); + irql.executeSqlQuery(createTable, dbc); + String insertRow = ""; + insertRow = "INSERT INTO " + irql.normalizeName(tableName, dbc.getDataBaseType()) + " ("; + for (int i = 0; i < intList.size(); i++) { + if (i == 0) { + insertRow += irql.normalizeName(header.get(intList.get(i)), dbc.getDataBaseType()); + } else { + insertRow += ", " + irql.normalizeName(header.get(intList.get(i)), dbc.getDataBaseType()); + } + } + insertRow += ") "; + String values = ""; + Iterator iteratorRow = sheet.iterator(); + if (iteratorRow.hasNext()) + iteratorRow.next(); + while (iteratorRow.hasNext()) { + values = insertRow + "VALUES("; + Row row = iteratorRow.next(); + for (int i = 0; i < intList.size(); i++) { + if (colTypeList.get(i) == CellType.STRING) { + String val = formatter.formatCellValue(row.getCell(intList.get(i))); + if (i == 0) { + values += "'" + val.replace("'", "") + "'"; + } else { + values += ", " + "'" + val.replace("'", "") + "'"; + } + } else if (colTypeList.get(i) == CellType.NUMERIC) { + Integer val = -1; + val = (int) row.getCell(intList.get(i)).getNumericCellValue(); + if (i == 0) { + values += val; + } else { + values += ", " + val; + } + } else if (colTypeList.get(i) == CellType.BOOLEAN) { + + } else { + boolean val = (boolean) row.getCell(intList.get(i)).getBooleanCellValue(); + if (i == 0) { + values += val; + } else { + values += ", " + val; + } + } + } + values += ")"; + writer.println(values); + sql.insertRow(values); + } + sql.closeDB(); + writer.close(); + + } catch (Exception e) { + System.out.println(e.getMessage()); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + + return tir; + } + + @Override + public Response scriptDownload(String id) { + ResponseBuilder rb = null; + File file = new File(cfg.getConfiguration().tmpResultsDir() + "/" + id + "_Script.txt"); + rb = Response.ok((Object) file); + rb.header("Content-Disposition", "attachment; filename=" + "/" + id + "_Script.txt"); + return rb.build(); + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/ProjectResourceImp.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/ProjectResourceImp.java new file mode 100644 index 0000000..8420b09 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/ProjectResourceImp.java @@ -0,0 +1,193 @@ +package fr.ensma.lias.rql.service; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +import javax.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import fr.ensma.lias.rql.api.ProjectResource; +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.core.IRql; +import fr.ensma.lias.rql.dao.dbconfiguration.IConfigurationDAO; +import fr.ensma.lias.rql.dao.dbschema.favorite.IFavoriteDAO; +import fr.ensma.lias.rql.dao.postgressession.IPostgresSession; +import fr.ensma.lias.rql.dao.project.IProjectDAO; +import fr.ensma.lias.rql.dao.userdao.IUserDAO; +import fr.ensma.lias.rql.dto.Favorite; +import fr.ensma.lias.rql.dto.Project; +import fr.ensma.lias.rql.dto.User; +import fr.ensma.lias.rql.model.DataBaseConfig; + +/** + * @author Bilal REZKELLAH + */ +public class ProjectResourceImp implements ProjectResource { + + @Inject + IProjectDAO iproject; + + @Inject + IUserDAO iuser; + + @Inject + IFavoriteDAO ifavorite; + + @Inject + IPostgresSession ips; + + @Inject + IConfigurationDAO icd; + + @Inject + IConfiguration cfg; + + @Inject + IRql irql; + + @Override + public List getAllProjectByUserID(String userID) { + + try { + return iproject.getAllProjectByUser(userID); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public String createNewProject(Project project) { + String date = new SimpleDateFormat("dd-MM-yyyy HH:mm").format(new Date()); + project.setCreationDate(date); + String projectID = ""; + try { + if (project.getDbType().toLowerCase().equals("postgresql")) { + projectID = iproject.createProject(project); + String dbName = project.getName() + projectID; + DataBaseConfig dbc = new DataBaseConfig(projectID, + irql.normalizeName(dbName, project.getDbType().toLowerCase()).toLowerCase(), + cfg.getConfiguration().rqlDbHostMetier(), 5432, "postgres", "postgres", + project.getDbType().toLowerCase()); + icd.createConfig(dbc); + for (User user : project.getCollaborators()) { + iuser.createCollaborator(projectID, user.getUsername()); + } + String SQL = "CREATE DATABASE " + irql.normalizeName(dbName, project.getDbType().toLowerCase()); + Connection conn = DriverManager.getConnection( + "jdbc:postgresql://" + cfg.getConfiguration().rqlDbHostMetier() + ":" + + cfg.getConfiguration().rqlDbPort() + "/" + "postgres", + cfg.getConfiguration().rqlDbAdminLogin(), cfg.getConfiguration().rqlDbAdminPwd()); + PreparedStatement pstmt = conn.prepareStatement(SQL); + pstmt.execute(); + } + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return projectID; + } + + @Override + public Project getProjectById(String id) { + try { + return iproject.getProjectById(id); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public boolean deleteProjectById(String id) { + try { + return iproject.deleteProjectbyId(id); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public boolean updateProject(Project project) { + // TODO Auto-generated method stub + try { + return iproject.updateProject(project); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public List getAllFavoriteByProject(String id) { + // TODO Auto-generated method stub + try { + return ifavorite.getAllFavoriteByProject(id); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public boolean deleteFavoriteById(String id) { + try { + return ifavorite.deleteFavorite(id); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public String createNewFavorite(Favorite favorite) { + try { + String date = new SimpleDateFormat("dd-MM-yyyy HH:mm").format(new Date()); + favorite.setCreationDate(date); + if (irql.isRqlQuery(favorite.getQuery())) { + favorite.setType("RQL"); + } else { + favorite.setType("SQL"); + } + return ifavorite.createFavorite(favorite); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public List getAllFavoriteSqlQueries(String id) { + try { + return ifavorite.getAllFavoriteSQLQueries(id); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/QueryConstructionImp.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/QueryConstructionImp.java new file mode 100644 index 0000000..514357b --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/QueryConstructionImp.java @@ -0,0 +1,32 @@ +package fr.ensma.lias.rql.service; + +import javax.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response.Status; + +import fr.ensma.lias.rql.api.QueryConstruction; +import fr.ensma.lias.rql.core.IRql; + +/** + * @author Bilal REZKELLAH + */ +public class QueryConstructionImp implements QueryConstruction { + + @Inject + IRql irql; + + @Override + public String getQuery(String QueryType, String isTable, String isALLData, String sqlQuery, String tableName, + String subsetWhere, String attributesList, String isConditional, String conditionalWhere, + String tolerence) { + if (QueryType == null || QueryType.isEmpty()) { + throw new WebApplicationException("Parameter is missing.", Status.NOT_FOUND); + } + String rqlQuery = ""; + rqlQuery = irql.constructQuery(QueryType, isTable, isALLData, sqlQuery, tableName, subsetWhere, attributesList, + isConditional.equals("true"), conditionalWhere, tolerence); + + return rqlQuery; + } + +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/QueryResourceImp.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/QueryResourceImp.java new file mode 100644 index 0000000..f8b58df --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/QueryResourceImp.java @@ -0,0 +1,131 @@ +package fr.ensma.lias.rql.service; + +import java.io.IOException; +import java.sql.SQLException; + +import javax.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import fr.ensma.lias.rql.api.QueryResource; +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.core.IRql; +import fr.ensma.lias.rql.dao.dbconfiguration.IConfigurationDAO; +import fr.ensma.lias.rql.dao.inmemory.InMemory; +import fr.ensma.lias.rql.dao.query.IQueryDAO; +import fr.ensma.lias.rql.dto.CheckRuleResult; +import fr.ensma.lias.rql.dto.RQLResult; +import fr.ensma.lias.rql.dto.SQLResult; +import fr.ensma.lias.rql.dto.TypeQuery; +import fr.ensma.lias.rql.rqlgrammar.ParseException; + +/** + * @author Rezkellah Bilal + */ +public class QueryResourceImp implements QueryResource { + + @Inject + InMemory myInstance; + + @Inject + IConfiguration cfg; + + @Inject + IQueryDAO iquery; + + @Inject + IConfigurationDAO iconfig; + + @Inject + IRql irql; + + @Override + public SQLResult getResultSet(String ID, String ProjectID) throws JsonParseException, JsonMappingException, IOException { + if (ID == null || ID.isEmpty()) { + throw new WebApplicationException("Parameter is missing.", Status.NOT_FOUND); + } + System.out.println(ProjectID); + String query = myInstance.getSqlQueryDB().get(ID); + if (ID == null || ID.isEmpty()) { + throw new WebApplicationException("Parameter is missing.", Status.NOT_FOUND); + } + try { + SQLResult executeSqlQuery = irql.executeSqlQuery(query,iconfig.getConfigByID(ProjectID) ); + return executeSqlQuery; + } catch (SQLException e) { + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public TypeQuery createQuery(String query, String projectid) { + if (irql.isRqlQuery(query)) { + try { + return iquery.createRQLQuery(query, iconfig.getConfigByID(projectid)); + } catch (Exception e) { + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } else { + try { + return iquery.createSQLQuery(query); + } catch (Exception e) { + e.printStackTrace(); + throw new WebApplicationException("Query is bad.", Status.BAD_REQUEST); + } + } + } + + @Override + public RQLResult getAllRulesID(String id, String support, String confidence) { + try { + return irql.executeRqlQuery(id, Double.parseDouble(support), Double.parseDouble(confidence)); + } catch (Exception e) { + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public CheckRuleResult checkForThisRule(String id, String leftAttributes, String rightAttribute, String support, + String confidence, String projectID) { + long debut = System.currentTimeMillis(); + + try { + return irql.checkRule(debut, iconfig.getConfigByID(projectID), id, leftAttributes, rightAttribute, Double.parseDouble(support), + Double.parseDouble(confidence)); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + throw new WebApplicationException("Query is bad.", Status.BAD_REQUEST); + } catch (NumberFormatException e) { + e.printStackTrace(); + throw new WebApplicationException("Query is bad.", Status.BAD_REQUEST); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + throw new WebApplicationException("Connection faild", Status.BAD_REQUEST); + } catch (IOException e) { + e.printStackTrace(); + throw new WebApplicationException("Connection faild", Status.BAD_REQUEST); + + } + } + + @Override + public String isGoodConstructed(String query) { + try { + irql.testQuery(query); + } catch (Exception e) { + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + return "true"; + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/SchemaResourceImp.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/SchemaResourceImp.java new file mode 100644 index 0000000..d336c8b --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/SchemaResourceImp.java @@ -0,0 +1,85 @@ +package fr.ensma.lias.rql.service; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +import javax.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response.Status; + +import fr.ensma.lias.rql.api.SchemaResource; +import fr.ensma.lias.rql.core.IRql; +import fr.ensma.lias.rql.dao.dbconfiguration.IConfigurationDAO; +import fr.ensma.lias.rql.dao.project.IProjectDAO; +import fr.ensma.lias.rql.dto.SchemaResult; +import fr.ensma.lias.rql.model.DataBaseConfig; + +/** + * @author Bilal REZKELLAH + */ +public class SchemaResourceImp implements SchemaResource { + + @Inject + IRql irql; + + @Inject + IConfigurationDAO iconfig; + + @Inject + IProjectDAO iproject; + + @Override + public SchemaResult getAllTables(String projectID) { + DataBaseConfig dbc = null; + try { + dbc = iconfig.getConfigByID(projectID); + } catch (SQLException | IOException e1) { + e1.printStackTrace(); + throw new WebApplicationException("Connexion faild.", Status.BAD_REQUEST); + + } + try { + return irql.getDataBaseSchema(dbc); + } catch (SQLException | IOException e) { + e.printStackTrace(); + throw new WebApplicationException("Schema Base Error.", Status.BAD_REQUEST); + } + } + + @Override + public List getAllTablesHeader(String projectID) { + DataBaseConfig dbc = null; + try { + dbc = iconfig.getConfigByID(projectID); + } catch (SQLException | IOException e1) { + e1.printStackTrace(); + throw new WebApplicationException("Connexion faild.", Status.BAD_REQUEST); + + } + try { + return irql.getDataBaseTablesHeader(dbc); + } catch (SQLException | IOException e) { + e.printStackTrace(); + throw new WebApplicationException("Schema Base Error.", Status.BAD_REQUEST); + } + } + + @Override + public List getAttributesList(String id, String queryType, String projectID) { + DataBaseConfig dbc = null; + try { + dbc = iconfig.getConfigByID(projectID); + } catch (SQLException | IOException e1) { + e1.printStackTrace(); + throw new WebApplicationException("Connexion faild.", Status.BAD_REQUEST); + + } + try { + return irql.getTableAttributesList(id, queryType, dbc); + } catch (SQLException | IOException e) { + e.printStackTrace(); + throw new WebApplicationException("Schema Base Error.", Status.BAD_REQUEST); + } + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/UserResourceImp.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/UserResourceImp.java new file mode 100644 index 0000000..632b7b8 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/UserResourceImp.java @@ -0,0 +1,65 @@ +package fr.ensma.lias.rql.service; + +import java.sql.SQLException; +import java.util.List; + +import javax.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import fr.ensma.lias.rql.api.UserResource; +import fr.ensma.lias.rql.dao.userdao.IUserDAO; +import fr.ensma.lias.rql.dto.User; + + +/** + * @author Bilal REZKELLAH + */ +public class UserResourceImp implements UserResource { + + @Inject + IUserDAO iuser; + + @Override + public List getAllCollaborarors(String userid) { + try { + return iuser.getAllUsers(userid); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public boolean deleteCollaborator(String projectid, String username) { + try { + return iuser.deleteCollabortor(projectid, username); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public String addCollaborator(String projectid, String username) { + try { + return iuser.createCollaborator(projectid, username); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + } + + @Override + public String getCollaborators(String projectid, String username) { + // TODO Auto-generated method stub + return null; + } +} diff --git a/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/XlsxResourceImp.java b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/XlsxResourceImp.java new file mode 100644 index 0000000..89f4e73 --- /dev/null +++ b/rql-backend/rql-server/src/main/java/fr/ensma/lias/rql/service/XlsxResourceImp.java @@ -0,0 +1,418 @@ +package fr.ensma.lias.rql.service; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.sql.SQLException; + +import javax.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import fr.ensma.lias.rql.api.XlsxResource; +import fr.ensma.lias.rql.cfg.IConfiguration; +import fr.ensma.lias.rql.core.IRql; +import fr.ensma.lias.rql.dao.dbconfiguration.IConfigurationDAO; +import fr.ensma.lias.rql.dao.inmemory.InMemory; +import fr.ensma.lias.rql.dto.CheckRuleResult; +import fr.ensma.lias.rql.dto.RQLResult; +import fr.ensma.lias.rql.dto.RQLRow; +import fr.ensma.lias.rql.rqlgrammar.ParseException; +import fr.ensma.lias.rql.sql.SQLResultsRow; +import fr.ensma.lias.rql.sql.SQLRow; + +/** + * @author Bilal REZKELLAH + */ +public class XlsxResourceImp implements XlsxResource { + @Inject + IRql irql; + + @Inject + InMemory myInstance; + + @Inject + IConfiguration cfg; + + @Inject + IConfigurationDAO iconfig; + + RQLResult rqlResult; + + private Workbook workbook; + + @Override + public Response getRule(String id, String support, String confidence) { + ResponseBuilder rb = null; + try { + rqlResult = irql.executeRqlQuery(id, Double.parseDouble(support), Double.parseDouble(confidence)); + } catch (Exception e) { + System.out.println(e.getMessage()); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + workbook = new XSSFWorkbook(); + String query = myInstance.getRqlQueryDB().get(id); + // Create a Sheets + Sheet sheet = workbook.createSheet("Rules"); + // Create a Font for styling header cells + Font headerFont = workbook.createFont(); + headerFont.setBold(true); + headerFont.setFontHeightInPoints((short) 12); + headerFont.setColor(IndexedColors.RED.getIndex()); + + // Create a CellStyle with the font + CellStyle headerCellStyle = workbook.createCellStyle(); + headerCellStyle.setFont(headerFont); + + // Create a header row for exactRules + Row headerRow1 = sheet.createRow(0); + Row headerRow = sheet.createRow(1); + // Creating cells + Cell cell = headerRow.createCell(0); + cell.setCellValue("LeftAttributes"); + cell.setCellStyle(headerCellStyle); + + Cell cell2 = headerRow.createCell(1); + cell2.setCellValue("RightAttribut"); + cell2.setCellStyle(headerCellStyle); + + Cell cellquery = headerRow1.createCell(0); + cellquery.setCellValue("RQL Query"); + cellquery.setCellStyle(headerCellStyle); + + Cell cell2query = headerRow1.createCell(2); + cell2query.setCellValue(query); + // Create Other rows and cells with exactRules Data + int rowNum = 2; + for (RQLRow rqlrow : rqlResult.getexactRule()) { + Row row = sheet.createRow(rowNum++); + + row.createCell(0).setCellValue(String.join(" ", rqlrow.getLeftAttributes())); + + row.createCell(1).setCellValue(rqlrow.getRightAttribute()); + } + + // Resize all columns to fit the content size + for (int i = 0; i < 2; i++) { + sheet.autoSizeColumn(i); + } + + // Write the output to a file + FileOutputStream fileOut = null; + try { + fileOut = new FileOutputStream(cfg.getConfiguration().tmpResultsDir() + "/" + id + "poi.xlsx"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + try { + workbook.write(fileOut); + } catch (IOException e) { + e.printStackTrace(); + } + try { + fileOut.close(); + } catch (IOException e) { + e.printStackTrace(); + } + File file = new File(cfg.getConfiguration().tmpResultsDir() + "/" + id + "poi.xlsx"); + rb = Response.ok((Object) file); + rb.header("Content-Disposition", "attachment; filename=" + "/" + id + "_Rules.xlsx"); + return rb.build(); + } + + @Override + public Response getCounterExample(String id, String leftAttributes, String rightAttribute, String support, + String confidence, String projectID) { + ResponseBuilder rb = null; + File resultDir = new File(cfg.getConfiguration().tmpResultsDir()); + resultDir.mkdir(); + long debut = System.currentTimeMillis(); + String query = myInstance.getRqlQueryDB().get(id); + CheckRuleResult crr = null; + try { + crr = irql.checkRule(debut, iconfig.getConfigByID(projectID), id, leftAttributes, rightAttribute, + Double.parseDouble(support), Double.parseDouble(confidence)); + } catch (ParseException | NumberFormatException | SQLException | IOException e) { + e.printStackTrace(); + throw new WebApplicationException("Query is bad.", Status.BAD_REQUEST); + } + + workbook = new XSSFWorkbook(); + // Create a Sheets + Sheet sheet = workbook.createSheet("CounterExamples1"); + Sheet sheet2 = workbook.createSheet("CounterExamples2"); + Sheet sheet3 = workbook.createSheet("CounterExamples3"); + // Create a Font for styling header cells + Font headerFont = workbook.createFont(); + headerFont.setBold(true); + headerFont.setFontHeightInPoints((short) 12); + headerFont.setColor(IndexedColors.RED.getIndex()); + // Create a header row for counter examples + Row headerRow = sheet.createRow(1); + Row headerRow1 = sheet.createRow(0); + + // Create a CellStyle with the font + CellStyle headerCellStyle = workbook.createCellStyle(); + headerCellStyle.setFont(headerFont); + // Creating cells + Cell cell = headerRow.createCell(0); + cell.setCellValue("LeftAttributes"); + cell.setCellStyle(headerCellStyle); + + Cell cell2 = headerRow.createCell(1); + cell2.setCellValue("RightAttribut"); + cell2.setCellStyle(headerCellStyle); + + Cell cellquery = headerRow1.createCell(0); + cellquery.setCellValue("RQL Query"); + cellquery.setCellStyle(headerCellStyle); + + Cell cellquery2 = headerRow1.createCell(2); + cellquery2.setCellValue(query); + // save the rule + Row row = sheet.createRow(2); + row.createCell(0).setCellValue(leftAttributes); + row.createCell(1).setCellValue(rightAttribute); + // Create Other rows and cells with counterExamples Data + Row headerRow2 = sheet.createRow(3); + headerCellStyle.setFont(headerFont); + // Creating cells + Cell cell1 = headerRow2.createCell(0); + cell1.setCellValue("Counter Example N°"); + cell1.setCellStyle(headerCellStyle); + for (int i = 0; i < crr.getCheckResult().getCounterExamples3().getHeader().size(); i++) { + cell1 = headerRow2.createCell(i + 1); + cell1.setCellValue(crr.getCheckResult().getCounterExamples3().getHeader().get(i)); + cell1.setCellStyle(headerCellStyle); + } + + int rowNum = 4; + for (SQLRow sqlrow : crr.getCheckResult().getCounterExamples3().getRows()) { + Row row1 = sheet.createRow(rowNum++); + + row1.createCell(0).setCellValue(Math.floor((rowNum - 5) / crr.getSummary().getTupleNB() + 1)); + + int cellNum = 1; + for (String cel : sqlrow.getCels()) { + row1.createCell(cellNum++).setCellValue(cel); + } + } + + // Resize all columns to fit the content size + for (int i = 0; i < crr.getCheckResult().getCounterExamples3().getHeader().size(); i++) { + sheet.autoSizeColumn(i); + } + + // Create a header row for counter examples + Row headerRow21 = sheet2.createRow(0); + // Creating cells + Cell cell21 = headerRow21.createCell(0); + cell21.setCellValue("LeftAttributes"); + cell21.setCellStyle(headerCellStyle); + + Cell cell22 = headerRow21.createCell(1); + cell22.setCellValue("RightAttribut"); + cell22.setCellStyle(headerCellStyle); + // save the rule + Row row21 = sheet2.createRow(1); + row21.createCell(0).setCellValue(leftAttributes); + row21.createCell(1).setCellValue(rightAttribute); + // Create Other rows and cells with counterExamples Data + Row headerRow22 = sheet2.createRow(2); + headerCellStyle.setFont(headerFont); + // Creating cells + Cell cell23 = headerRow22.createCell(0); + cell23.setCellValue("Counter Example N°"); + cell23.setCellStyle(headerCellStyle); + for (int i = 0; i < crr.getCheckResult().getCounterExamples().getHeader().size(); i++) { + cell23 = headerRow22.createCell(i + 1); + cell23.setCellValue(crr.getCheckResult().getCounterExamples().getHeader().get(i)); + cell23.setCellStyle(headerCellStyle); + } + + int rowNum2 = 3; + for (SQLRow sqlrow : crr.getCheckResult().getCounterExamples().getRows()) { + Row row1 = sheet2.createRow(rowNum2++); + + row1.createCell(0).setCellValue(Math.floor((rowNum2 - 4) / crr.getSummary().getTupleNB() + 1)); + + int cellNum = 1; + for (String cel : sqlrow.getCels()) { + row1.createCell(cellNum++).setCellValue(cel); + } + } + + // Resize all columns to fit the content size + for (int i = 0; i < crr.getCheckResult().getCounterExamples().getHeader().size(); i++) { + sheet2.autoSizeColumn(i); + } + + // Create a header row for counter examples + Row headerRow31 = sheet3.createRow(0); + // Creating cells + Cell cell31 = headerRow31.createCell(0); + cell31.setCellValue("LeftAttributes"); + cell31.setCellStyle(headerCellStyle); + + Cell cell32 = headerRow31.createCell(1); + cell32.setCellValue("RightAttribut"); + cell32.setCellStyle(headerCellStyle); + // save the rule + Row row31 = sheet3.createRow(1); + row31.createCell(0).setCellValue(leftAttributes); + row31.createCell(1).setCellValue(rightAttribute); + // Create Other rows and cells with counterExamples Data + Row headerRow32 = sheet3.createRow(2); + headerCellStyle.setFont(headerFont); + // Creating cells + Cell cell33 = headerRow32.createCell(0); + cell33.setCellValue("Counter Example N°"); + cell33.setCellStyle(headerCellStyle); + for (int i = 0; i < crr.getCheckResult().getCounterExamples2().getHeader().size(); i++) { + cell33 = headerRow32.createCell(i + 1); + cell33.setCellValue(crr.getCheckResult().getCounterExamples2().getHeader().get(i)); + cell33.setCellStyle(headerCellStyle); + } + + int rowNum3 = 3; + for (SQLRow sqlrow : crr.getCheckResult().getCounterExamples2().getRows()) { + Row row1 = sheet3.createRow(rowNum3++); + + row1.createCell(0).setCellValue(Math.floor((rowNum3 - 4) / crr.getSummary().getTupleNB() + 1)); + + int cellNum = 1; + for (String cel : sqlrow.getCels()) { + row1.createCell(cellNum++).setCellValue(cel); + } + } + + // Resize all columns to fit the content size + for (int i = 0; i < crr.getCheckResult().getCounterExamples2().getHeader().size(); i++) { + sheet3.autoSizeColumn(i); + } + + FileOutputStream fileOut = null; + try { + fileOut = new FileOutputStream(cfg.getConfiguration().tmpResultsDir() + "/" + id + "CounterExample.xlsx"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + try { + workbook.write(fileOut); + } catch (IOException e) { + e.printStackTrace(); + } + try { + fileOut.close(); + } catch (IOException e) { + e.printStackTrace(); + } + File file = new File(cfg.getConfiguration().tmpResultsDir() + "/" + id + "CounterExample.xlsx"); + rb = Response.ok((Object) file); + rb.header("Content-Disposition", "attachment; filename=" + "/" + id + "_CounterExample.xlsx"); + return rb.build(); + } + + @Override + public Response getResultSet(String ID, String projectID) { + SQLResultsRow executeSqlQuery = null; + ResponseBuilder rb = null; + File resultDir = new File(cfg.getConfiguration().tmpResultsDir()); + resultDir.mkdir(); + workbook = new XSSFWorkbook(); + String query; + if (ID == null || ID.isEmpty()) { + throw new WebApplicationException("Parameter is missing.", Status.NOT_FOUND); + } + query = myInstance.getSqlQueryDB().get(ID); + if (ID == null || ID.isEmpty()) { + throw new WebApplicationException("Parameter is missing.", Status.NOT_FOUND); + } + try { + executeSqlQuery = irql.executeSqlQuery2(query, iconfig.getConfigByID(projectID)); + } catch (SQLException | IOException e) { + e.printStackTrace(); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + throw new WebApplicationException(response); + } + + // Create a Sheets + Sheet sheet = workbook.createSheet("ResultSet"); + // Create a Font for styling header cells + Font headerFont = workbook.createFont(); + headerFont.setBold(true); + headerFont.setFontHeightInPoints((short) 12); + headerFont.setColor(IndexedColors.RED.getIndex()); + // Create a CellStyle with the font + CellStyle headerCellStyle = workbook.createCellStyle(); + headerCellStyle.setFont(headerFont); + // Create a header row for query + Row headerRow = sheet.createRow(0); + + // Creating cells + Cell cell = headerRow.createCell(0); + cell.setCellValue("SQL query"); + cell.setCellStyle(headerCellStyle); + + Cell cell2 = headerRow.createCell(1); + cell2.setCellValue(query); + + // Create a header row for query + Row headerRow2 = sheet.createRow(1); + int cellNum = 0; + for (String cel : executeSqlQuery.getHeader()) { + Cell cell1 = headerRow2.createCell(cellNum++); + cell1.setCellValue(cel); + cell1.setCellStyle(headerCellStyle); + } + + // Create Other rows and cells with exactRules Data + int rowNum = 2; + for (SQLRow sqlrow : executeSqlQuery.getRows()) { + Row row = sheet.createRow(rowNum++); + int cellNum1 = 0; + for (String cel : sqlrow.getCels()) { + row.createCell(cellNum1++).setCellValue(cel); + } + } + // Resize all columns to fit the content size + for (int i = 0; i < executeSqlQuery.getHeader().size(); i++) { + if (i != 1) + sheet.autoSizeColumn(i); + } + // Write the output to a file + FileOutputStream fileOut = null; + try { + fileOut = new FileOutputStream(cfg.getConfiguration().tmpResultsDir() + "/" + ID + "SQL.xlsx"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + try { + workbook.write(fileOut); + } catch (IOException e) { + e.printStackTrace(); + } + try { + fileOut.close(); + } catch (IOException e) { + e.printStackTrace(); + } + File file = new File(cfg.getConfiguration().tmpResultsDir() + "/" + ID + "SQL.xlsx"); + rb = Response.ok((Object) file); + rb.header("Content-Disposition", "attachment; filename=" + "/" + ID + "_ResultSet.xlsx"); + return rb.build(); + } +} diff --git a/rql-backend/rql-server/src/main/resources/META-INF/beans.xml b/rql-backend/rql-server/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000..5e71dd7 --- /dev/null +++ b/rql-backend/rql-server/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/rql-backend/rql-server/src/test/java/DELETE.me b/rql-backend/rql-server/src/test/java/DELETE.me new file mode 100644 index 0000000..e69de29 diff --git a/rql-backend/rql-server/src/test/resources/DELETE.me b/rql-backend/rql-server/src/test/resources/DELETE.me new file mode 100644 index 0000000..e69de29 diff --git a/rql-backend/shd31/01conv.pl b/rql-backend/shd31/01conv.pl new file mode 100644 index 0000000..e6e26da --- /dev/null +++ b/rql-backend/shd31/01conv.pl @@ -0,0 +1,33 @@ +#!/usr/bin/perl + +# this script covert a 01 matrix to a to the transaction database, or +# adjacency matrix, +# each line is converted to the sequence of columns which has value 1. + +$ARGC = @ARGV; +if ( $ARGC < 0 ){ + printf ("01conv.pl: [separator] < input-file > output-file\n"); + exit (1); +} +$count = 0; +%numbers = (); + +$sep = " "; +if ( $ARGC >= 1 ){ $sep = $ARGV[0]; } + +while (){ + chomp; + @eles = split($sep, $_); + $all = @eles; + $c = 1; + foreach $item( @eles ) { + if ( $item ne "0" ){ + print "$c" ; + if ($c<$all){ print $sep; } + } + $c++; + } + print "\n"; +} + + diff --git a/rql-backend/shd31/aheap.c b/rql-backend/shd31/aheap.c new file mode 100644 index 0000000..0d5377f --- /dev/null +++ b/rql-backend/shd31/aheap.c @@ -0,0 +1,216 @@ +/* + array-based simple heap (fixex size) + 12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +#ifndef _aheap_c_ +#define _aheap_c_ + +#include"aheap.h" + +QSORT_TYPE (AHEAP_KEY, AHEAP_KEY) +QSORT_TYPE (AHEAP_ID, AHEAP_ID) +AHEAP INIT_AHEAP = {TYPE_AHEAP,NULL,0,0}; + +/* allocate memory */ +void AHEAP_alloc (AHEAP *H, AHEAP_ID num){ + AHEAP_ID i; +#ifdef ERROR_CHECK + if ( num<0 ) error_num ("size is out of range", num, EXIT); +#endif + *H = INIT_AHEAP; + if ( num>0 ) malloc2 (H->v, num*2, EXIT); + H->end = num; + ARY_FILL (H->v, 0, num*2, AHEAP_KEYHUGE); + for (i=0 ; ibase = i - num + 1; +} + +/* termination */ +void AHEAP_end (AHEAP *H){ + free2 (H->v); + *H = INIT_AHEAP; +} + +/* return the index of the leaf having the minimum key among the descendants + of the given node i. If several leaves with the smallest key are there, + return the minimum index among them if f=0, maximum index if f=1, and + random choice if f=2 */ +/* random choice version. choose one child to go down randomly for each node, + thus it is not uniformly random */ +/* node_ returns the ID of leaf */ +AHEAP_ID AHEAP_findmin_node_ (AHEAP *H, AHEAP_ID i, int f){ + while ( i < H->end-1 ){ + if ( H->v[i*2+1] == H->v[i] ) + if ( H->v[i*2+2] == H->v[i] ) + if ( f == 2 ) i = i*2 + 1 + rand()%2; + else i = i*2+1+f; + else i = i*2+1; + else i = i*2+2; + } + return (i); +} +AHEAP_ID AHEAP_findmin_node (AHEAP *H, AHEAP_ID i, int f){ + if ( H->end <= 0 ) return (-1); + return (AHEAP_IDX(*H, AHEAP_findmin_node_ (H, i, f))); +} +AHEAP_ID AHEAP_findmin_head (AHEAP *H){ return (AHEAP_findmin_node (H, 0, 0) ); } +AHEAP_ID AHEAP_findmin_tail (AHEAP *H){ return (AHEAP_findmin_node (H, 0, 1) ); } +AHEAP_ID AHEAP_findmin_rnd (AHEAP *H){ return (AHEAP_findmin_node (H, 0, 2) ); } + +/* return the index of the leaf having smaller value than a among the + descendants of the given node i. If several leaves with the smallest key + are there, return the minimum index among them if f=0, maximum index if f=1, + and random choice if f=2 */ +AHEAP_ID AHEAP_findlow_node (AHEAP *H, AHEAP_KEY a, AHEAP_ID i, int f){ + if ( H->end == 0 ) return (-1); + if ( H->v[0] > a ) return (-1); + while ( i < H->end-1 ){ + if ( f == 2 ) { + if ( H->v[i*2+1] <= a ) + if ( H->v[i*2+2] <= a ) i = i*2 + 1 + rand()%2; + else i = i*2+1; + else i = i*2+2; + } else if ( H->v[i*2+1] <= a ) i = i*2+1+f; else i = i*2+2-f; + } + return (AHEAP_IDX(*H, i) ); +} +AHEAP_ID AHEAP_findlow_head (AHEAP *H, AHEAP_KEY a){ return (AHEAP_findlow_node (H, a, 0, 0) ); } +AHEAP_ID AHEAP_findlow_tail (AHEAP *H, AHEAP_KEY a){ return (AHEAP_findlow_node (H, a, 0, 1) ); } +AHEAP_ID AHEAP_findlow_rnd (AHEAP *H, AHEAP_KEY a){ return (AHEAP_findlow_node (H, a, 0, 2) ); } + +/* return the index of the leaf having smaller value than a next/previous to + leaf i. return -1 if such a leaf does not exist */ +AHEAP_ID AHEAP_findlow_nxt (AHEAP *H, AHEAP_ID i, AHEAP_KEY a){ + if ( H->end == 0 ) return (-1); + if ( i<0 || i>= H->end ) return ( AHEAP_findlow_head (H, a)); + for (i=AHEAP_LEAF(*H,i); i>0 ; i=(i-1)/2){ + /* i is the child of smaller index, and the key of the sibling of i is less than a */ + if ( i%2 == 1 && H->v[i+1] <= a ) return (AHEAP_findlow_node (H, a, i+1, 0) ); + } + return (-1); +} +AHEAP_ID AHEAP_findlow_prv (AHEAP *H, AHEAP_ID i, AHEAP_KEY a){ + if ( H->end == 0 ) return (-1); + if ( i<0 || i>= H->end ) return ( AHEAP_findlow_head (H, a)); + for (i=AHEAP_LEAF(*H,i); i>0 ; i=(i-1)/2){ + /* i is the child of larger index, and the key of the sibling of i is less than a */ + if ( i%2 == 0 && H->v[i-1] <= a ) return (AHEAP_findlow_node (H, a, i-1, 1) ); + } + return (-1); +} + +/* change the key of node i to a /Add a to the key of node i, and update heap H */ +void AHEAP_chg (AHEAP *H, AHEAP_ID i, AHEAP_KEY a){ + i = AHEAP_LEAF (*H, i); + H->v[i] = a; + AHEAP_update (H, i); +} +void AHEAP_add (AHEAP *H, AHEAP_ID i, AHEAP_KEY a){ + i = AHEAP_LEAF (*H, i); + H->v[i] += a; + AHEAP_update (H, i); +} + +/* update the ancestor of node i */ +void AHEAP_update (AHEAP *H, AHEAP_ID i){ + AHEAP_ID j; + AHEAP_KEY a = H->v[i]; + while ( i>0 ){ + j = i - 1 + (i%2)*2; /* j = the sibling of i */ + i = (i-1) / 2; + if ( H->v[j] < a ) a = H->v[j]; + if ( a == H->v[i] ) break; + H->v[i] = a; + } +} + +/* find the leaf with the minimum key value among the leaves having index + smaller/larger than i, or between i and j */ +AHEAP_ID AHEAP_upper_min (AHEAP *H, AHEAP_ID i){ + AHEAP_ID fi=0, j = AHEAP_LEAF (*H, H->end - 1); + AHEAP_KEY fm = AHEAP_KEYHUGE; + if ( i == 0 ) return (AHEAP_findmin_head (H) ); + i = AHEAP_LEAF (*H, i-1); + while ( i != j ){ + if ( i%2 ){ /* if i is the child with smaller index */ + if ( fm > H->v[i+1] ){ + fm = H->v[i+1]; + fi = i+1; + } + } + i = (i-1)/2; + if ( j == i ) break; /* stop if the right pointer and the left pointer are the same */ + j = (j-1)/2; + } + while ( fi < H->end-1 ) fi = fi*2 + (H->v[fi*2+1]<=fm?1:2); + return ( AHEAP_IDX(*H, fi) ); +} +AHEAP_ID AHEAP_lower_min (AHEAP *H, AHEAP_ID i){ + AHEAP_ID fi=0, j = AHEAP_LEAF (*H, 0); + AHEAP_KEY fm = AHEAP_KEYHUGE; + if ( i == H->end-1 ) return (AHEAP_findmin_head (H) ); + i = AHEAP_LEAF (*H, i+1); + while ( i != j ){ + if ( i%2 == 0 ){ /* if i is the child of larger index */ + if ( fm > H->v[i-1] ){ + fm = H->v[i-1]; + fi = i-1; + } + } + j = (j-1)/2; + if ( j == i ) break; /* stop if the right pointer and the left pointer are the same */ + i = (i-1)/2; + } + while ( fi < H->end-1 ) fi = fi*2 + (H->v[fi*2+1]<=fm?1:2); + return (AHEAP_IDX(*H, fi) ); +} + +/* find the index having the minimum among given two indices */ +AHEAP_ID AHEAP_interval_min (AHEAP *H, AHEAP_ID i, AHEAP_ID j){ + AHEAP_ID fi=0; + AHEAP_KEY fm = AHEAP_KEYHUGE; + if ( i == 0 ) return (AHEAP_lower_min (H, j) ); + if ( j == H->end-1 ) return (AHEAP_upper_min (H, i) ); + i = AHEAP_LEAF (*H, i-1); + j = AHEAP_LEAF (*H, j+1); + while ( i != j && i != j-1 ){ + if ( i%2 ){ /* if i is the child of smaller index */ + if ( fm > H->v[i+1] ){ + fm = H->v[i+1]; + fi = i+1; + } + } + i = (i-1)/2; + if ( j == i || j == i+1 ) break; /* stop if the right pointer and the left pointer are the same */ + if ( j%2 == 0 ){ /* if j is the child of larger index */ + if ( fm > H->v[j-1] ){ + fm = H->v[j-1]; + fi = j-1; + } + } + j = (j-1)/2; + } + while ( fi < H->end-1 ) + fi = fi*2 + (H->v[fi*2+1] <= fm?1:2); + return (AHEAP_IDX(*H, fi) ); +} + +/* print heap keys according to the structure of the heap */ +void AHEAP_print (AHEAP *H){ + AHEAP_ID i, j=1; + while ( j<=H->end*2-1 ){ + FLOOP (i, j-1, MIN(j, H->end)*2-1) printf (AHEAP_KEYF ",", H->v[i] ); + printf ("\n"); + j = j*2; + } +} + +#endif diff --git a/rql-backend/shd31/aheap.h b/rql-backend/shd31/aheap.h new file mode 100644 index 0000000..2d680e5 --- /dev/null +++ b/rql-backend/shd31/aheap.h @@ -0,0 +1,111 @@ +/* + array-based simple heap (fixed size) + 12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +/* bench mark + PentiumIII 500MHz, Memory 256MB Linux + values 0-1,000,000 : set & del & get 1,000,000 times + 2.55sec + + # rotation == 1/5 per 1 set/del + + *** simple array *** + value 0-1,000,000 set & set & set 1,000,000 times, + 0.88sec + */ + +#ifndef _aheap_h_ +#define _aheap_h_ + +#include"stdlib2.h" + +#ifndef AHEAP_KEY + #ifdef AHEAP_KEY_DOUBLE + #define AHEAP_KEY double + #define AHEAP_KEYHUGE DOUBLEHUGE + #define AHEAP_KEYF "%f" + #elif defined(AHEAP_KEY_WEIGHT) + #define AHEAP_KEY WEIGHT + #define AHEAP_KEYHUGE WEIGHTHUGE + #define AHEAP_KEYF WEIGHTF + #else +#define AHEAP_KEY int + #define AHEAP_KEYHUGE INTHUGE + #define AHEAP_KEYF "%d" + #endif +#endif + +#ifndef AHEAP_ID + #define AHEAP_ID int + #define AHEAP_ID_END INTHUGE + #define AHEAP_IDF "%d" +#endif + +#define AHEAP_IDX(H,i) (((i)+1-(H).base)%(H).end) +#define AHEAP_LEAF(H,i) (((i)+(H).base)%(H).end+(H).end-1) +#define AHEAP_H(H,i) (H).v[(((i)+(H).base)%(H).end+(H).end-1)] + +typedef struct { + unsigned char type; + AHEAP_KEY *v; /* array for heap key */ + int end; /* the number of maximum elements */ + int base; /* the constant for set 0 to the leftmost leaf */ +} AHEAP; + +QSORT_TYPE_HEADER (AHEAP_KEY, AHEAP_KEY) +QSORT_TYPE_HEADER (AHEAP_ID, AHEAP_ID) +extern AHEAP INIT_AHEAP; + +/* initialization. allocate memory for H and fill it by +infinity */ +void AHEAP_alloc (AHEAP *H, int num); +void AHEAP_end (AHEAP *H); + +/* return the index of the leaf having the minimum key among the descendants + of the given node i. If several leaves with the smallest key are there, + return the minimum index among them if f=0, maximum index if f=1, and + random choice if f=2 */ +AHEAP_ID AHEAP_findmin_node_ (AHEAP *H, AHEAP_ID i, int f); +AHEAP_ID AHEAP_findmin_node (AHEAP *H, AHEAP_ID i, int f); +AHEAP_ID AHEAP_findmin_head (AHEAP *H); +AHEAP_ID AHEAP_findmin_tail (AHEAP *H); +AHEAP_ID AHEAP_findmin_rnd (AHEAP *H); + +/* return the index of the leaf having smaller value than a among the + descendants of the given node i. If several leaves with the smallest key + are there, return the minimum index among them if f=0, maximum index if f=1, + and random choice if f=2 */ +AHEAP_ID AHEAP_findlow_node (AHEAP *H, AHEAP_KEY a, AHEAP_ID i, int f); +AHEAP_ID AHEAP_findlow_head (AHEAP *H, AHEAP_KEY a); +AHEAP_ID AHEAP_findlow_tail (AHEAP *H, AHEAP_KEY a); +AHEAP_ID AHEAP_findlow_rnd (AHEAP *H, AHEAP_KEY a); + +/* return the index of the leaf having smaller value than a next/previous to + leaf i. return -1 if such a leaf does not exist */ +AHEAP_ID AHEAP_findlow_nxt (AHEAP *H, AHEAP_ID i, AHEAP_KEY a); +AHEAP_ID AHEAP_findlow_prv (AHEAP *H, AHEAP_ID i, AHEAP_KEY a); + +/* change the key of node i to a /Add a to the key of node i, and update heap H */ +void AHEAP_chg (AHEAP *H, AHEAP_ID i, AHEAP_KEY a); +void AHEAP_add (AHEAP *H, AHEAP_ID i, AHEAP_KEY a); + +/* update the ancestor of node i */ +void AHEAP_update (AHEAP *H, AHEAP_ID i); + +/* find the leaf with the minimum key value among the leaves having index + smaller/larger than i, or between i and j */ +AHEAP_ID AHEAP_upper_min (AHEAP *H, AHEAP_ID i); +AHEAP_ID AHEAP_lower_min (AHEAP *H, AHEAP_ID i); +AHEAP_ID AHEAP_interval_min (AHEAP *H, AHEAP_ID i, AHEAP_ID j); + +/* print heap keys according to the structure of the heap */ +void AHEAP_print (AHEAP *H); + +#endif diff --git a/rql-backend/shd31/alist.c b/rql-backend/shd31/alist.c new file mode 100644 index 0000000..a6394e0 --- /dev/null +++ b/rql-backend/shd31/alist.c @@ -0,0 +1,637 @@ +/* + array-based list/multi-list library + 12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, pleas + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about codes for the users. */ + +#ifndef _alist_c_ +#define _alist_c_ + +#include"alist.h" +#include"stdlib2.c" +#include"undo.c" + +/* if error check is unnecessary, comment out the next line */ +//#define ERROR_CHECK + +ALIST INIT_ALIST = {TYPE_ALIST,NULL,NULL,0,0}; +MALIST INIT_MALIST = {TYPE_MALIST,NULL,NULL,0,NULL,NULL,0}; +QSORT_TYPE(ALIST_ID, ALIST_ID) +/************* initialization/termination ************/ + +/* initialization */ +void ALIST_alloc (ALIST *A, ALIST_ID siz){ + ALIST_ID i; + *A = INIT_ALIST; + malloc2 (A->prv, siz+1, EXIT); // allocate memory + malloc2 (A->nxt, siz+1, {free2(A->prv);EXIT;}); // allocate memory + A->end = siz; + A->prv[siz] = siz; // make empty list by connecting root to itself in bidirection + A->nxt[siz] = siz; + for ( i=0 ; iprv[i] = -1; // set prv[i]=-1 for each element since they are not inserted in the list +} + +/* termination */ +void ALIST_end (ALIST *A){ + mfree (A->prv, A->nxt); + *A = INIT_ALIST; +} + +/* copy list A2 to A1. If the size of A1 is less than current size of A2, error */ +void ALIST_cpy (ALIST *A1, ALIST *A2){ + ALIST_ID i; + ALIST_rmall (A1); + ALIST_DO_FORWARD (*A2, i){ +#ifdef ERROR_CHECK + if ( !ALIST_IS_ELM(*A1,i) ) + error ("ALIST_cpy: the size of A1 is smaller than current size of A2", EXIT); +#endif + ALIST_ins_tail (A1, i, 0); + } +} + +/* duplication */ +ALIST ALIST_dup (ALIST *A){ + ALIST AA; + ALIST_alloc (&AA, A->end); /* initialize the new list */ + ALIST_cpy (&AA, A); /* copy A to AA */ + return (AA); +} + + +/************* addition/deletion ************/ + +/* insert an element e next/previous to element i or haed/tail of the list + error is checked for already inserted elements or out of range */ +void ALIST_ins_nxt (ALIST *A, ALIST_ID e, ALIST_ID ee, int undo){ +#ifdef ERROR_CHECK + if ( e < 0 || e >= A->end ) error_num ("ALIST_ins: e is out of range", e, EXIT); + if ( ee < 0 || ee > A->end ) error_num ("ALIST_ins: ee is out of range", ee, EXIT); + if ( A->prv[e] >= 0 ) error_num ("ALIST_ins: element is already in the list", e, EXIT); +#endif + + A->num++; /* increment the length of the list */ + A->nxt[e] = A->nxt[ee]; /* change the four links */ + A->prv[A->nxt[ee]] = e; + A->nxt[ee] = e; + A->prv[e] = ee; + if ( undo ) ALISTundo_ins (U_ALIST_rm, (void *)A, e, e); +} + +void ALIST_ins_prv (ALIST *A, ALIST_ID e, ALIST_ID ee, int undo){ +#ifdef ERROR_CHECK + if ( ee < 0 || ee > A->end ) error_num ("ALIST_ins_prv: ee is out of range", ee, EXIT); +#endif + ALIST_ins_nxt (A, e, A->prv[ee], undo); +} +void ALIST_ins_head (ALIST *A, ALIST_ID e, int undo){ ALIST_ins_prv (A, e, ALIST_HEAD(*A), undo);} +void ALIST_ins_tail (ALIST *A, ALIST_ID e, int undo){ ALIST_ins_nxt (A, e, ALIST_TAIL(*A), undo);} + +/* remove head/tail of the list. do nothing if e is root + with check removal of removed element/range check */ +void ALIST_rm (ALIST *A, ALIST_ID e, int undo){ +#ifdef ERROR_CHECK + if ( e < 0 || e >= A->end ) error_num ("ALIST_rm: e is out of range", e, EXIT); + if ( A->prv[e] < 0 ) error_num ("ALIST_rm: element is not in the list", e, EXIT ); +#endif + if ( e == A->end ) return; + if ( undo ) ALISTundo_ins (U_ALIST_ins, (void *)A, e, A->prv[e]); + A->num--; /* decrement the length of the list */ + A->nxt[A->prv[e]] = A->nxt[e]; /* short cut the previous & next elements to e */ + A->prv[A->nxt[e]] = A->prv[e]; + A->prv[e] = -1; /* set prv[i]=-1 so that i is out */ +} + + +/* remove head/tail of the list, and return it. return root if empty list + with check removal of removed element/range check */ +ALIST_ID ALIST_rm_head (ALIST *A, int undo){ + ALIST_ID e = ALIST_HEAD(*A); /* set e to the head of list */ + if ( ALIST_IS_ELM(*A,e) ) ALIST_rm (A, e, undo); /* if e is element, remove e */ + return (e); +} + +ALIST_ID ALIST_rm_tail (ALIST *A, int undo){ + ALIST_ID e = ALIST_TAIL(*A); /* set e to the tail */ + if ( ALIST_IS_ELM(*A,e) ) ALIST_rm (A, e, undo); /* if e is element, remove e */ + return (e); +} + +/* re-insert removed element by ALIST_rm to its original position. precisely, + insert removed element e previous to the next element when e is in the list + with check insertion of non-removed element/range check */ +void ALIST_recov (ALIST *A, ALIST_ID e, int undo){ + ALIST_ID i; +#ifdef ERROR_CHECK + if ( e < 0 || e >= A->end ) error_num ("ALIST_recov: e is out of range", e, EXIT); + if ( A->prv[e] >= 0 ) error_num ("ALIST_rm: recover element %d in the list\n", e, EXIT); +#endif + i = A->prv[A->nxt[e]]; /* i = element previous to the next to e */ + A->num++; /* increment the length of the list */ + A->nxt[i] = e; /* insert e by changing the links */ + A->prv[A->nxt[e]] = e; + A->prv[e] = i; /* re-set prv[e], since it was -1 */ + if ( undo ) ALISTundo_ins (U_ALIST_rm, (void *)A, e, -1); +} + +/* remove all elements in a list */ +void ALIST_rmall (ALIST *A){ + ALIST_ID i; + ALIST_DO_FORWARD (*A, i) A->prv[i] = -1; /* set prv[i]=-1 for all elements */ + A->num = 0; /* set length of the list to 0 */ + A->nxt[A->end] = A->end; /* make empty list */ + A->prv[A->end] = A->end; +} + +/************* print routines ************/ + +/* print all elements in a list + flag&1: not print newline after the print, flag&2: not print size, + flag&4: print all elements not in the list */ +void ALIST_print (ALIST *A, int flag){ + ALIST_ID i; + if ( flag&2 ) printf (ALIST_IDF": ", flag&4?A->end-A->num:A->num ); + if ( flag&4 ){ + FLOOP (i, 0, A->end) if ( A->prv[i] == -1 ) printf (ALIST_IDF",", i); + } else ALIST_DO_FORWARD (*A, i) printf (ALIST_IDF",", i); + if ( (flag&1) == 0 ) printf ("\n"); +} + +/************* search ************/ + +/* return the kth element next/previous to i */ +/* note that return i when k=1, and return root if root is reached */ +ALIST_ID ALIST_knxt (ALIST *A, ALIST_ID i, ALIST_ID k){ + for ( ; k>=1&& ALIST_IS_ELM(*A,i) ; k--) i = A->nxt[i]; /* go next k-1 times from i */ + return (i); +} +ALIST_ID ALIST_kprv (ALIST *A, ALIST_ID i, ALIST_ID k){ + for ( ; k>=1 && ALIST_IS_ELM(*A,i) ; k--) i = A->prv[i]; /* go previous k-1 times from i */ + return (i); +} + +/* return kth element from the head/tail. return the head/tail if k<1. + return root if k>current size */ +ALIST_ID ALIST_find_kth (ALIST *A, ALIST_ID k){ return (ALIST_knxt (A, ALIST_HEAD (*A), k-1) );} +ALIST_ID ALIST_find_tkth (ALIST *A, ALIST_ID k){ return (ALIST_kprv (A, ALIST_TAIL (*A), k-1) );} + +/* return element randomly chosen from all element in A */ +ALIST_ID ALIST_find_rnd (ALIST *A){ + ALIST_ID k = rand()%A->num +1; /* generate random number ranging the size of list */ + if ( k < A->num/2 ) return (ALIST_find_kth (A, k) ); + else return (ALIST_find_tkth (A, A->num-k+1) ); +} + +/* return the most tailmost element which does not exceed i. + return root if there is no such element */ +ALIST_ID ALIST_find_i (ALIST *A, ALIST_ID i){ + ALIST_ID e; + ALIST_DO_FORWARD (*A, e) if ( e>i ) break; + return ( A->prv[e] ); +} + +/* return the element most close to i and not exceed i */ +/* return -1 if no element does not exceed i */ +ALIST_ID ALIST_find_max_le_i (ALIST *A, ALIST_ID i){ + ALIST_ID e, m=-1; + ALIST_DO_FORWARD (*A, e) if ( e<=i ) ENMAX (m, e); + return (m); +} + +/* sort elements in the list by merge sort without recursion */ +/* increasing order if f==0 */ +void ALIST_sort ( ALIST *A, int f, int undo ){ + ALIST_ID k, i, ii, j1, j2; + for (k=1 ; knum; k=k*2){ /* twice the size of partial sequence to be sorted */ + i = ALIST_HEAD (*A); + while (1){ + j1 = ALIST_knxt (A, i, k-1); /* to merge from ith to (i+k-1)th and (i+k)th to (i+k+k)th, set pointers to the position */ + if ( !ALIST_IS_ELM (*A, j1) ) break; + j2 = ALIST_knxt(A, j1, k+1); + while (1){ + ii = A->nxt[j1]; + if ( i > ii ){ + ALIST_rm (A, ii, undo); + ALIST_ins_prv (A, ii, i, undo); /* insert ii previous to i if i>ii */ + if ( A->nxt[j1] == j2 ) break; + } else { + i = A->nxt[i]; /* finish if i reach to the last */ + if ( i == ii ) break; + } + } + i = j2; + } + } +} + +/************* rich operations ************/ + +/* remove elements in B from A */ +void ALIST_minus (ALIST *A, ALIST *B, int undo){ + ALIST_ID i; + ALIST_DO_FORWARD (*B, i) + if ( A->prv[i] >= 0 ) ALIST_rm (A, i, undo); +} + +/* remove elements not in B from A (intersection of A and B) */ +void ALIST_and (ALIST *A, ALIST *B, int undo){ + ALIST_ID i; + ALIST_DO_FORWARD (*A, i) + if ( B->prv[i] == -1 ) ALIST_rm (A, i, undo); +} + +/* concatinate A2 following to A1, A2 remains in ALIST_concat, not remain in ALIST_append */ +void ALIST_concat (ALIST *A1, ALIST *A2, int undo){ + ALIST_ID e; + ALIST_DO_FORWARD (*A2, e) ALIST_ins_tail (A1, e, undo); +} + +void ALIST_append (ALIST *A1, ALIST *A2, int undo){ + ALIST_ID e; + while (1){ + e = ALIST_rm_head (A2, undo); + if ( !ALIST_IS_ELM(*A2, e) ) return; + ALIST_ins_tail (A1, e, undo); + } +} + + +/***********************************************************************/ +/* Multi list structure */ +/***********************************************************************/ + + +/************* initialization/termination ************/ + +/* initialization. parameters are + pointer to the structure, #elements, #lists. No range check */ +void MALIST_alloc (MALIST *A, ALIST_ID siz, ALIST_ID list_siz){ + ALIST_ID i; + *A = INIT_MALIST; + malloc2 (A->prv, siz+list_siz, EXIT); + malloc2 (A->nxt, siz+list_siz, {MALIST_end(A);EXIT;}); + malloc2 (A->num, list_siz, {MALIST_end(A);EXIT;}); + malloc2 (A->list, siz, {MALIST_end(A);EXIT;}); + A->end = siz; + A->list_end = list_siz; + ARY_FILL (A->prv, 0, siz, -1); /* each element belongs no list */ + FLOOP (i, 0, list_siz){ + A->num[i] = 0; /* set the length of each list to 0 */ + A->prv[siz+i] = siz+i; /* set each list to the empty list */ + A->nxt[siz+i] = siz+i; + } +} + +/* termination */ +void MALIST_end (MALIST *A){ + mfree (A->prv, A->nxt, A->num, A->list); + *A = INIT_MALIST; +} + +/* copy AA to A1. error if max #elements in A1 is length of A2 */ +void MALIST_cpy (MALIST *A1, MALIST *A2){ + ALIST_ID l, e; + FLOOP (l, 0, A1->list_end) MALIST_rmall (A1, l); /* remove all elements in A1 */ + FLOOP (l, 0, A2->list_end){ /* For each list in A2 */ + if ( A2->num[l] >0 ){ /* if lth list is non-empty, do ... */ +#ifdef ERROR_CHECK + if ( A1->list_end <= l ) error ("MALIST_cpy: #lists in A1 < #lists in A2.", EXIT); +#endif + MALIST_DO_FORWARD (*A2, l, e){ /* cpoy lth element of list A2 */ + if ( MALIST_IS_ELM(*A1,e) ) MALIST_ins_tail (A1, l, e, 0); + error ("MALIST_cpy: #elements in A1 < #current elements in A2.", EXIT); + } + } + } +} + +/* duplication */ +MALIST MALIST_dup (MALIST *A){ + MALIST AA; + MALIST_alloc (&AA, A->end, A->list_end); /* initialize AA as same as A */ + MALIST_cpy (&AA, A); /* copy AA to A */ + return (AA); +} + + +/************* addition/deletion ************/ + +/* insert an element e previous/next to element ee or haed/tail of the list l + error is checked for already inserted elements or out of range */ +void MALIST_ins_nxt (MALIST *A, ALIST_ID e, ALIST_ID ee, int undo){ + ALIST_ID f, l; +#ifdef ERROR_CHECK + if ( e < 0 || e >= A->end ) error_num ("MALIST_ins: e is out of range", e, EXIT); + if ( ee < 0 || ee >= A->end+A->list_end ) error_num ("MALIST_ins: ee is out of range", ee, EXIT); + if ( A->prv[e] >= 0 ) error_num ("MALIST_ins: element is already in some list", e, EXIT); +#endif + f = A->nxt[ee]; + if ( MALIST_IS_ELM(*A,ee) ) l=A->list[ee]; else l=ee-A->end; + A->num[l]++; /* increment the length of the list ee belongs */ + A->list[e] = l; /* set list[e] to the list ee belongs */ + A->nxt[e] = f; /* change the links to insert e */ + A->prv[f] = e; + A->nxt[ee] = e; + A->prv[e] = ee; + if ( undo ) ALISTundo_ins (U_MALIST_rm, (void *)A, e, -1); +} + +void MALIST_ins_prv (MALIST *A, ALIST_ID e, ALIST_ID ee, int undo){ +#ifdef ERROR_CHECK + if ( ee < 0 || ee >= A->end+A->list_end ) error_num ("MALIST_ins_prv: ee is out of range", ee, EXIT); +#endif + MALIST_ins_nxt (A, e, A->prv[ee], undo); +} + +/* insert an element e to the head/tail of the list l + error is checked for already inserted elements or out of range */ +void MALIST_ins_head ( MALIST *A, ALIST_ID l, ALIST_ID e, int undo ){ +#ifdef ERROR_CHECK + if ( l < 0 || l >= A->list_end ) error_num ("MALIST_ins_prv: l is out of range.%d\n", l, EXIT); +#endif + MALIST_ins_prv (A, e, MALIST_HEAD (*A, l), undo); +} + +void MALIST_ins_tail (MALIST *A, ALIST_ID l, ALIST_ID e, int undo){ +#ifdef ERROR_CHECK + if ( l < 0 || l >= A->list_end ) error_num ("MALIST_ins_prv: l is out of range", l, EXIT); +#endif + MALIST_ins_nxt (A, e, MALIST_TAIL (*A, l), undo); +} + +/* remove the head of l-th list, and return it. return the root if it is empty. no range check */ +ALIST_ID MALIST_rm_head (MALIST *A, ALIST_ID l, int undo){ + ALIST_ID e = MALIST_HEAD (*A,l); + if ( MALIST_IS_ELM(*A,e) ){ MALIST_rm (A, e, undo); return (e); } else return (-1); +} + +/* remove head/tail of the list, and return it. return root if empty list + with check removal of removed element/range check */ +ALIST_ID MALIST_rm_tail (MALIST *A, ALIST_ID l, int undo){ + ALIST_ID e = MALIST_TAIL(*A,l); + if ( MALIST_IS_ELM(*A,e) ){ MALIST_rm (A, e, undo); return (e); } else return (-1); +} + +/* remove an element e from A. + with check removal of removed element/range check */ +void MALIST_rm ( MALIST *A, ALIST_ID e, int undo ){ +#ifdef ERROR_CHECK + if ( e < 0 || e >= A->end ) error_num ("MALIST_rm: e is out of range", e, EXIT); + if ( A->prv[e] < 0 ) error_num ("MALIST_rm: element is not in any list", e, EXIT); +#endif + if ( undo ) ALISTundo_ins (U_MALIST_ins, (void *)A, e, A->prv[e]); + A->num[A->list[e]]--; + A->nxt[A->prv[e]] = A->nxt[e]; + A->prv[A->nxt[e]] = A->prv[e]; + A->prv[e] = -1; +} + +/* re-insert removed element by MALIST_rm to its original position. precisely, + insert removed element e previous to the next element when e is in the list + with check insertion of non-removed element/range check */ +void MALIST_recov (MALIST *A, ALIST_ID e, int undo){ + ALIST_ID i, l; +#ifdef ERROR_CHECK + if ( e < 0 || e >= A->end ) error_num ("MALIST_recov: e is out of range", e, EXIT); + if ( A->prv[e] >= 0 ) error_num ("MALIST_rm: element %d is already in some list.\n", e, EXIT); +#endif + i = A->prv[A->nxt[e]]; + l = MALIST_IS_ELM(*A,i)? A->list[i]: i - A->end; + A->list[e] = l; + A->num[l]++; + A->prv[e] = i; + A->nxt[i] = e; + A->prv[A->nxt[e]] = e; + if ( undo ) ALISTundo_ins (U_MALIST_rm, (void *)A, e, 0); +} + +/* remove all elements in the lth list */ +void MALIST_rmall (MALIST *A, ALIST_ID l){ + ALIST_ID i; + MALIST_DO_FORWARD (*A, l, i) A->prv[i] = -1; + A->num[l] = 0; + A->nxt[A->end+l] = A->end+l; + A->prv[A->end+l] = A->end+l; +} + +/* move element e to the lth list + with check insertion of non-removed element/range check */ +void MALIST_mv (MALIST *A, ALIST_ID l, ALIST_ID e, int undo){ + MALIST_rm (A, e, undo); + MALIST_ins_tail (A, l, e, undo); +} +void MALIST_mv_head (MALIST *A, ALIST_ID l, ALIST_ID e, int undo){ + MALIST_rm (A, e, undo); + MALIST_ins_head (A, l, e, undo); +} + +/* move all elements in llth list to lth list. do nothing if l==ll */ +void MALIST_mvall (MALIST *A, ALIST_ID l, ALIST_ID ll, int undo){ + ALIST_ID i, ii; +#ifdef ERROR_CHECK + if ( l == ll ) return; +#endif + MALIST_DO_FORWARD2 (*A, ll, i, ii) MALIST_mv (A, l, i, undo); +} + +/************* print routine ************/ + +/* print lth list */ +void MALIST_print (MALIST *A, ALIST_ID l){ + ALIST_ID i; + MALIST_DO_FORWARD (*A, l, i) printf (ALIST_IDF",", i); + printf ("\n"); +} + +/* print all lists */ +void MALIST_print_all (MALIST *A){ + ALIST_ID l, i; + FLOOP (l, 0, A->list_end){ + printf ("%d:", l); + MALIST_DO_FORWARD (*A, l, i) printf (ALIST_IDF",", i); + printf ("\n"); + } +} + + +/************* n ************/ + +/* return kth element from the head/tail. return the head/tail if k<1. + return root if k>current size */ +/* for large k, pass through the root element. */ +ALIST_ID MALIST_find_kth (MALIST *A, ALIST_ID l, ALIST_ID k){ + int x = MALIST_HEAD(*A,l); /* set x to the head of lth list */ + for ( ; k>1 ; k--) x = A->nxt[x]; /* go next from x k-1 times */ + return (x); +} + +ALIST_ID MALIST_find_tkth (MALIST *A, ALIST_ID l, ALIST_ID k){ + ALIST_ID x = MALIST_TAIL(*A,l); /* set x to the tail of lth list */ + for ( ; k>1 ; k--) x = A->prv[x]; /* go forward from x k-1 times */ + return (x); +} + +/* return a random element of lth list */ +ALIST_ID MALIST_find_rnd (MALIST *A, ALIST_ID l){ + ALIST_ID k = rand() % A->num[l]+1; + if ( k < A->num[l]/2 ) return (MALIST_find_kth (A, l, k) ); + return (MALIST_find_tkth (A, l, A->num[l]-k+1) ); +} + +/* find minimum/maximum weight of the element in lth list. + weights are given by array odr. find minimum if f==0, otherwise find the maximum + if odr is NULL, use index as weights */ +ALIST_ID MALIST_find_min_odr ( MALIST *A, ALIST_ID l, ALIST_ID *odr, int f ){ + ALIST_ID m = -1, i; + MALIST_DO_FORWARD (*A, l, i){ + if ( m == -1 ) m = i; + else { + if ( f ){ + if ( odr ){ + if ( odr[m] < odr[i] ) m = i; + } else if ( m < i ) m = i; + } else if ( odr ){ + if ( odr[m] > odr[i] ) m = i; + } else if ( m > i ) m = i; + } + } + return (m); +} + +/* partition the sub-list from head to tail, in the l-th list so that the former part + is composed of elements smaller than ind + and the latter is the remaining. if f!=0, then reverse order */ +/* return the position at which idx should be placed */ +ALIST_ID MALIST_seg_partition (MALIST *A, ALIST_ID l, ALIST_ID head, ALIST_ID tail, ALIST_ID idx, int f, int undo){ + ALIST_ID e1, e2, e, k=head; +#ifdef ERROR_CHECK + if ( l < 0 || l >= A->list_end ) error_num ("MALIST_partition: l is out of range", l, EXIT0); +#endif + if ( head >= A->num[l] ) return (-1); + e1 = MALIST_find_kth (A, l, head); + if ( tail>A->num[l] ) e2 = MALIST_TAIL (*A, l); + else e2 = MALIST_find_kth (A, l, tail); + + while (1){ + while ( f? (e1>idx): (e1nxt[e1]; + k++; + if ( e1==e2 ) goto END; + } + while ( f? (e2<=idx): (e2>idx) ){ + e2 = A->prv[e2]; + if ( e1==e2 ) goto END; + } + e = A->prv[e1]; + MALIST_rm (A, e1, undo); + MALIST_ins_nxt (A, e1, e2, undo); + MALIST_rm (A, e2, undo); + MALIST_ins_nxt (A, e2, e, undo); + e=e1; e1=e2; e2=e; + } + END:; + return (k); +} + +/* partition the l-th list so that the former part is composed of elements smaller than ind + and the latter is the remaining. if f!=0, then reverse order */ +/* return the position at which idx should be placed */ +ALIST_ID MALIST_partition (MALIST *A, ALIST_ID l, ALIST_ID idx, int f, int undo){ + ALIST_ID e, e1, e2, k=1; +#ifdef ERROR_CHECK + if ( l < 0 || l >= A->list_end ) error_num ("MALIST_partition: l is out of range", l, EXIT0); +#endif + e1 = MALIST_HEAD ( *A, l ); + e2 = MALIST_TAIL ( *A, l ); + while (1){ + while ( f? (e1>idx): (e1nxt[e1]; + k++; + if ( e1==e2 ) goto END; + } + while ( f? (e2<=idx): (e2>idx) ){ + e2 = A->prv[e2]; + if ( e1==e2 ) goto END; + } + e = A->prv[e1]; + MALIST_rm (A, e1, undo); + MALIST_ins_nxt (A, e1, e2, undo); + MALIST_rm (A, e2, undo); + MALIST_ins_nxt (A, e2, e, undo); + e=e1; e1=e2; e2=e; + } + END:; + if ( e2 == MALIST_TAIL (*A, l) && ( f? (e2<=idx): (e2>idx) ) ) k++; + return (k); +} + +/* partition the l-th list so that any of the former k elements is smaller than any of the + lattter. if f!=0, then reverse order */ +/* return the k-th element */ +ALIST_ID MALIST_k_partition (MALIST *A, ALIST_ID l, ALIST_ID k, int f, int undo){ + ALIST_ID e, ee, head=1, tail=A->num[l], kk; +#ifdef ERROR_CHECK + if ( l < 0 || l >= A->list_end ) error_num ("MALIST_partition: l is out of range", l, EXIT0); +#endif + while (1){ + e = MALIST_find_kth (A, l, k); + if ( tail == head ) break; + kk = MALIST_seg_partition (A, l, head, tail, e, f, undo); + if ( kk == head ){ + if ( k == head ) return (e); + ee = MALIST_find_kth (A, l, head); + kk = A->prv[ee]; + MALIST_rm (A, ee, undo); + MALIST_ins_nxt (A, ee, e, undo); + MALIST_rm (A, e, undo); + MALIST_ins_nxt (A, e, kk, undo); + head++; + } + else if ( kk<=k ) head = kk; + else tail = kk-1; + } + return (e); +} + + + +/* sort lth list in the order of indices. increasing order if f==0, decreasing otherwise */ +void MALIST_sort (MALIST *A, ALIST_ID l, int f, int undo){ + ALIST_ID i, ii, j; + MALIST_DO_FORWARD2 (*A, l, i, ii){ + j=A->prv[i]; + MALIST_rm (A, i, undo); + if ( f ) while (MALIST_IS_ELM(*A, j) && jprv[j]; + else while (MALIST_IS_ELM(*A, j) && j>i ) j = A->prv[j]; + MALIST_ins_nxt (A, i, j, undo); + } +} + +void MALIST_sort_odr (MALIST *A, ALIST_ID l, ALIST_ID f, int *odr, int undo){ + ALIST_ID i, ii, j; + MALIST_DO_FORWARD2 (*A, l, i, ii){ + j = A->prv[i]; + MALIST_rm (A, i, undo); + if ( f ) while (MALIST_IS_ELM(*A, j) && odr[j]prv[j]; + else while (MALIST_IS_ELM(*A, j) && odr[j]>odr[i]) j = A->prv[j]; + MALIST_ins_nxt (A, i, j, undo); + } +} + +/* remove all elements included in ALIST B, from lth list of MALIST A */ +void MALIST_minus_ALIST ( MALIST *A, ALIST_ID l, ALIST *B ){ + ALIST_ID i; + ALIST_DO_FORWARD (*B, i) if ( A->list[i] == l ) MALIST_rm (A, i, 0); +} + + +#endif + + + diff --git a/rql-backend/shd31/alist.h b/rql-backend/shd31/alist.h new file mode 100644 index 0000000..6826783 --- /dev/null +++ b/rql-backend/shd31/alist.h @@ -0,0 +1,225 @@ +/* array-based list/multi-list library + 12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +#ifndef _alist_h_ +#define _alist_h_ + +#include"stdlib2.h" +#include"undo.h" + +#ifndef ALIST_ID + #ifdef ALIST_ID_LONG + #define ALIST_ID LONG + #define ALIST_ID_END LONGHUGE + #define ALIST_IDF LONGF + #else + #define ALIST_ID int + #define ALIST_ID_END INTHUGE + #define ALIST_IDF "%d" + #endif +#endif + +/* macros for getting head, tail of (multi) list */ +#define ALIST_HEAD(A) ((A).nxt[(A).end]) +#define ALIST_TAIL(A) ((A).prv[(A).end]) +#define MALIST_HEAD(A,l) ((A).nxt[(A).end+l]) +#define MALIST_TAIL(A,l) ((A).prv[(A).end+l]) + +/* macro to check if e is an element(or root element) */ +#define ALIST_IS_ELM(A,e) (e<(A).end) +#define MALIST_IS_ELM(A,e) (e<(A).end) + +/* macros for loops */ +/* each ***2 works correctly even when we remove the current element from the list */ +#define ALIST_DO_FORWARD(A,i) for((i)=(A).nxt[(A).end];(i)<(A).end;(i)=(A).nxt[(i)]) +#define ALIST_DO_FORWARD2(A,i,ii) for(i=(A).nxt[(A).end],ii=(A).nxt[i];(i)<(A).end;i=ii,ii=(A).nxt[i]) +#define ALIST_DO_BACKWARD(A,i) for((i)=(A).prv[(A).end];(i)<(A).end;i=(A).prv[(i)]) +#define ALIST_DO_BACKWARD2(A,i,ii) for((i)=(A).prv[(A).end],ii=(A).prv[i];(i)<(A).end;i=ii,ii=(A).prv[i]) +#define MALIST_DO_FORWARD(A,l,i) for((i)=(A).nxt[(A).end+l];(i)<(A).end;(i)=(A).nxt[(i)]) +#define MALIST_DO_FORWARD2(A,l,i,ii) for((i)=(A).nxt[(A).end+l],ii=(A).nxt[i];(i)<(A).end;i=ii,ii=(A).nxt[i]) +#define MALIST_DO_BACKWARD(A,l,i) for((i)=(A).prv[(A).end+l];(i)<(A).end;(i)=(A).prv[(i)]) +#define MALIST_DO_BACKWARD2(A,l,i,ii) for((i)=(A).prv[(A).end+l],ii=(A).prv[i];(i)<(A).end;i=ii,ii=(A).prv[i]) + +/* marco for getting the list number of a root element e */ +#define MALIST_LIST(A,e) ((e)-((A).end)) + +/* struct for array list. the "end"th element is the root of the list */ +/* the element e not included in the list is identified by "prv[e] = -1 */ +typedef struct { + unsigned char type; + int *prv; /* index of the previous element of each element */ + int *nxt; /* index of the next element of each element */ + int end; /* maximum number of elements */ + int num; /* the length of the current list */ +} ALIST; + +extern ALIST INIT_ALIST; +QSORT_TYPE_HEADER(ALIST_ID, ALIST_ID) + +/************* initialization/termination ************/ + +void ALIST_alloc (ALIST *A, ALIST_ID siz); /* initialization */ +void ALIST_end (ALIST *A); /* termination */ +void ALIST_cpy (ALIST *A1, ALIST *A2); /* copy A2 to A1 */ +ALIST ALIST_dup (ALIST *A); /* duplication */ + +/************* addition/deletion ************/ + +/* insert an element e previous/next to element i or haed/tail of the list + error is checked for already inserted elements or out of range */ +void ALIST_ins_nxt (ALIST *A, ALIST_ID e, ALIST_ID i, int undo); +void ALIST_ins_prv (ALIST *A, ALIST_ID e, ALIST_ID i, int undo); +void ALIST_ins_head (ALIST *A, ALIST_ID e, int undo); +void ALIST_ins_tail (ALIST *A, ALIST_ID e, int undo); + +/* remove head/tail of the list, and return it. return root if empty list + with check removal of removed element/range check */ +ALIST_ID ALIST_rm_head (ALIST *A, int undo); +ALIST_ID ALIST_rm_tail (ALIST *A, int undo); + +/* remove an element e from list A. + with check removal of removed element/range check */ +void ALIST_rm (ALIST *A, ALIST_ID e, int undo); + +/* re-insert removed element by ALIST_rm to its original position. precisely, + insert removed element e previous to the next element when e is in the list + with check insertion of non-removed element/range check */ +void ALIST_recov (ALIST *A, ALIST_ID e, int undo); + +/* remove all elements in a list */ +void ALIST_rmall (ALIST *A); + +/************* print routines ************/ + +/* print all elements in the list */ +void ALIST_print (ALIST *A, int flag); + +/************* search ************/ + +/* return the kth element next/previous to i */ +/* for large k, pass through the root element. */ +ALIST_ID ALIST_knxt (ALIST *A, ALIST_ID i, ALIST_ID k); +ALIST_ID ALIST_kprv (ALIST *A, ALIST_ID i, ALIST_ID k); + +/* return kth element from the head/tail. return the head/tail if k<1. + return root if k>current size */ +ALIST_ID ALIST_find_kth (ALIST *A, ALIST_ID k); +ALIST_ID ALIST_find_tkth (ALIST *A, ALIST_ID k); + +/* return element randomly chosen from all element in A */ +ALIST_ID ALIST_find_rnd (ALIST *A); + + +/* sort elements in the list by merge sort without recursion */ +/* increasing order if f==0 */ +void ALIST_sort (ALIST *A, int f, int undo); + +/* return the most tailmost element which does not exceed i. + return root if there is no such element */ +ALIST_ID ALIST_find_i (ALIST *A, ALIST_ID i); + +/************* rich operations ************/ + +/* remove elements in B/not in B from A */ +void ALIST_minus (ALIST *A, ALIST *B, int undo); +void ALIST_and (ALIST *A, ALIST *B, int undo); + +/* concatinate A2 following to A1, A2 remains in ALIST_concat, not remain in ALIST_append */ +void ALIST_append (ALIST *A1, ALIST *A2, int undo); +void ALIST_concat (ALIST *A1, ALIST *A2, int undo); + + + +/********************************************************************/ +/******************* ȌAMALIST *********************************/ +/********************************************************************/ + +/* structure for array based multi list. each element can belong to at most one list */ +typedef struct { + unsigned char type; + ALIST_ID *prv; /* previous element to i */ + ALIST_ID *nxt; /* next element to i */ + ALIST_ID end; /* total #of elements */ + ALIST_ID *num; /* current length of each list */ + ALIST_ID *list; /* index of the list that each element belongs. If not belong, -1 */ + ALIST_ID list_end; /* maximum #lists */ +} MALIST; + +extern MALIST INIT_MALIST; + +/************* initialization/termination ************/ + +void MALIST_alloc (MALIST *A, ALIST_ID siz, ALIST_ID list_siz); /* initialization with #elements siz, and #list list_siz */ +void MALIST_end (MALIST *A); /* termination */ +void MALIST_cpy (MALIST *A1, MALIST *A2); /* copy. with size overflow check */ +MALIST MALIST_dup (MALIST *A); /* duplication */ + + +/************* addition/deletion ************/ + +/* insert an element e previous/next to element ee or haed/tail of the list l + error is checked for already inserted elements or out of range */ +void MALIST_ins_nxt (MALIST *A, ALIST_ID e, ALIST_ID ee, int undo); +void MALIST_ins_prv (MALIST *A, ALIST_ID e, ALIST_ID ee, int undo); +void MALIST_ins_head (MALIST *A, ALIST_ID l, ALIST_ID e, int undo); +void MALIST_ins_tail (MALIST *A, ALIST_ID l, ALIST_ID e, int undo); + +/* remove head/tail of the list, and return it. return root if empty list + with check removal of removed element/range check */ +ALIST_ID MALIST_rm_head (MALIST *A, ALIST_ID l, int undo); +ALIST_ID MALIST_rm_tail (MALIST *A, ALIST_ID l, int undo); + +/* remove an element e from A. + with check removal of removed element/range check */ +void MALIST_rm (MALIST *A, ALIST_ID e, int undo); + +/* re-insert removed element by MALIST_rm to its original position. precisely, + insert removed element e previous to the next element when e is in the list + with check insertion of non-removed element/range check */ +void MALIST_recov (MALIST *A, ALIST_ID e, int undo); + +/* remove all elements in the lth list */ +void MALIST_rmall (MALIST *A, ALIST_ID l); + +/* move element e to the lth list + with check insertion of non-removed element/range check */ +void MALIST_mv (MALIST *A, ALIST_ID l, ALIST_ID e, int undo); +void MALIST_mv_head (MALIST *A, ALIST_ID l, ALIST_ID e, int undo); +/* move all elements in llth list to lth list. do nothing if l==ll */ +void MALIST_mvall (MALIST *A, ALIST_ID l, ALIST_ID ll, int undo); + +/************* print routines ************/ + +void MALIST_print (MALIST *A, ALIST_ID l); /* print lth list */ +void MALIST_print_all (MALIST *A); /* print all lists */ + +/************* search ************/ + +/* return the kth element from the head/tail of the lth list */ +ALIST_ID MALIST_find_kth (MALIST *A, ALIST_ID l, ALIST_ID k); +ALIST_ID MALIST_find_tkth (MALIST *A, ALIST_ID l, ALIST_ID k); + +/* return a random element of lth list */ +ALIST_ID MALIST_find_rnd (MALIST *A, ALIST_ID l); + +/* find minimum/maximum weight of the element in lth list. + weights are given by array odr. find minimum if f==0, otherwise find the maximum + if odr is NULL, use index as weights */ +ALIST_ID MALIST_find_min_odr (MALIST *A, ALIST_ID l, ALIST_ID *odr, int f); + +/* sort lth list in the order of indices/weights. increasing order if f==0, decreasing otherwise */ +void MALIST_sort (MALIST *A, ALIST_ID l, int f, int undo); +void MALIST_sort_odr (MALIST *A, ALIST_ID l, int f, int *odr, int undo); + +/* remove all elements included in ALIST B, from lth list of MALIST A */ +void MALIST_minus_ALIST (MALIST *A, ALIST_ID l, ALIST *B); + +#endif diff --git a/rql-backend/shd31/appendnum.pl b/rql-backend/shd31/appendnum.pl new file mode 100644 index 0000000..7012684 --- /dev/null +++ b/rql-backend/shd31/appendnum.pl @@ -0,0 +1,31 @@ +#!/usr/bin/perl + +#appendnum.pl appends the column number (column ID) to each item in each line +# the item-separator can be given by the first parameter +# input and output are done from/to standard input/output + +$ARGC = @ARGV; +if ( $ARGC < 0 ){ + printf ("appendnum.pl: [separator] < input-file > output-file\n"); + exit (1); +} +$count = 0; +%numbers = (); + +$sep = " "; +if ( $ARGC >= 1 ){ $sep = $ARGV[0]; } + +while (){ + chomp; + @eles = split($sep, $_); + $all = @eles; + $c = 0; + foreach $item( @eles ) { + if ( $item ne "" ){ + print "$item.$c" ; + $c++; + if ($c<$all){ print $sep; } + } + } + print "\n"; +} diff --git a/rql-backend/shd31/barray.c b/rql-backend/shd31/barray.c new file mode 100644 index 0000000..8c40cfe --- /dev/null +++ b/rql-backend/shd31/barray.c @@ -0,0 +1,238 @@ +/* + bit-array library + 12/Mar/2002 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +#ifndef _barray_c_ +#define _barray_c_ + +#include"barray.h" + +BARRAY INIT_BARRAY = {TYPE_BARRAY, NULL, 0, NULL, 0, 0, 0, 0}; + +/* initialization */ +void BARRAY_init (BARRAY *A, QUEUE_ID xsiz, VEC_ID t){ + A->xsiz = xsiz; + A->xend = (xsiz-1)/32+1; + A->end = A->t = t; + calloc2 (A->v, (A->xend)*t, EXIT); +} + +/* termination */ +void BARRAY_end (BARRAY *A){ + free2 (A->v); +} + +/* set from x1-th bit to x2-th bit to 1. x2 is also set to 1 */ +void BARRAY_set_interval (unsigned long *a, QUEUE_ID x1, QUEUE_ID x2){ + QUEUE_ID x=x1/32, i, xx=x2/32; + if ( x == xx ){ + for (i=x1%32 ; i<=x2%32 ; i++) BARY_SET (a, i); + } else { + a[x] |= BITMASK_UPPER1[x1%32]; + x++; + for ( ; xxsiz, A->t); + FLOOP (i, 0, A->t){ + FLOOP (j, 0, A->xsiz) printf (BARRAY_BIT (*A, j, i)?"1":"0"); + printf ("\n"); + } +} + +/* compare one long as bit sequence from k1-th bit to k2-th bit. + (_suf compares top to k-th bits, _pre compares k-th bits to the tail. + return minus value if A is small, 0 if same, plus value if B is small (same as "qsort") + the absolute value of the returned value is the first different bit +1 */ +int BARRAY_longcmp_suf (unsigned long a, unsigned long b, int k){ + unsigned long m = a^b; + for ( ; k<32 ; k++){ + if ( m&BITMASK_1[k] ){ + if ( a&BITMASK_1[k] ) return (k+1); + else return (-k-1); + } + } + return(0); +} +int BARRAY_longcmp_pre (unsigned long a, unsigned long b, int k ){ + unsigned long j, m = a^b; + FLOOP (j, 0, k+1){ + if ( m&BITMASK_1[j] ){ + if ( a&BITMASK_1[j] ) return (j+1); + else return (-j-1); + } + } + return(0); +} +int BARRAY_longcmp ( unsigned long a, unsigned long b, int k1, int k2){ + unsigned long m = a^b; + for ( ; k1<=k2 ; k1++){ + if ( m&BITMASK_1[k1] ){ + if ( a&BITMASK_1[k1] ) return (k1+1); + else return (-k1-1); + } + } + return(0); +} + +/* for return */ +int BARRAY_cmp_return (unsigned long a, unsigned long b){ + return ( b + (b<0?-a*32:b>0?a*32:0) ); +} + +int BARRAY_cmp (unsigned long *a, unsigned long *b, QUEUE_ID k){ + QUEUE_ID i=0; + while ( a[i] == b[i] ){ + i++; + if ( i > (k-1)/32 ) return (0); /* two are the same until the last */ + } + return ( BARRAY_cmp_return ( i, BARRAY_longcmp_pre (a[i], b[i], k%32))); +} + +/* set 1 for all positions in QUEUE Q */ +void BARRAY_set_subset (unsigned long *a, QUEUE *Q){ + QUEUE_INT *x; + MQUE_FLOOP (*Q, x) BIT_SET(a,*x); +} + +/* +int BARRAY_subcmp_ (unsigned long *a, unsigned long *b, QUEUE_ID k1, QUEUE_ID k2 ){ + int i=k1/32, m; + if ( i == k2/32 ) + return (BARRAY_cmp_return(i, BARRAY_longcmp(A->v[i], B->v[i], k1%32, k2%32))); + m = BARRAY_longcmp_suf ( A->v[i], B->v[i], k1%32 ); + if ( m != 0 ) return ( BARRAY_cmp_return ( i, m ) ); + + while ( A->v[i] == B->v[i] ){ + i++; + if ( i == k2/32 ) break; + } + return( BARRAY_cmp_return( i, BARRAY_longcmp_pre( A->v[i], B->v[i], k2%32))); +} +int BARRAY_subcmp (unsigned long *a, unsigned long *b, QUEUE_ID k1, QUEUE_ID k2, QUEUE_ID k){ +#ifdef ERROR_CHECK + if ( k1<0 || k1>=A->end ){ + printf ("BARRAY_subcmp: k1 is out of range. %d\n", k1 ); + exit(1); + } + if ( k2<0 || k2>=B->end ){ + printf ("BARRAY_subcmp: k2 is out of range. %d\n", k2 ); + exit(1); + } + if ( k+k1 >= A->end ) k = A->end - k1; + if ( k+k2 >= B->end ) k = B->end - k2; +#endif + while ( BARRAY_01(*A,k1) == BARRAY_01(*B,k2) ){ + if ( k1 == k ) return (0); + k1++; + k2++; + } + return ( BARRAY_BIT(*A,k1)? k1+1: -k1-1 ); +} +*/ + +/* load barray matrix, from 01 matrix file */ +/* if cr code is middle of a line, the rest is trancated (not filled), + and the following line will be read to a new line. */ +/* 0, -, ' ' will be 0, and the others will be 1 */ +/* support LOAD_TPOSE */ +void BARRAY_load (BARRAY *A){ + FILE2 fp; + size_t xmax=0, x=0, y=0, i=0; + int c, flag=0, f, ff; + + FILE2_open (fp, A->fname, "r", EXIT); + while ( (c = FILE2_getc (&fp)) >=0 ){ + if ( c=='\n' ){ + if ( flag == 2 ) flag = 0; + else flag = 1; + } else if ( c=='\r' ){ + if ( flag == 1 ) flag = 0; + else flag = 2; + } else { x++; flag = 0; } + if ( flag ){ i++; ENMAX (xmax, x); x=0; } + } + if ( A->flag & LOAD_TPOSE ) { y=xmax; xmax=i; i=y; } + BARRAY_init (A, xmax, i); + x = i = 0; + FILE2_reset (&fp); + while ( (c=FILE2_getc(&fp)) >=0 ){ + if ( c=='\n' ){ + if ( flag == 2 ) flag = 0; + else flag = 1; + } else if ( c=='\r' ){ + if ( flag == 1 ) flag = 0; + else flag = 2; + } else { + flag = 0; + f = (c=='0' || c==' ' || c=='-')?1:0; + ff = (A->flag&LOAD_COMP)?1:0; + if ( f^ff ){ + if ( A->flag & LOAD_TPOSE ) BARRAY_RESET (*A, i, x); + else BARRAY_RESET (*A, x, i); + } else if ( A->flag & LOAD_TPOSE ) BARRAY_SET (*A, i, x); + else BARRAY_SET (*A, x, i); + x++; + } + if ( flag ){ i++; x=0; } + } + FILE2_close (&fp); if(ERROR_MES) EXIT; +} + + +/* +main (){ + BARRAY A, B; + int i, j; + + BARRAY_init ( &A, 70 ); + BARRAY_init ( &B, 70 ); + A.a[0] = 0x1111ffff; + B.a[0] = 0x1111ffff; + A.a[1] = 0x1111f1ff; + B.a[1] = 0x1111ff1f; + printf ("%d\n", BARRAY_subcmp ( &A, &B, 26,30,40) ); + + BARRAY_set_interval ( &A, 0, 69); + BARRAY_reset_interval ( &A, 0, 63 ); + BARRAY_SET ( A,10 ); + BARRAY_SET ( A,20 ); + BARRAY_SET ( A,30 ); + BARRAY_SET ( A,40 ); + BARRAY_SET ( A,50 ); + BARRAY_SET ( A,60 ); + BARRAY_print ( &A ); +} +*/ + + +#endif + diff --git a/rql-backend/shd31/barray.h b/rql-backend/shd31/barray.h new file mode 100644 index 0000000..8b6b507 --- /dev/null +++ b/rql-backend/shd31/barray.h @@ -0,0 +1,74 @@ +/* + bit-array library + 12/Mar/2002 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +#ifndef _barray_h_ +#define _barray_h_ + +#include"queue.h" + + +typedef struct { + unsigned char type; // mark to identify type of the structure + char *fname; // input file name + int flag; // flag + + unsigned long *v; + VEC_ID end; + VEC_ID t; + QUEUE_ID xend; + QUEUE_ID xsiz; +} BARRAY; +extern BARRAY INIT_BARRAY; + +#define BARY_SET(a,x) ((a)[(x)/32]|=BITMASK_1[(x)%32]) +#define BARY_RESET(a,x) ((a)[(x)/32]&=BITMASK_31[(x)%32]) +#define BARY_BIT(a,x) ((a)[(x)/32]&BITMASK_1[(x)%32]) +#define BARY_01(a,x) (((a)[(x)/32]&BITMASK_1[(x)%32])/BITMASK_1[(x)%32]) +#define BARRAY_SET(A,x,y) ((A).v[(y)*(A).xend+(x)/32]|=BITMASK_1[(x)%32]) +#define BARRAY_RESET(A,x,y) ((A).v[(y)*(A).xend+(x)/32]&=BITMASK_31[(x)%32]) +#define BARRAY_BIT(A,x,y) ((A).v[(y)*(A).xend+(x)/32]&BITMASK_1[(x)%32]) +#define BARRAY_01(A,x,y) (((A).v[(y)*(A).xend+(x)/32]&BITMASK_1[(x)%32])/BITMASK_1[(x)%32]) + +/* initialization/termination */ +void BARRAY_init (BARRAY *A, QUEUE_ID x_end, VEC_ID t); +void BARRAY_end (BARRAY *A); + +/* set from x1-th bit to x2-th bit to 1/0. x2 is also set to 1/0 */ +void BARRAY_set_interval (unsigned long *a, QUEUE_ID x1, QUEUE_ID x2); +void BARRAY_reset_interval (unsigned long *a, QUEUE_ID x1, QUEUE_ID x2); + +/* print */ +void BARRAY_print (BARRAY *A); + + +/* compare one long as bit sequence from k1-th bit to k2-th bit. + (_suf compares top to k-th bits, _pre compares k-th bits to the tail. + return minus value if A is small, 0 if same, plus value if B is small (same as "qsort") + the absolute value of the returned value is the first different bit +1 */ +int BARRAY_longcmp_suf (unsigned long a, unsigned long b, int k); +int BARRAY_longcmp_pre (unsigned long a, unsigned long b, int k); +int BARRAY_longcmp (unsigned long a, unsigned long b, int k1, int k2); +/* for "return" */ +int BARRAY_cmp_return (unsigned long a, unsigned long b); + +/* compare bit sequence in the lexicographical order. + (compare from k1 to k2-th bits, compare k1-th to (k1+k)th bits of A and + k2-th to (k2+k)th bits of B) + return minus value if A is small, 0 if same, plus value if B is small (same as "qsort") + the absolute value of the returned value is the first different bit +1 */ +int BARRAY_cmp (unsigned long *a, unsigned long *b, QUEUE_ID k); +int BARRAY_subcmp_ (unsigned long *a, unsigned long *b, QUEUE_ID k1, QUEUE_ID k2); +int BARRAY_subcmp (unsigned long *a, unsigned long *b, QUEUE_ID k1, QUEUE_ID k2, QUEUE_ID k); + + +#endif + diff --git a/rql-backend/shd31/base.c b/rql-backend/shd31/base.c new file mode 100644 index 0000000..9699f65 --- /dev/null +++ b/rql-backend/shd31/base.c @@ -0,0 +1,92 @@ +/* + blocked memory allocation library + 12/Mar/2002 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +#ifndef _base_c_ +#define _base_c_ + +#include"base.h" + +BASE INIT_BASE = {TYPE_BASE,NULL,0,0,0,0,-1,NULL}; + +/* initialization, and allocate memory for header */ +void BASE_alloc (BASE *B, int unit, int block_siz){ + *B = INIT_BASE; + B->dellist = B; + B->unit = unit; + B->block_siz = block_siz; + B->num = block_siz; + B->block_num = -1; + calloc2 (B->base, 20, EXIT); + B->block_end = 20; +} + +/* termination */ +void BASE_end (BASE *B){ + int i; + FLOOP (i, 0, B->block_end) free2 (B->base[i]); + free2 (B->base); + *B = INIT_BASE; +} + +/* return pointer to the cell corresponding to the given index */ +void *BASE_pnt (BASE *B, size_t i){ + return ( B->base[i/BASE_BLOCK] + (i%BASE_BLOCK)*B->unit); +} +/* return index corresponding to the given pointer */ +size_t BASE_index (BASE *B, void *x){ + size_t i; + FLOOP (i, 0, (size_t)(B->block_end+1)){ + if ( ((char*)x)>= B->base[i] && ((char*)x)<=B->base[i]+B->unit*BASE_BLOCK ) + return ( i*BASE_BLOCK + ((size_t)(((char *)x) - B->base[i])) / B->unit); + } + return (0); +} + +/* increment the current memory block pointer and (re)allcate memory if necessary */ +void *BASE_get_memory (BASE *B, int i){ + B->num += i; + if ( B->num >= B->block_siz ){ /* if reach to the end of base array */ + B->num = i; /* allocate one more base array, and increment the counter */ + B->block_num++; + reallocx(B->base, B->block_end, B->block_num, NULL, EXIT0); + if ( B->base[B->block_num] == NULL ) + malloc2 (B->base[B->block_num], B->block_siz*B->unit, EXIT0); + return (B->base[B->block_num]); + } + return (B->base[B->block_num] + (B->num-i)*B->unit); +} + + +/* allocate new cell */ +void *BASE_new (BASE *B){ + char *x; + + /* use deleted cell if it exists */ + if ( B->dellist != ((void *)B) ){ + x = (char *)B->dellist; /* return the deleted cell */ + B->dellist = (void *)(*((char **)x)); /* increment the head of the list */ + } else { + /* take a new cell from the base array if no deleted one exists */ + x = (char *)BASE_get_memory (B, 1); + } + return (x); +} + +/* delete one cell. (add to the deleted list) */ +void BASE_del (BASE *B, void *x){ + *((void **)x) = B->dellist; + B->dellist = x; +} + +#endif + + diff --git a/rql-backend/shd31/base.h b/rql-backend/shd31/base.h new file mode 100644 index 0000000..61b7792 --- /dev/null +++ b/rql-backend/shd31/base.h @@ -0,0 +1,59 @@ +/* + blocked memory allocation library + 12/Mar/2002 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + + +#ifndef _base_h_ +#define _base_h_ + +#include"stdlib2.h" + +/* structure for base array */ +#define BASE_UNIT 16 +#define BASE_BLOCK 65536 + +typedef struct { + unsigned char type; + char **base; + int block_siz; // size of one block of memory + int block_num; // currently using block + int unit; // size of one unit memory + int num; // current position in a block + int block_end; // current end of the block + void *dellist; +} BASE; + +extern BASE INIT_BASE; + +/* initialization, and allocate memory for header */ +void BASE_alloc (BASE *B, int unit, int block_siz); + +/* termination */ +void BASE_end (BASE *B); + +/* return pointer to the cell corresponding to the given index */ +void *BASE_pnt (BASE *B, size_t i); + +/* return index corresponding to the given pointer */ +size_t BASE_index (BASE *B, void *x); + +/* increment the current memory block pointer and (re)allcate memory if necessary */ +void *BASE_get_memory (BASE *B, int i); + +/* allocate new cell */ +void *BASE_new (BASE *B); + +/* delete one cell. (add to the deleted list) */ +void BASE_del (BASE *B, void *x); + + +#endif + diff --git a/rql-backend/shd31/col_conv.pl b/rql-backend/shd31/col_conv.pl new file mode 100644 index 0000000..95fbffe --- /dev/null +++ b/rql-backend/shd31/col_conv.pl @@ -0,0 +1,101 @@ +#!/bin/perl + +#!/usr/bin/perl + +# according to the rule file, convert each item of each line to +# another item +# each line of the rule file is a rule for one column +# the ith line is for ith column +# the first item of each line means the type of conversion, of each column. + +# #: comment +# I: ignore the column; no item will be added +# S: string, the column is treated as a string +# P: the column is treated as a number. The following sequence of +# numbers means the boundaries, and when the number in a column exceeds +# the i-th number, then item XX_i is put. Thus, if the sequence is +# 1 5 8 11, and the number is 6, then the items put are XX_3 and XX_4, +# where XX is the column ID +# N: same as P, but items are put when the number is smaller than the boundaries. +# B: P and N +# M: items are put when the number in a column is smaller than a number in +# the former half, or bigger than a number in the latter half + + +# the intervals. The numbers will be classified according to the number +# ex) x y z, mean intervals (-inf, x), [x, y), [y,z), [z,+inf) + +# The separator for the rule-file is " ", but we can specify the separator +# of the number in the data file, by the second parameter + + +$ARGC = @ARGV; +$c=0; +if ( $ARGC < 1 ){ + printf ("col_conv.pl: rule-file [separator] < input-file > output-file\n"); + exit (1); +} +open ( RULEFILE, "<$ARGV[0]" ); +$c++; +$sep = " "; +if ( $ARGC > 1 ){ $sep = $ARGV[$c]; } + +@table = ; +$count = 0; +%numbers = (); +$clms=0; + +foreach $trans( @table ){ + chomp ( $trans ); + @eles = split(" ", $trans); + $type[$clms] = shift(@eles); + if ( $type[$clms] ne "#" ){ + if ( $type[$clms] ne "S" && $type[$clms] ne "I" ){ + $c=0; + foreach $cell(@eles){ + if ( $cell == 0 ){ + if (index ( $cell, "0") >= 0 ){ $bound[$clms] .= $cell." "; } + } else { $bound[$clms] .= $cell." "; } + $c++; + } + $bound_num[$clms]=$c; + } + $clms++; + } +} + +while (){ + chomp; + @eles = split($sep, $_); + $c=0; + foreach $cell(@eles){ + if ( $c >= $clms ){ + print $cell." "; + } elsif ( $type[$c] eq "S" ){ + print "($c)".$cell." "; + } elsif ( $type[$c] ne "I" ){ + @bnd=split(" ", $bound[$c]); + $cc=0; + foreach $bbb(@bnd){ + if ( ($type[$c] eq "P" || $type[$c] eq "B") && ($cell > $bbb) ){ + print "($c)>$bbb "; + } + if ( ($type[$c] eq "N" || $type[$c] eq "B") && ($cell < $bbb) ){ + print "($c)<$bbb "; + } + if ( ($type[$c] eq "M") && ($cell < $bbb) && ($cc < ($bound_num[$c]+1)/2) ){ + print "($c)<$bbb "; + } + if ( ($type[$c] eq "M") && ($cell > $bbb) && ($cc >= ($bound_num[$c]-1)/2)){ + print "($c)>$bbb "; + } + $cc++; + } + } + $c++; + } + print "\n"; +} + + + diff --git a/rql-backend/shd31/exec_shd b/rql-backend/shd31/exec_shd new file mode 100644 index 0000000..fca7c85 --- /dev/null +++ b/rql-backend/shd31/exec_shd @@ -0,0 +1,5 @@ +./transnum.pl __tmp1__ < $2 > __tmp2__ +./shd $1 $4 $5 $6 $7 $8 $9 __tmp2__ $3 __tmp3__ +touch __tmp3__ +./untransnum.pl __tmp1__ < __tmp3__ > $3 +rm -f __tmp1__ __tmp2__ __tmp3__ diff --git a/rql-backend/shd31/exec_shd_ b/rql-backend/shd31/exec_shd_ new file mode 100644 index 0000000..130e0b9 --- /dev/null +++ b/rql-backend/shd31/exec_shd_ @@ -0,0 +1,7 @@ +./appendnum.pl < $2 > __tmp4__ +./transnum.pl __tmp1__ < __tmp4__ > __tmp2__ +rm -f __tmp4__ +./shd $1 $4 $5 $6 $7 $8 $9 __tmp2__ __tmp3__ +touch __tmp3__ +./untransnum.pl __tmp1__ < __tmp3__ > $3 +rm -f __tmp1__ __tmp2__ __tmp3__ diff --git a/rql-backend/shd31/itemset.c b/rql-backend/shd31/itemset.c new file mode 100644 index 0000000..b7ae1f2 --- /dev/null +++ b/rql-backend/shd31/itemset.c @@ -0,0 +1,496 @@ +/* itemset search input/output common routines + 25/Nov/2007 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +/* routines for itemset mining */ + +#ifndef _itemset_c_ +#define _itemset_c_ + +#include"itemset.h" +#include"queue.c" +#include"aheap.c" + +/* flush the write buffer, available for multi-core mode */ +void ITEMSET_flush (ITEMSET *I, FILE2 *fp){ + if ( !(I->flag&ITEMSET_MULTI_OUTPUT) || (fp->buf-fp->buf_org) > FILE2_BUFSIZ/2 ){ + SPIN_LOCK(I->multi_core, I->lock_output); + FILE2_flush (fp); + SPIN_UNLOCK(I->multi_core, I->lock_output); + } +} + +/* Output information about ITEMSET structure. flag&1: print frequency constraint */ +void ITEMSET_print (ITEMSET *I, int flag){ + if ( I->lb>0 || I->ublb > 0 ) print_err ("%d <= ", I->lb); + print_err ("itemsets "); + if ( I->ub < INTHUGE ) print_err (" <= %d\n", I->ub); + print_err ("\n"); + } + if ( flag&1 ){ + if ( I->frq_lb > -WEIGHTHUGE ) print_err (WEIGHTF" <=", I->frq_lb); + print_err (" frequency "); + if ( I->frq_ub < WEIGHTHUGE ) print_err (" <="WEIGHTF, I->frq_ub); + print_err ("\n"); + } +} + +/* ITEMSET initialization */ +void ITEMSET_init (ITEMSET *I){ + I->flag = 0; + I->progress = 0; + I->iters = I->iters2 = I->iters3 = 0; + I->solutions = I->solutions2 = I->max_solutions = I->outputs = I->outputs2 = 0; + I->topk.end = 0; + I->item_max = I->item_max_org = 0; + I->ub = I->len_ub = I->gap_ub = INTHUGE; + I->lb = I->len_lb = I->gap_lb = 0; + I->frq = I->pfrq = I->total_weight = 0; + I->ratio = I->prob = 0.0; + I->posi_ub = I->nega_ub = I->frq_ub = WEIGHTHUGE; + I->posi_lb = I->nega_lb = I->frq_lb = I->setrule_lb = -WEIGHTHUGE; + I->dir = 0; + I->target = INTHUGE; + I->prob_ub = I->ratio_ub = I->rposi_ub = 1; + I->prob_lb = I->ratio_lb = I->rposi_lb = 0; + I->itemflag = NULL; + I->perm = NULL; + I->item_frq = NULL; + I->sc = NULL; + I->X = NULL; + I->fp = NULL; + I->separator = ' '; + I->topk = INIT_AHEAP; + I->itemset = I->add = INIT_QUEUE; + I->set_weight = NULL; + I->set_occ = NULL; + + I->multi_iters = I->multi_iters2 = I->multi_iters3 = NULL; + I->multi_outputs = I->multi_outputs2 = NULL; + I->multi_solutions = I->multi_solutions2 = NULL; + I->multi_fp = NULL; + + I->multi_core = 0; +} + + +/* second initialization + topk.end>0 => initialize heap for topk mining */ +/* all pointers will be set to 0, but not for */ +/* if topK mining, set topk.end to "K" */ +void ITEMSET_alloc (ITEMSET *I, char *fname, PERM *perm, QUEUE_INT item_max, size_t item_max_org){ + LONG i; + size_t siz = (I->flag&ITEMSET_USE_ORG)?item_max_org+2: item_max+2; + int j; + + I->prob = I->ratio = 1.0; + I->frq = 0; + I->perm = perm; + if ( I->topk.end>0 ){ + AHEAP_alloc (&I->topk, I->topk.end); + FLOOP (i, 0, I->topk.end) AHEAP_chg (&I->topk, (AHEAP_ID)i, -WEIGHTHUGE); + I->frq_lb = -WEIGHTHUGE; + } else I->topk.v = NULL; + QUEUE_alloc (&I->itemset, (QUEUE_ID)siz); I->itemset.end = (QUEUE_ID)siz; + if ( I->flag&ITEMSET_ADD ) QUEUE_alloc (&I->add, (QUEUE_ID)siz); + calloc2 (I->sc, siz+2, goto ERR); + if ( I->flag&ITEMSET_SET_RULE ){ + calloc2 (I->set_weight, siz, goto ERR); + if ( I->flag&(ITEMSET_TRSACT_ID+ITEMSET_MULTI_OCC_PRINT) ) + calloc2 (I->set_occ, siz, goto ERR); + } + I->iters = I->iters2 = I->solutions = 0; + I->item_max = item_max; + I->item_max_org = (QUEUE_INT)item_max_org; + if ( fname ){ + if ( strcmp (fname, "-") == 0 ) I->fp = stdout; + else fopen2 (I->fp, fname, (I->flag&ITEMSET_APPEND)?"a":"w", goto ERR); + } else I->fp = 0; + if ( I->flag&ITEMSET_ITEMFRQ ) + malloc2 (I->item_frq, item_max+2, goto ERR); + if ( I->flag&ITEMSET_RULE ){ + calloc2 (I->itemflag, item_max+2, goto ERR); + } + I->total_weight = 1; + j = MAX(I->multi_core,1); + calloc2 (I->multi_iters, j*7, goto ERR); + I->multi_iters2 = I->multi_iters + j; + I->multi_iters3 = I->multi_iters2 + j; + I->multi_outputs = I->multi_iters3 + j; + I->multi_outputs2 = I->multi_outputs + j; + I->multi_solutions = I->multi_outputs2 + j; + I->multi_solutions2 = I->multi_solutions + j; + + malloc2 (I->multi_fp, j, goto ERR); + FLOOP (i, 0, j) + FILE2_open_ (I->multi_fp[i], I->fp, goto ERR); +#ifdef MULTI_CORE + if ( I->multi_core > 0 ){ + pthread_spin_init (&I->lock_counter, PTHREAD_PROCESS_PRIVATE); + pthread_spin_init (&I->lock_sc, PTHREAD_PROCESS_PRIVATE); + pthread_spin_init (&I->lock_output, PTHREAD_PROCESS_PRIVATE); + } +#endif + return; + ERR:; + ITEMSET_end (I); + EXIT; +} + +/* sum the counters computed by each thread */ +void ITEMSET_merge_counters (ITEMSET *I){ + int i; + FLOOP (i, 0, MAX(I->multi_core,1)){ + I->iters += I->multi_iters[i]; + I->iters2 += I->multi_iters2[i]; + I->iters3 += I->multi_iters3[i]; + I->outputs += I->multi_outputs[i]; + I->outputs2 += I->multi_outputs2[i]; + I->solutions += I->multi_solutions[i]; + I->solutions2 += I->multi_solutions2[i]; + if ( I->multi_fp[i].buf ) FILE2_flush_last (&I->multi_fp[i]); + } + ARY_FILL (I->multi_iters, 0, MAX(I->multi_core,1)*7, 0); +} + +/*******************************************************************/ +/* termination of ITEMSET */ +/*******************************************************************/ +void ITEMSET_end (ITEMSET *I){ + int i; + QUEUE_end (&I->itemset); + QUEUE_end (&I->add); + AHEAP_end (&I->topk); + fclose2 (I->fp); + mfree (I->sc, I->item_frq, I->itemflag, I->perm, I->set_weight, I->set_occ); + + if ( I->multi_fp ) + FLOOP (i, 0, MAX(I->multi_core,1)) free2 (I->multi_fp[i].buf); + mfree (I->multi_iters, I->multi_fp); +#ifdef MULTI_CORE + if ( I->multi_core>0 ){ + pthread_spin_destroy(&I->lock_counter); + pthread_spin_destroy(&I->lock_sc); + pthread_spin_destroy(&I->lock_output); + } +#endif + ITEMSET_init (I); +} + +/*******************************************************************/ +/* output at the termination of the algorithm */ +/* print #of itemsets of size k, for each k */ +/*******************************************************************/ +void ITEMSET_last_output (ITEMSET *I){ + QUEUE_ID i; + LONG n=0, nn=0; + + ITEMSET_merge_counters (I); + if ( !(I->flag&SHOW_MESSAGE) ) return; // "no message" is specified + if ( I->topk.end > 0 ){ + i = AHEAP_findmin_head (&I->topk); + fprint_WEIGHT (stdout, AHEAP_H (I->topk, i)); + printf ("\n"); + return; + } + FLOOP (i, 0, I->itemset.end+1){ + n += I->sc[i]; + if ( I->sc[i] != 0 ) nn = i; + } + if ( n!=0 ){ + printf (LONGF "\n", n); + FLOOP (i, 0, nn+1) printf (LONGF "\n", I->sc[i]); + } + print_err ("iters=" LONGF, I->iters); + if ( I->flag&ITEMSET_ITERS2 ) print_err (", iters2=" LONGF, I->iters2); + print_err ("\n"); +} + +/* output frequency, coverage */ +void ITEMSET_output_frequency (ITEMSET *I, int core_id){ + FILE2 *fp = &I->multi_fp[core_id]; + if ( I->flag&(ITEMSET_FREQ+ITEMSET_PRE_FREQ) ){ + if ( I->flag&ITEMSET_FREQ ) FILE2_putc (fp, ' '); + FILE2_print_WEIGHT (fp, I->frq, 4, '('); + FILE2_putc (fp, ')'); + if ( I->flag&ITEMSET_PRE_FREQ ) FILE2_putc (fp, ' '); + } + if ( I->flag&ITEMSET_OUTPUT_POSINEGA ){ // output positive sum, negative sum in the occurrence + FILE2_putc (fp, ' '); + FILE2_print_WEIGHT (fp, I->pfrq, 4, '('); + FILE2_print_WEIGHT (fp, I->pfrq-I->frq, 4, ','); + FILE2_print_WEIGHT (fp, I->pfrq/(2*I->pfrq-I->frq), 4, ','); + FILE2_putc (fp, ')'); + } +} + +#ifdef _trsact_h_ +void ITEMSET_output_occ (ITEMSET *I, QUEUE *occ, int core_id){ + QUEUE_ID i; + QUEUE_INT *x; + FILE2 *fp = &I->multi_fp[core_id]; + TRSACT *TT = (TRSACT *)(I->X); + VEC_ID j, ee = TT->rows_org; + int flag = I->flag&(ITEMSET_TRSACT_ID+ITEMSET_MULTI_OCC_PRINT); + + i=0; MQUE_FLOOP_ (*occ, x, TT->occ_unit){ + if ( (I->flag&ITEMSET_RM_DUP_TRSACT)==0 || *x != ee ){ + FILE2_print_int (fp, TT->trperm? TT->trperm[*x]: *x, I->separator); + if (flag == ITEMSET_MULTI_OCC_PRINT ){ + FLOOP (j, 1, (VEC_ID)(TT->occ_unit/sizeof(QUEUE_INT))) + FILE2_print_int (fp, *(x+j), I->separator); + } else if ( flag == (ITEMSET_MULTI_OCC_PRINT+ITEMSET_TRSACT_ID) ){ + FILE2_print_int (fp, *(x+1), I->separator); + } + } + ee = *x; + if ( (++i)%256==0 ) ITEMSET_flush (I, fp); + } + FILE2_putc (fp, '\n'); +} +#endif + +/* output an itemset to the output file */ +void ITEMSET_output_itemset (ITEMSET *I, QUEUE *occ, int core_id){ + QUEUE_ID i; + QUEUE_INT e; +#ifdef _agraph_h_ + QUEUE_INT ee; +#endif + + FILE2 *fp = &I->multi_fp[core_id]; + + I->multi_outputs[core_id]++; + if ( (I->flag&SHOW_PROGRESS ) && (I->multi_outputs[core_id]%(ITEMSET_INTERVAL) == 0) ) + print_err ("---- " LONGF " solutions in " LONGF " candidates\n", + I->multi_solutions[core_id], I->multi_outputs[core_id]); + if ( I->itemset.t < I->lb || I->itemset.t > I->ub ) return; + if ( (I->flag&ITEMSET_IGNORE_BOUND)==0 && (I->frq < I->frq_lb || I->frq > I->frq_ub) ) return; + if ( (I->flag&ITEMSET_IGNORE_BOUND)==0 && (I->pfrq < I->posi_lb || I->pfrq > I->posi_ub || (I->frq - I->pfrq) > I->nega_ub || (I->frq - I->pfrq) < I->nega_lb) ) return; + + I->multi_solutions[core_id]++; + if ( I->max_solutions>0 && I->multi_solutions[core_id] > I->max_solutions ){ + ITEMSET_last_output (I); + ERROR_MES = "reached to maximum number of solutions"; + EXIT; + } + if ( I->topk.v ){ + e = AHEAP_findmin_head (&(I->topk)); + if ( I->frq > AHEAP_H (I->topk, e) ){ + AHEAP_chg (&(I->topk), e, I->frq); + e = AHEAP_findmin_head (&(I->topk)); + I->frq_lb = AHEAP_H (I->topk, e); + } + } else if ( I->fp ){ + if ( I->flag&ITEMSET_PRE_FREQ ) ITEMSET_output_frequency (I, core_id); + if ( (I->flag & ITEMSET_NOT_ITEMSET) == 0 ){ +#ifdef _agraph_h_ + if ( I->flag&ITEMSET_OUTPUT_EDGE ){ + FLOOP (i, 0, I->itemset.t){ + e = I->itemset.v[i]; + ee = AGRAPH_INC_FROM(*((AGRAPH *)(I->X)), e, I->dir); + FILE2_print_int (fp, I->perm? I->perm[ee]: ee, '(' ); + ee = AGRAPH_INC_TO(*((AGRAPH *)(I->X)), e, I->dir); + FILE2_print_int (fp, I->perm? I->perm[ee]: ee, I->separator); + FILE2_putc (fp, ')'); + if ( iitemset.t-1 ) FILE2_putc (fp, I->separator); + if ( (i+1)%256==0 ) ITEMSET_flush (I, fp); + } + goto NEXT; + } +#endif + FLOOP (i, 0, I->itemset.t){ + e = I->itemset.v[i]; + FILE2_print_int (fp, I->perm? I->perm[e]: e, i==0? 0: I->separator); + if ( (i+1)%256==0 ) ITEMSET_flush (I, fp); + } +#ifdef _agraph_h_ + NEXT:; +#endif + } + if ( !(I->flag&ITEMSET_PRE_FREQ) ) ITEMSET_output_frequency (I, core_id); + if ( ((I->flag & ITEMSET_NOT_ITEMSET) == 0) || (I->flag&ITEMSET_FREQ) || (I->flag&ITEMSET_PRE_FREQ) ) FILE2_putc (fp, '\n'); + +#ifdef _trsact_h_ + if (I->flag&(ITEMSET_TRSACT_ID+ITEMSET_MULTI_OCC_PRINT)) ITEMSET_output_occ (I, occ, core_id); +#endif + } + I->sc[I->itemset.t]++; + ITEMSET_flush (I, fp); +} + +/* output itemsets with adding all combination of "add" + at the first call, i has to be "add->t" */ +void ITEMSET_solution_iter (ITEMSET *I, QUEUE *occ, int core_id){ + QUEUE_ID t=I->add.t; + if ( I->itemset.t > I->ub ) return; + ITEMSET_output_itemset (I, occ, core_id); +if ( ERROR_MES ) return; + BLOOP (I->add.t, I->add.t, 0){ + QUE_INS (I->itemset, I->add.v[I->add.t]); + ITEMSET_solution_iter (I, occ, core_id); +if ( ERROR_MES ) return; + I->itemset.t--; + } + I->add.t = t; +} + +void ITEMSET_solution (ITEMSET *I, QUEUE *occ, int core_id){ + QUEUE_ID i; + LONG s; + if ( I->itemset.t > I->ub ) return; + if ( I->flag & ITEMSET_ALL ){ + if ( I->fp || I->topk.v ) ITEMSET_solution_iter (I, occ, core_id); + else { + s=1; FLOOP (i, 0, I->add.t+1){ + I->sc[I->itemset.t+i] += s; + s = s*(I->add.t-i)/(i+1); + } + } + } else { + FLOOP (i, 0, I->add.t) QUE_INS (I->itemset, I->add.v[i]); + ITEMSET_output_itemset (I, occ, core_id); + I->itemset.t -= I->add.t; + } +} + +/*************************************************************************/ +/* ourput a rule */ +/*************************************************************************/ +void ITEMSET_output_rule (ITEMSET *I, QUEUE *occ, double p1, double p2, size_t item, int core_id){ + FILE2 *fp = &I->multi_fp[core_id]; + if ( fp->fp && !(I->topk.v) ){ + FILE2_print_real (fp, p1, 4, '('); + FILE2_print_real (fp, p2, 4, ','); + FILE2_putc (fp, ')'); + FILE2_print_int (fp, I->perm[item], I->separator); + FILE2_puts (fp, " <= "); + } + if ( I->flag & ITEMSET_RULE ){ + if ( I->flag & ITEMSET_RULE_ADD ) ITEMSET_solution (I, occ, core_id); + else ITEMSET_output_itemset (I, occ, core_id); + } else ITEMSET_solution (I, occ, core_id); +} +/*************************************************************************/ +/* check all rules for a pair of itemset and item */ +/*************************************************************************/ +void ITEMSET_check_rule (ITEMSET *I, WEIGHT *w, QUEUE *occ, size_t item, int core_id){ + double p = w[item]/I->frq, pp, ff; +// printf ("[ratio] %f, p=%f, (%f/ %f), %d(%d) <= ", I->ratio_lb, p, w[item], I->frq, I->perm[item], I->itemflag[item]); + if ( I->itemflag[item]==1 ) return; + if ( w[item] <= -WEIGHTHUGE ) p = 0; + pp = p; ff = I->item_frq[item]; + if ( I->flag & ITEMSET_RULE_SUPP ){ pp = w[item]; ff *= I->total_weight; } + + if ( I->flag & (ITEMSET_RULE_FRQ+ITEMSET_RULE_INFRQ)){ + if ( (I->flag & ITEMSET_RULE_FRQ) && p < I->ratio_lb ) return; + if ( (I->flag & ITEMSET_RULE_INFRQ) && p > I->ratio_ub ) return; + ITEMSET_output_rule (I, occ, p, ff, item, core_id); + } else if ( I->flag & (ITEMSET_RULE_RFRQ+ITEMSET_RULE_RINFRQ) ){ + if ( (I->flag & ITEMSET_RULE_RFRQ) && (1-p) > I->ratio_lb * (1-I->item_frq[item]) ) return; + if ( (I->flag & ITEMSET_RULE_RINFRQ) && p > I->ratio_ub * I->item_frq[item] ) return; + ITEMSET_output_rule (I, occ, pp, ff, item, core_id); + } +} + +/*************************************************************************/ +/* check all rules for an itemset and all items */ +/*************************************************************************/ +void ITEMSET_check_all_rule (ITEMSET *I, WEIGHT *w, QUEUE *occ, QUEUE *jump, WEIGHT total, int core_id){ + QUEUE_ID i, t; + QUEUE_INT e, f=0, *x; + WEIGHT d = I->frq/total; + + // checking out of range for itemset size and (posi/nega) frequency + if ( I->itemset.t+I->add.t < I->lb || I->itemset.t>I->ub || (!(I->flag&ITEMSET_ALL) && I->itemset.t+I->add.t>I->ub)) return; + if ( !(I->flag&ITEMSET_IGNORE_BOUND) && (I->frq < I->frq_lb || I->frq > I->frq_ub) ) return; + if ( !(I->flag&ITEMSET_IGNORE_BOUND) && (I->pfrq < I->posi_lb || I->pfrq > I->posi_ub || (I->frq - I->pfrq) > I->nega_ub || (I->frq - I->pfrq) < I->nega_lb) ) return; + + if ( I->flag&ITEMSET_SET_RULE ){ // itemset->itemset rule for sequence mining + FLOOP (i, 0, I->itemset.t-1){ + if ( I->frq/I->set_weight[i] >= I->setrule_lb && I->fp ){ + I->sc[i]++; + if ( I->flag&ITEMSET_PRE_FREQ ) ITEMSET_output_frequency (I, core_id); + FLOOP (t, 0, I->itemset.t){ + FILE2_print_int (&I->multi_fp[core_id], I->itemset.v[t], t?I->separator:0); + if ( t == i ){ + FILE2_putc (&I->multi_fp[core_id], ' '); + FILE2_putc (&I->multi_fp[core_id], '='); + FILE2_putc (&I->multi_fp[core_id], '>'); + } + } + if ( !(I->flag&ITEMSET_PRE_FREQ) ) ITEMSET_output_frequency ( I, core_id); + FILE2_putc (&I->multi_fp[core_id], ' '); + FILE2_print_real (&I->multi_fp[core_id], I->frq/I->set_weight[i], 4, '('); + FILE2_putc (&I->multi_fp[core_id], ')'); + FILE2_putc (&I->multi_fp[core_id], '\n'); +#ifdef _trsact_h_ + if ( I->flag&(ITEMSET_TRSACT_ID+ITEMSET_MULTI_OCC_PRINT) ){ + ITEMSET_output_occ (I, I->set_occ[i], core_id); + } +#endif + ITEMSET_flush (I, &I->multi_fp[core_id]); + } + } + } + // constraint of relational frequency + if ( ((I->flag&ITEMSET_RFRQ)==0 || d >= I->prob_lb * I->prob ) + && ((I->flag&ITEMSET_RINFRQ)==0 || d <= I->prob * I->prob_ub) ){ + if ( I->flag&ITEMSET_RULE ){ // rule mining routines + if ( I->itemset.t == 0 ) return; + if ( I->target < I->item_max ){ + MQUE_FLOOP (*jump, x){ + if ( *x == I->target ){ + ITEMSET_check_rule (I, w, occ, *x, core_id); if (ERROR_MES) return; + } + } +// ITEMSET_check_rule (I, w, occ, I->target, core_id); if (ERROR_MES) return; + } else { + if ( I->flag & (ITEMSET_RULE_FRQ + ITEMSET_RULE_RFRQ) ){ + if ( I->add.t>0 ){ +// if ( I->itemflag[I->add.v[0]] ) // for POSI_EQUISUPP (occ_w[e] may not be 100%, in the case) + f = I->add.v[I->add.t-1]; t = I->add.t; I->add.t--; + FLOOP (i, 0, t){ + e = I->add.v[i]; + I->add.v[i] = f; + ITEMSET_check_rule (I, w, occ, e, core_id); if (ERROR_MES) return; + I->add.v[i] = e; + } + I->add.t++; + } + MQUE_FLOOP (*jump, x) + ITEMSET_check_rule (I, w, occ, *x, core_id); if (ERROR_MES) return; + } else { + if ( I->flag & (ITEMSET_RULE_INFRQ + ITEMSET_RULE_RINFRQ) ){ +// ARY_FLOOP ( *jump, i, e ) I->itemflag[e]--; + FLOOP (i, 0, I->item_max){ + if ( I->itemflag[i] != 1 ){ + ITEMSET_check_rule (I, w, occ, i, core_id); if (ERROR_MES) return; + } + } +// ARY_FLOOP ( *jump, i, e ) I->itemflag[e]++; +// } +// ARY_FLOOP ( *jump, i, e ) ITEMSET_check_rule (I, w, occ, e); + } + } + } + } else { // usual mining (not rule mining) + if ( I->fp && (I->flag&(ITEMSET_RFRQ+ITEMSET_RINFRQ))){ + FILE2_print_real (&I->multi_fp[core_id], d, 4, '['); + FILE2_print_real (&I->multi_fp[core_id], I->prob, 4, ','); + FILE2_putc (&I->multi_fp[core_id], ']'); + } + ITEMSET_solution (I, occ, core_id); + } + } +} + +#endif diff --git a/rql-backend/shd31/itemset.h b/rql-backend/shd31/itemset.h new file mode 100644 index 0000000..0611242 --- /dev/null +++ b/rql-backend/shd31/itemset.h @@ -0,0 +1,157 @@ +/* itemset search input/output common routines + 25/Nov/2007 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +/* routines for itemset mining */ + +#ifndef _itemset_h_ +#define _itemset_h_ + +#include"stdlib2.h" +#include"queue.h" +#define AHEAP_KEY_WEIGHT +#include"aheap.h" + + +typedef struct { + int a; + QUEUE itemset; // current operating itemset + QUEUE add; // for equisupport (hypercube decomposition) + int ub, lb; // upper/lower bounds for the itemset size + WEIGHT frq, pfrq, frq_ub, frq_lb; // upper/lower bounds for the frequency + WEIGHT rposi_lb, rposi_ub, posi_lb, posi_ub, nega_ub, nega_lb; // upper/lower bounds for the sum of positive/negative weights + WEIGHT setrule_lb; // frequency lower bound for set rule + double ratio, prob; // confidence and independent probability of the current pattern + double ratio_ub, ratio_lb, prob_ub, prob_lb; // upper/lower bounds for confidence and independent probability + QUEUE_INT target; // target item for rule mining + char *itemflag; // 1 if it is include in the pattern (and 2 if included in add) + WEIGHT *item_frq; // frequency of each item + WEIGHT total_weight; // total weight of the input database + int len_ub, len_lb; // upper/lower bounds for the length of the pattern + int gap_ub, gap_lb; // upper/lower bounds for the gaps in the pattern + LONG *sc; // #itemsets classified by the sizes + QUEUE_INT item_max, item_max_org; // (original) maximum item + AHEAP topk; // heap for topk mining. valid if topk->h is not NULL + int flag; // flag for various functions + PERM *perm; // permutation array for output itemset: item => original item + FILE *fp; // file pointer to the output file + char separator; // separator of items output + int progress; + LONG iters, iters2, iters3; //iterations + LONG solutions, solutions2; // number of solutions output + LONG outputs, outputs2; // #calls of ITEMSET_output_itemset or ITEMSET_solusion + LONG max_solutions; // maximum solutions to be output + void *X; // pointer to the original data + int dir; // direction flag for AGRAPH & SGRAPH + + int multi_core; // number of processors + LONG *multi_iters, *multi_iters2, *multi_iters3; //iterations + LONG *multi_solutions, *multi_solutions2; // number of solutions output + LONG *multi_outputs, *multi_outputs2; // #calls of ITEMSET_output_itemset or ITEMSET_solusion + FILE2 *multi_fp; // output file2 pointer for multi-core mode + WEIGHT *set_weight; // the frequency of each prefix of current itemset + QUEUE **set_occ; // the occurrence of each prefix of current itemset + +#ifdef MULTI_CORE + pthread_spinlock_t lock_counter; // couneter locker for jump counter + pthread_spinlock_t lock_sc; // couneter locker for score counter + pthread_spinlock_t lock_output; // couneter locker for #output +#endif +} ITEMSET; + +/* parameters for ITEMSET.flag */ + +#define ITEMSET_ITERS2 4 // output #iters2 +#define ITEMSET_PRE_FREQ 8 // output frequency preceding to each itemset +#define ITEMSET_FREQ 16 // output frequency following to each itemset +#define ITEMSET_ALL 32 // concat all combinations of "add" to each itemset + +#define ITEMSET_TRSACT_ID 64 // output transaction ID's in occurrences +#define ITEMSET_OUTPUT_EDGE 128 // output itemset as edge set (refer AGRAPH) +#define ITEMSET_IGNORE_BOUND 256 // ignore constraint for frequency +#define ITEMSET_RM_DUP_TRSACT 512 // remove duplicated transaction ID's +#define ITEMSET_MULTI_OCC_PRINT 1024 //print each component of occ + // TRSACT_ID+MULTI_OCC_PRINT means print first two components of occ +#define ITEMSET_NOT_ITEMSET 2048 // do not print itemset to the output file +#define ITEMSET_RULE_SUPP 4096 // output confidence and item frquency by abusolute value +#define ITEMSET_OUTPUT_POSINEGA 8192 // output negative/positive frequencies +#define ITEMSET_MULTI_OUTPUT 16384 // for multi-core mode +#define ITEMSET_USE_ORG 32768 // use item_max_org to the size of use +#define ITEMSET_ITEMFRQ 65536 // allocate item_frq +#define ITEMSET_ADD 131072 // allocate add + +#define ITEMSET_RULE_FRQ 262144 +#define ITEMSET_RULE_INFRQ 524288 +#define ITEMSET_RULE_RFRQ 1048576 +#define ITEMSET_RULE_RINFRQ 2097152 +#define ITEMSET_RFRQ 4194304 +#define ITEMSET_RINFRQ 8388608 +#define ITEMSET_POSI_RATIO 16777216 +#define ITEMSET_SET_RULE 134217728 + +#define ITEMSET_APPEND 268435456 // append the output to the fiile +#define ITEMSET_RULE_ADD 536870912 // append items in add to the solution, for rule output + +//#define ITEMSET_RULE (ITEMSET_RULE_FRQ + ITEMSET_RULE_INFRQ + ITEMSET_RULE_RFRQ + ITEMSET_RULE_RINFRQ + ITEMSET_RFRQ + ITEMSET_RINFRQ + ITEMSET_SET_RULE) // for check any rule is true +#define ITEMSET_RULE (ITEMSET_RULE_FRQ + ITEMSET_RULE_INFRQ + ITEMSET_RULE_RFRQ + ITEMSET_RULE_RINFRQ + ITEMSET_SET_RULE) // for check any rule is true + +#ifndef ITEMSET_INTERVAL +#define ITEMSET_INTERVAL 500000 +#endif + +/* Output information about ITEMSET structure. flag&1: print frequency constraint */ +void ITEMSET_print (ITEMSET *II, int flag); + +/* topk.end>0 => initialize heap for topk mining */ +/* all pointers will be set to 0, but not for */ +/* if topK mining, set topk.end to "K" */ +void ITEMSET_init (ITEMSET *I); +void ITEMSET_alloc (ITEMSET *I, char *fname, PERM *perm, QUEUE_INT item_max, size_t item_max_org); +void ITEMSET_end (ITEMSET *I); + +/* sum the counters computed by each thread */ +void ITEMSET_merge_counters (ITEMSET *I); + +/*******************************************************************/ +/* output at the termination of the algorithm */ +/* print #of itemsets of size k, for each k */ +/*******************************************************************/ +void ITEMSET_last_output (ITEMSET *I); + +/* output frequency, coverage */ +void ITEMSET_output_frequency (ITEMSET *I, int core_id); + +/* output an itemset to the output file */ +void ITEMSET_output_itemset (ITEMSET *I, QUEUE *occ, int core_id); + +/* output itemsets with adding all combination of "add" + at the first call, i has to be "add->t" */ +void ITEMSET_solution (ITEMSET *I, QUEUE *occ, int core_id); + +/*************************************************************************/ +/* ourput a rule */ +/*************************************************************************/ +void ITEMSET_output_rule (ITEMSET *I, QUEUE *occ, double p1, double p2, size_t item, int core_id); + +/*************************************************************************/ +/* check all rules for a pair of itemset and item */ +/*************************************************************************/ +void ITEMSET_check_rule (ITEMSET *I, WEIGHT *w, QUEUE *occ, size_t item, int core_id); + +/*************************************************************************/ +/* check all rules for an itemset and all items */ +/*************************************************************************/ +void ITEMSET_check_all_rule (ITEMSET *I, WEIGHT *w, QUEUE *occ, QUEUE *jump, WEIGHT total, int core_id); + +#endif + + + + diff --git a/rql-backend/shd31/makefile b/rql-backend/shd31/makefile new file mode 100644 index 0000000..3853521 --- /dev/null +++ b/rql-backend/shd31/makefile @@ -0,0 +1,2 @@ +SHD: shd.c problem.c itemset.c queue.c aheap.c stdlib2.c undo.c alist.c base.c vec.c + gcc -O3 -Os -s -o shd shd.c diff --git a/rql-backend/shd31/problem.c b/rql-backend/shd31/problem.c new file mode 100644 index 0000000..8bae8b8 --- /dev/null +++ b/rql-backend/shd31/problem.c @@ -0,0 +1,350 @@ +/* Common problem input/output routines /structure + 25/Nov/2007 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +/***************************************************/ + +#ifndef _problem_c_ +#define _problem_c_ + +#include"problem.h" + +#include"stdlib2.c" +#include"queue.c" +#include"itemset.c" + +void PROBLEM_error (){ + ERROR_MES = "command explanation"; + EXIT; +} + +/*************************************************************************/ +/* PROBLEM and ITEMSET initialization */ +/*************************************************************************/ +void PROBLEM_init (PROBLEM *P){ + P->start_time = clock(); + RAND_INIT; + ERROR_MES = NULL; + + P->problem = P->problem2 = 0; + P->prog = 0; + P->prog2 = 0; + P->input_fname = P->input_fname2 = P->output_fname = P->output_fname2 = NULL; + P->workdir = P->workdir2 = NULL; + P->weight_fname = P->header_fname = P->table_fname = P->sc_fname = NULL; + P->position_fname = P->position2_fname = NULL; + P->outperm_fname = NULL; + + P->root = 0; + P->dir = P->edge_dir = 0; + P->th = P->th2 = P->th3 = 0; + P->ratio = P->ratio2 = 0; + P->num = P->siz = P->dim = P->len = P->width = P->height = 0; + P->rows = 0; + P->clms = 0; + P->gap_ub = INTHUGE; + P->gap_lb = 0; + P->xmax = P->ymax = P->pxmax = P->pymax = 0; + P->cost = P->cost2 = 0; + + ITEMSET_init (&P->II); + ITEMSET_init (&P->II2); + + P->vf = P->dep = NULL; + P->ff = INIT_QUEUE; + + P->shift = NULL; + P->occ_w = P->occ_pw = P->occ_w2 = P->occ_pw2 = NULL; + P->buf = P->buf_org = NULL; + P->buf_end = 0; + + P->itemjump = P->itemcand = P->vecjump = P->veccand = INIT_QUEUE; // for delivery + P->itemchr = P->vecchr = NULL; + P->OQ = P->OQ2 = P->VQ = P->VQ2 = NULL; // for delivery + P->itemary = NULL; + P->itemmark = P->itemflag = P->vecmark = P->vecflag = NULL; // mark for vector + P->occ_t = P->vecary = NULL; + P->oo = INIT_QUEUE; + P->vecw = NULL; + + P->pat = NULL; + P->plen = P->perr = 0; + +#ifdef _base_h_ + P->B = INIT_BASE; +#endif + +#ifdef _alist_h_ + P->occ = INIT_MALIST; + P->itemlist = INIT_ALIST; + P->veclist = INIT_ALIST; +#endif + +#ifdef _trsact_h_ + TRSACT_init (&P->TT); + TRSACT_init (&P->TT2); +#endif +#ifdef _sgraph_h_ + P->SG = INIT_SGRAPH; + P->SG2 = INIT_SGRAPH; +#endif +#ifdef _agraph_h_ + P->AG = INIT_AGRAPH; + P->AG2 = INIT_AGRAPH; +#endif +#ifdef _seq_h_ + SEQ_init (&P->SS); + SEQ_init (&P->SS2); +#endif +#ifdef _pos_h_ + POS_init (&P->PS); + POS_init (&P->PS2); + P->PS.S = &P->SS; + P->PS2.S = &P->SS2; + P->PS.I = &P->II; + P->PS2.I = &P->II; +#endif +#ifdef _fstar_h_ + P->FS = INIT_FSTAR; + P->FS2 = INIT_FSTAR; +#endif + +#ifdef _vec_h_ + P->MM = INIT_MAT; + P->MM2 = INIT_MAT; + P->SM = INIT_SMAT; + P->SM2 = INIT_SMAT; + P->FF = INIT_SETFAMILY; + P->FF2 = INIT_SETFAMILY; +#endif + +#ifdef _barray_h_ + P->BA = INIT_BARRAY; + P->BA2 = INIT_BARRAY; +#endif +} + +/*************************************************************************/ +/* PROBLEM load */ +/*************************************************************************/ +void PROBLEM_load (PROBLEM *P){ + int f=0; + ITEMSET *II = &P->II; +/******************************/ +#ifdef _trsact_h_ + if ( P->TT.fname ){ TRSACT_load (&P->TT); if (ERROR_MES) goto ERR; } + if ( P->TT2.fname ){ TRSACT_load (&P->TT2); if (ERROR_MES) goto ERR; } +#endif +#ifdef _sgraph_h_ + if ( P->SG.fname ){ SGRAPH_load (&P->SG); if (ERROR_MES) goto ERR; } + if ( P->SG2.fname ){ SGRAPH_load (&P->SG); if (ERROR_MES) goto ERR; } +#endif +#ifdef _agraph_h_ + if ( P->AG.fname ){ AGRAPH_load (&P->AG); if (ERROR_MES) goto ERR;} + if ( P->AG2.fname ){ AGRAPH_load (&P->AG2); if (ERROR_MES) goto ERR; } +#endif +#ifdef _fstar_h_ + if ( P->FS.fname ){ FSTAR_load (&P->FS); if (ERROR_MES) goto ERR; } + if ( P->FS2.fname ){ FSTAR_load (&P->FS2); if (ERROR_MES) goto ERR; } +#endif +#ifdef _vec_h_ + if ( P->MM.fname ){ MAT_load (&P->MM); if (ERROR_MES) goto ERR; } + if ( P->MM2.fname ){ MAT_load (&P->MM2); if (ERROR_MES) goto ERR; } + if ( P->SM.fname ){ SMAT_load (&P->SM); if (ERROR_MES) goto ERR; } + if ( P->SM2.fname ){ SMAT_load (&P->SM2); if (ERROR_MES) goto ERR; } + if ( P->FF.fname ){ SETFAMILY_load (&P->FF); if (ERROR_MES) goto ERR; } + if ( P->FF2.fname ){ SETFAMILY_load (&P->FF2); if (ERROR_MES) goto ERR; } + if ( P->FF.wfname ){ SETFAMILY_load_weight (&P->FF); if (ERROR_MES) goto ERR; } + if ( P->FF2.wfname ){ SETFAMILY_load_weight (&P->FF2); if (ERROR_MES) goto ERR; } + if ( P->FF.cwfname ){ SETFAMILY_load_column_weight (&P->FF); if (ERROR_MES) goto ERR; } + if ( P->FF2.cwfname ){ SETFAMILY_load_column_weight (&P->FF2); if (ERROR_MES) goto ERR; } + if ( P->FF.rwfname ){ SETFAMILY_load_row_weight (&P->FF); if (ERROR_MES) goto ERR; } + if ( P->FF2.rwfname ){ SETFAMILY_load_row_weight (&P->FF2); if (ERROR_MES) goto ERR; } +#endif +#ifdef _seq_h_ + if ( P->SS.fname ){ SEQ_load (&P->SS); if (ERROR_MES) goto ERR; } + if ( P->SS2.fname ){ SEQ_load (&P->SS2); if (ERROR_MES) goto ERR; } +#endif +#ifdef _barray_h_ + if ( P->BA.fname ){ BARRAY_load (&P->BA); if (ERROR_MES) goto ERR; } + if ( P->BA2.fname ){ BARRAY_load (&P->BA2); if (ERROR_MES) goto ERR; } +#endif + if (P->input_fname){ f=1; print_mes (II, " input: %s", P->input_fname); } + if (P->weight_fname){ f=1; print_mes (II, " weight: %s", P->weight_fname); } + if (P->output_fname){ f=1; print_mes (II, " output to: %s",P->output_fname); } + if ( f ) print_mes (II, "\n"); + +/******************************/ + + if ( !ERROR_MES ) return; + ERR:; + PROBLEM_end (P); + EXIT; +} + +/* termination of problem */ +void PROBLEM_end (PROBLEM *P){ + ITEMSET *II = &P->II; + +#ifdef _trsact_h_ + TRSACT_end (&P->TT); + TRSACT_end (&P->TT2); +#endif +#ifdef _sgraph_h_ + SGRAPH_end (&P->SG); + SGRAPH_end (&P->SG2); +#endif +#ifdef _agraph_h_ + AGRAPH_end (&P->AG); + AGRAPH_end (&P->AG2); +#endif +#ifdef _seq_h_ + SEQ_end (&P->SS); + SEQ_end (&P->SS2); +#endif +#ifdef _fstar_h_ + FSTAR_end (&P->FS); + FSTAR_end (&P->FS2); +#endif +#ifdef _vec_h_ + MAT_end (&P->MM); + MAT_end (&P->MM2); + SMAT_end (&P->SM); + SMAT_end (&P->SM2); + SETFAMILY_end (&P->FF); + SETFAMILY_end (&P->FF2); +#endif +#ifdef _pos_h_ + POS_end (&P->PS); + POS_end (&P->PS2); +#endif +#ifdef _barray_h_ + BARRAY_end (&P->BA); + BARRAY_end (&P->BA2); +#endif + +/******************************/ + + mfree (P->vf, P->dep); + QUEUE_end (&P->ff); + + ITEMSET_end (II); + ITEMSET_end (&P->II2); + + if ( P->occ_pw2 != P->occ_pw && P->occ_pw2 != P->occ_w2 ) free2 (P->occ_pw2); + if ( P->occ_w2 != P->occ_w ) free2 (P->occ_w2); + if ( P->occ_pw != P->occ_w ) free2 (P->occ_pw); + mfree (P->shift, P->occ_t, P->occ_w); + + if ( P->OQ ) free2 (P->OQ[0].v); + if ( P->OQ2 ) free2 (P->OQ2[0].v); + if ( P->VQ ) free2 (P->VQ[0].v); + if ( P->VQ2 ) free2 (P->VQ2[0].v); + mfree (P->OQ, P->OQ2, P->VQ, P->VQ2, P->itemchr, P->vecchr); + + mfree (P->itemary, P->itemflag, P->itemmark, P->vecary, P->vecflag, P->vecmark, P->vecw); + QUEUE_end (&P->itemcand); + QUEUE_end (&P->itemjump); + + QUEUE_end (&P->veccand); + QUEUE_end (&P->vecjump); + QUEUE_end (&P->oo); + + free2 (P->buf_org); + +#ifdef _alist_h_ + MALIST_end (&P->occ); + ALIST_end (&P->itemlist); + ALIST_end (&P->veclist); +#endif + +#ifdef _undo_h_ + ALISTundo_end (); +#endif + + P->end_time = clock(); + if ( print_time_flag ) + print_mes (II, "computation_time= %3f\n", ((double)(P->end_time-P->start_time))/CLOCKS_PER_SEC); + + PROBLEM_init (P); +} + +/* allocate arrays and structures */ +void PROBLEM_alloc (PROBLEM *P, QUEUE_ID siz, QUEUE_ID siz2, size_t siz3, PERM *perm, int f){ + PERM *p; +#ifdef _alist_h_ + ALIST_ID i=0; +#endif + int j; + + if ( f&PROBLEM_SHIFT ) calloc2 (P->shift, siz+2, goto ERR); + if ( f&PROBLEM_OCC_T ) calloc2 (P->occ_t, siz+2, goto ERR); + if ( f&(PROBLEM_OCC_W+PROBLEM_OCC_PW) ) calloc2 (P->occ_w, siz+2, goto ERR); + if ( f&PROBLEM_OCC_PW ) calloc2 (P->occ_pw, siz+2, goto ERR); + else P->occ_pw = P->occ_w; + if ( f&PROBLEM_OCC_W2 ){ + calloc2 (P->occ_w2, siz+2, goto ERR); + if ( f&PROBLEM_OCC_PW ) calloc2 (P->occ_pw2, siz+2, goto ERR); + else P->occ_pw2 = P->occ_w2; + } else { P->occ_w2 = P->occ_w; P->occ_pw2 = P->occ_pw; } + + if ( f&PROBLEM_ITEMFLAG ) calloc2 (P->itemflag, siz+2, goto ERR); + if ( f&PROBLEM_ITEMMARK ) calloc2 (P->itemmark, siz+2, goto ERR); + if ( f&PROBLEM_ITEMARY ) calloc2(P->itemary, siz+2, goto ERR); + if ( f&PROBLEM_ITEMCHR ) calloc2(P->itemchr, siz+2, goto ERR); + if ( f&PROBLEM_ITEMJUMP ) QUEUE_alloc (&P->itemjump, siz+2); + if ( f&PROBLEM_ITEMCAND ) QUEUE_alloc (&P->itemcand, siz+2); + + if ( f&PROBLEM_VECFLAG ) calloc2 (P->vecflag, siz2+2, goto ERR); + if ( f&PROBLEM_VECMARK ) calloc2 (P->vecmark, siz2+2, goto ERR); + if ( f&PROBLEM_VECARY ) calloc2 (P->vecary, siz2+2, goto ERR); + if ( f&PROBLEM_VECCHR ) calloc2 (P->vecchr, siz2+2, goto ERR); + if ( f&PROBLEM_VECJUMP ) QUEUE_alloc (&P->vecjump, siz2+2); + if ( f&PROBLEM_VECCAND ) QUEUE_alloc (&P->veccand, siz2+2); + if ( f&PROBLEM_VECW ) calloc2 (P->vecw, siz2+2, goto ERR); + +#ifdef _alist_h_ + if ( f&PROBLEM_ITEMLIST ) ALIST_alloc (&P->itemlist, siz+2); + if ( f&PROBLEM_VECLIST ) ALIST_alloc (&P->veclist, siz2+2); + + if ( f&PROBLEM_OCC3 ){ + MALIST_alloc (&P->occ, siz, siz2+2); // element=> +if ( ERROR_MES ) goto ERR; + if ( f&PROBLEM_OCC2 ){ + FLOOP (i, 0, siz) MALIST_ins_tail (&P->occ, (f&PROBLEM_OCC1)?siz2: 0, i, 0); + } + } +#endif + + // set outperm + if ( P->outperm_fname ){ + ARY_LOAD (p, int, j, P->outperm_fname, 1, EXIT); + if ( perm ){ + FLOOP (j, 0, siz) perm[j] = p[perm[j]]; + free2 (p); + } else perm = p; + } + ITEMSET_alloc (&P->II, P->output_fname, perm, siz, siz3); + if ( P->II.targetII.perm ) + FLOOP (j, 0, P->II.item_max){ if ( P->II.target == P->II.perm[j] ){ P->II.target = j; break; } } + +#ifdef _undo_h_ + ALISTundo_init (); +#endif + + return; + ERR:; + PROBLEM_end (P); + EXIT; +} + +#endif + + diff --git a/rql-backend/shd31/problem.h b/rql-backend/shd31/problem.h new file mode 100644 index 0000000..6b0a366 --- /dev/null +++ b/rql-backend/shd31/problem.h @@ -0,0 +1,177 @@ +/* Common problem input/output routines /structure + 25/Nov/2007 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +/***************************************************/ + +#ifndef _problem_h_ +#define _problem_h_ + +#include"stdlib2.h" +#include"queue.h" +#include"itemset.h" + +#define PROBLEM_FREQSET 1 +#define PROBLEM_MAXIMAL 2 +#define PROBLEM_CLOSED 4 +#define PROBLEM_EX_MAXIMAL 8 +#define PROBLEM_EX_CLOSED 16 +#define PROBLEM_DOC 32 + +/***** parameters for PROBLEM initialization, given to flag *****/ + +#define PROBLEM_PRINT_DENSE 4 // print density threshold +#define PROBLEM_PRINT_SHRINK 8 // print properties of shrinked database +#define PROBLEM_PRINT_FRQ 16 // print density threshold +#define PROBLEM_NORMALIZE 32 // print density threshold + +#define PROBLEM_ITEMARY 128 // alloc itemary +#define PROBLEM_ITEMJUMP 256 // alloc itemjump +#define PROBLEM_ITEMFLAG 512 // alloc itemflag +#define PROBLEM_ITEMMARK 1024 // alloc itemmark +#define PROBLEM_ITEMCAND 2048 // alloc itemcand +#define PROBLEM_VECARY 4096 // alloc itemary +#define PROBLEM_VECJUMP 8192 // alloc vecjump +#define PROBLEM_VECFLAG 16384 // alloc vecflag +#define PROBLEM_VECMARK 32768 // alloc vecmark +#define PROBLEM_VECCAND 65536 // alloc veccand +#define PROBLEM_ITEMCHR 131072 //alloc itemchr +#define PROBLEM_VECCHR 262144 //alloc vecchr +//4194304 +#define PROBLEM_OCC_T 524288 // alloc occ_t +#define PROBLEM_SHIFT 1048576 // allocate shift +#define PROBLEM_OCC_W 2097152 // weight/positive-weight sum for items +#define PROBLEM_OCC_PW 4194304 // weight/positive-weight sum for items +#define PROBLEM_OCC_W2 8388608 // weight/positive-weight sum for items +#define PROBLEM_ITEMLIST 16777216 // alist for items +#define PROBLEM_VECLIST 33554432 // alist for vecs +#define PROBLEM_VECW 67108864 // weight array for vecs + +#define PROBLEM_OCC1 16 // alloc occ +#define PROBLEM_OCC2 32 // alloc occ and ins all to list 0 +#define PROBLEM_OCC3 48 // alloc occ and ins all to list "siz" + +typedef struct { + clock_t start_time, end_time; + int problem, problem2; + LONG prog; + int prog2; + double dense; + char *input_fname, *input_fname2; + char *output_fname, *output_fname2; + char *workdir, *workdir2; + + char *weight_fname; + char *table_fname, *table2_fname; + char *outperm_fname, *outperm_fname2; + char *header_fname, *position_fname, *position2_fname, *sc_fname; + + ITEMSET II, II2; + QUEUE ff; // for agraph search + int *vf, *dep; // for agraph search + + int root, dir, edge_dir; + double th, th2, th3; // thresholds + double ratio, ratio2; // ratio + int num, siz, dim, len, width, height, gap_ub, gap_lb; + int xmax, ymax, pxmax, pymax; + QUEUE_INT clms; + VEC_ID rows; + WEIGHT cost, cost2; + + QUEUE_ID **shift; + QUEUE itemjump, itemcand, vecjump, veccand, *OQ, *OQ2, *VQ, *VQ2; // for delivery + QUEUE_INT *itemary; + char *itemchr, *vecchr; + int *itemmark, *itemflag, *vecmark, *vecflag; // mark for vector + VEC_ID *vecary, *occ_t; + WEIGHT *occ_w, *occ_pw, *occ_w2, *occ_pw2, *vecw; + QUEUE oo; + QUEUE_INT *buf, *buf_org; + size_t buf_end; + + char *pat; // pattern string + int plen, perr; // pattern length and #error allowed + +#ifdef _base_h_ + BASE B; +#endif + +#ifdef _alist_h_ + ALIST itemlist, veclist; +#endif + +#ifdef _alist_h_ + MALIST occ; +#endif + +#ifdef _sgraph_h_ + SGRAPH SG, SG2; +#endif + +#ifdef _agraph_h_ + AGRAPH AG, AG2; +#endif + +#ifdef _trsact_h_ + TRSACT TT, TT2; +#endif + +#ifdef _seq_h_ + SEQ SS, SS2; +#endif +#ifdef _pos_h_ + POS PS, PS2; +#endif + +#ifdef _fstar_h_ + FSTAR FS, FS2; +#endif + +#ifdef _vec_h_ + MAT MM, MM2; + SMAT SM, SM2; + SETFAMILY FF, FF2; +#endif + +#ifdef _barray_h_ + BARRAY BA; + BARRAY BA2; +#endif + +} PROBLEM; + + +/***** print filename information ****/ +void PROBLEM_print (PROBLEM *P); + +/***** print usage of the program *****/ +void PROBLEM_error (); + +/***** read parameters given by command line *****/ +void PROBLEM_read_param (int argc, char *argv[], PROBLEM *P); + +/***** PROBLEM and ITEMSET initialization *****/ +/* all pointers are set to NULL, but don't touch filenames */ +void PROBLEM_init (PROBLEM *P); + +/***** PROBLEM initialization: load the files given by filenames ******/ +void PROBLEM_load (PROBLEM *P); + +/***** allocate memory according to flag *****/ +void PROBLEM_alloc (PROBLEM *PP, QUEUE_ID siz, QUEUE_ID siz2, size_t siz3, PERM *p, int f); + +/* termination of problem */ +void PROBLEM_end (PROBLEM *PP); + + +#endif + + diff --git a/rql-backend/shd31/queue.c b/rql-backend/shd31/queue.c new file mode 100644 index 0000000..d961b44 --- /dev/null +++ b/rql-backend/shd31/queue.c @@ -0,0 +1,528 @@ +/* Library of queue: spped priority implementation + 12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +#ifndef _queue_c_ +#define _queue_c_ + + +#include"queue.h" +#include"stdlib2.c" + +QSORT_TYPE(QUEUE_INT, QUEUE_INT) +QSORT_TYPE(QUEUE_ID, QUEUE_ID) +QUEUE INIT_QUEUE = {TYPE_QUEUE,NULL,0,0,0}; +QUEUE_INT *common_QUEUE_INTp; + +/* initialization, not fill the memory by 0 */ +void QUEUE_alloc (QUEUE *Q, QUEUE_ID siz){ + *Q = INIT_QUEUE; + Q->end = siz+1; + malloc2 (Q->v, siz+1, EXIT); +} + +/* termination processing */ +void QUEUE_end (QUEUE *Q){ + free2 (Q->v); + *Q = INIT_QUEUE; +} + +/* tranpose the matrix ; counting/transpose/memory_allocate */ +void QUEUE_delivery(QUEUE *OQ, VEC_ID *c, QUEUE *jump, QUEUE *Q, QUEUE *occ, VEC_ID t, QUEUE_INT M){ VEC_ID i, e; + QUEUE_INT *x; + FLOOP(i, 0, occ? occ->t: t){ + e = occ? occ->v[i]: i; + if ( c ){ + if ( jump ){ MLOOP (x, Q[e].v, M){ if ( c[*x]==0 ) QUE_INS (*jump, *x); c[*x]++; } + } else { MLOOP (x, Q[e].v, M){ c[*x]++; }} + } else { + if ( jump ){ MLOOP (x, Q[e].v, M){ if ( OQ[*x].t==0 ) QUE_INS (*jump, *x); QUE_INS (OQ[*x], e); } + } else MLOOP (x, Q[e].v, M){ QUE_INS (OQ[*x], e); } + } + } +} + +/* sort a QUEUE with WEIGHT, with already allocated memory */ +void QUEUE_perm_WEIGHT (QUEUE *Q, WEIGHT *w, PERM *invperm, int flag){ + WEIGHT y; + if ( w ){ + qsort_perm__QUEUE_INT (Q->v, Q->t, invperm, flag); + ARY_INVPERMUTE_ (w, invperm, y, Q->t); + } + qsort_QUEUE_INT (Q->v, Q->t, flag); +} + +/* remove (or unify) the consecutive same ID's in a QUEUE (duplication delete, if sorted) */ +void QUEUE_rm_dup_WEIGHT (QUEUE *Q, WEIGHT *w){ + VEC_ID j, jj=0; + if ( w ){ + FLOOP (j, 1, Q->t){ + if ( Q->v[j-1] != Q->v[j] ){ + Q->v[++jj] = Q->v[j]; + w[jj] = w[j]; + } else w[jj] += w[j]; + } + } else FLOOP (j, 1, Q->t){ + if ( Q->v[j-1] != Q->v[j] ) Q->v[++jj] = Q->v[j]; + } + if ( Q->t>0 ) Q->t = jj+1; +} + +/***********************************************************************/ +/* duplicate occ's in jump, ( copy occ's to allocated QUEUE array) */ +/* Q[i].end := original item, clear each original occ */ +/* buffer size is multiplied by u */ +/*******************************************************/ +void QUEUE_occ_dup (QUEUE *jump, QUEUE **QQ, QUEUE *Q, WEIGHT **ww, WEIGHT *w, WEIGHT **ppw, WEIGHT *pw, int u){ + QUEUE_ID i, l=QUEUE_LENGTH_(*jump); + size_t cnt=0; + QUEUE_INT e, *x; + char *buf; + int unit = sizeof(*Q) + (w?sizeof(*w):0) + (pw?sizeof(*pw):0); + + ENMAX (u, sizeof(*x)); + MQUE_FLOOP (*jump, x) cnt += Q[*x].t; + if ( cnt == 0 ){ *QQ=NULL; return; } + malloc2 (buf, l*unit + (cnt+l)*u, EXIT); + *QQ = (QUEUE*)buf; buf += sizeof(*Q) *l; + if ( w ){ *ww = (WEIGHT *)buf; buf += sizeof(*w)*l; } + if ( pw ){ *ppw = (WEIGHT *)buf; buf += sizeof(*pw)*l; } + for (i=0 ; it ; i++){ + e = jump->v[i]; + (*QQ)[i].end = e; + (*QQ)[i].v = (QUEUE_INT *)buf; + (*QQ)[i].t = Q[e].t; + memcpy (buf, Q[e].v, (Q[e].t+1)*u); + buf += (Q[e].t+1) *u; + if ( w ) (*ww)[i] = w[e]; + if ( pw ) (*ppw)[i] = pw[e]; + } +} + + +/* return the position of the first element having value e. return -1 if no such element exists */ +LONG QUEUE_ele (QUEUE *Q, QUEUE_INT e){ + QUEUE_INT *x; + MQUE_FLOOP (*Q, x) + if ( *x == e ) return (x - Q->v); + return (-1); +} + +/* insert an element to the tail */ +void QUEUE_ins_ (QUEUE *Q, QUEUE_INT e){ + Q->v[Q->t] = e; + Q->t++; +} +void QUEUE_ins (QUEUE *Q, QUEUE_INT e){ + Q->v[Q->t] = e; + QUEUE_INCREMENT (*Q, Q->t); + if (Q->s == Q->t ) error_num ("QUEUE_ins: overflow", Q->s, EXIT); +} + +/* insert an element to the head */ +void QUEUE_ins_head_ (QUEUE *Q, QUEUE_INT e){ + Q->s--; + Q->v[Q->s] = e; +} +void QUEUE_ins_head (QUEUE *Q, QUEUE_INT e){ + QUEUE_DECREMENT(*Q,Q->s); + Q->v[Q->s] = e; + if (Q->s == Q->t ) error_num ("QUEUE_ins_head: underflow", Q->s, EXIT); +} + +/* extract an element from the head, without checking underflow */ +QUEUE_INT QUEUE_ext_ (QUEUE *Q){ + (Q->s)++; + return (Q->v[Q->s-1]); +} +QUEUE_INT QUEUE_ext (QUEUE *Q){ + QUEUE_INT e; + if (Q->s == Q->t ) error_num ("QUEUE_ext: empty queue", Q->s, EXIT0); + e = Q->v[Q->s]; + QUEUE_INCREMENT(*Q,Q->s); + return ( e); +} + +/* extract an element from the tail, without checking underflow */ +QUEUE_INT QUEUE_ext_tail_ (QUEUE *Q){ + (Q->t)--; + return (Q->v[Q->t]); +} +QUEUE_INT QUEUE_ext_tail (QUEUE *Q){ + if ( Q->s == Q->t ) error_num ("QUEUE_ext_tail: empty queue", Q->s, EXIT0); + QUEUE_DECREMENT(*Q,Q->t); + return (Q->v[Q->t]); +} + +/* remove the j-th element and replace it by the tail */ +void QUEUE_rm_ (QUEUE *Q, QUEUE_ID j){ + Q->t--; + Q->v[j] = Q->v[Q->t]; +} +void QUEUE_rm (QUEUE *Q, QUEUE_ID j){ + if ( Q->s <= Q->t ){ + if ( j < Q->s || j >= Q->t ) error ("QUEUE_rm: j is out of queue", EXIT); + } else if ( j < Q->s && j >= Q->t ) error ("QUEUE_rm: j is out of queue", EXIT); + QUEUE_DECREMENT(*Q,Q->t); + Q->v[j] = Q->v[Q->t]; +} + +/* remove the j-th element and replace it by the head */ +void QUEUE_rm_head_ (QUEUE *Q, QUEUE_ID j){ + Q->v[j] = Q->v[Q->s]; + Q->s++; +} +void QUEUE_rm_head (QUEUE *Q, QUEUE_ID j){ + if ( Q->s <= Q->t ){ + if ( j < Q->s || j >= Q->t ) error ("QUEUE_rm: j is out of queue", EXIT); + } else if ( j < Q->s && j >= Q->t ) error ("QUEUE_rm: j is out of queue", EXIT); + Q->v[j] = Q->v[Q->s]; + QUEUE_INCREMENT(*Q,Q->s); +} + +/* remove the j-th element and shift the following elements to fill the gap */ +int QUEUE_rm_ele_ (QUEUE *Q, QUEUE_INT e){ + QUEUE_ID i; + QUEUE_F_LOOP (*Q, i){ + if ( Q->v[i] == e ){ + memcpy ( &(Q->v[i]), &(Q->v[i+1]), (Q->t-i-1)*sizeof(QUEUE_INT)); + Q->t--; + return (1); + } + } + return (0); +} +/* insert e to the position determined by the increasing order of elements */ +void QUEUE_ins_ele_ (QUEUE *Q, QUEUE_INT e){ + QUEUE_ID i; + QUEUE_INT ee; + QUEUE_BE_LOOP_ (*Q, i, ee){ + if ( eev[i+1] = ee; + } + Q->v[i+1] = e; + Q->t++; +} + +/* Append Q2 to the tail of Q1. Q2 will not be deleted */ +void QUEUE_concat_ (QUEUE *Q1, QUEUE *Q2){ + memcpy ( &(Q1->v[Q1->t]), &(Q2->v[Q2->s]), (Q2->t-Q2->s)*sizeof(QUEUE_INT)); + Q1->t += Q2->t-Q2->s; +} +void QUEUE_concat (QUEUE *Q1, QUEUE *Q2){ + QUEUE_ID e = Q2->s; + while ( e != Q2->t){ + QUEUE_ins (Q1, Q2->v[e]); + QUEUE_INCREMENT(*Q2,e); + } +} +/* Append Q2 to the tail of Q1. Q2 will be deleted */ +void QUEUE_append_ (QUEUE *Q1, QUEUE *Q2){ + QUEUE_concat_ (Q1, Q2); + QUEUE_RMALL (*Q2); +} +void QUEUE_append (QUEUE *Q1, QUEUE *Q2){ // more improvement can be + while ( Q2->s != Q2->t ) + QUEUE_ins (Q1, QUEUE_ext(Q2)); +} + +/* Append from j to jj th elements to the tail of Q1. Q2 will not be deleted */ +void QUEUE_subconcat_ (QUEUE *Q1, QUEUE *Q2, QUEUE_ID j, QUEUE_ID jj){ + for ( ; j<=jj ; j++){ + Q1->v[Q1->t] = Q2->v[j]; + Q1->t++; + } +} +void QUEUE_subconcat (QUEUE *Q1, QUEUE *Q2, QUEUE_ID j, QUEUE_ID jj){ + while (1){ + QUEUE_ins (Q1, Q2->v[j]); + if ( j == jj ) break; + QUEUE_INCREMENT(*Q2,j); + } +} + +/* initialize Q1 by length of Q2, and copy Q2 to Q1 */ +void QUEUE_store_ (QUEUE *Q1, QUEUE *Q2){ + QUEUE_alloc (Q1, QUEUE_LENGTH(*Q2)); + QUEUE_concat_ (Q1, Q2); +} +void QUEUE_store (QUEUE *Q1, QUEUE *Q2){ + QUEUE_alloc (Q1, QUEUE_LENGTH(*Q2)); + QUEUE_concat (Q1, Q2); +} +/* copy Q2 to Q1 and delete Q2 */ +void QUEUE_restore_ (QUEUE *Q1, QUEUE *Q2){ + QUEUE_RMALL (*Q1); + QUEUE_concat_ (Q1, Q2); + QUEUE_end (Q2); +} +void QUEUE_restore (QUEUE *Q1, QUEUE *Q2){ + QUEUE_RMALL (*Q1); + QUEUE_concat (Q1, Q2); + QUEUE_end (Q2); +} + +/* copy Q2 to Q1 */ +void QUEUE_cpy_ (QUEUE *Q1, QUEUE *Q2){ + Q1->s = Q1->t = 0; + QUEUE_concat_ (Q1, Q2); +} +void QUEUE_cpy (QUEUE *Q1, QUEUE *Q2){ + QUEUE_RMALL (*Q1); + QUEUE_concat (Q1, Q2); +} + +/* compare two queues */ +int QUEUE_cmp_ (QUEUE *Q1, QUEUE *Q2){ + QUEUE_INT *x, *y=Q2->v; + MQUE_FLOOP (*Q1, x){ + if ( *x != *y ) return (0); + y++; + } + return (1); +} + +/* copy l elements of Q2 starting from s2 to the s1th position of Q1. + size of Q1 is not increasing */ +void QUEUE_subcpy_ (QUEUE *Q1, QUEUE_ID s1, QUEUE *Q2, QUEUE_ID s2, QUEUE_ID l){ + memcpy ( &(Q1->v[s1]), &(Q2->v[s2]), (l-s2)*sizeof(QUEUE_INT)); +} +void QUEUE_subcpy (QUEUE *Q1, QUEUE_ID s1, QUEUE *Q2, QUEUE_ID s2, QUEUE_ID l){ + for ( ; s2!=l ; QUEUE_INCREMENT(*Q1,s1),QUEUE_INCREMENT(*Q2,s2) ) + Q1->v[s1] = Q2->v[s2]; + Q1->v[s1] = Q2->v[s2]; +} + +/* duplicate Q2 to Q1. The memory size will be the length of Q2 */ +QUEUE QUEUE_dup_ (QUEUE *Q){ + QUEUE QQ; + QUEUE_alloc (&QQ, MAX(Q->t+1, Q->end-1)); + QUEUE_cpy_ (&QQ, Q); + return (QQ); +} + +/* merge Q1 and Q2 by insert all elements of Q2 to Q1 with deleting duplications. Both Q1 and Q2 have to be sorted in increasing order */ +void QUEUE_merge_ (QUEUE *Q1, QUEUE *Q2){ + QUEUE_ID i=Q1->t-1, j=Q2->t-1, t=i+j-Q2->s+1; + QUEUE_INT ei, ej; + if ( i+1 == Q1->s || j+1 == Q2->s ){ + QUEUE_concat_ (Q1, Q2); + return; + } + Q1->t = t+1; + ei = Q1->v[i]; + ej = Q2->v[j]; + while (1){ + if ( ei > ej ){ + Q1->v[t] = ei; + if ( i == Q1->s ){ + QUEUE_subcpy_ (Q1, Q1->s, Q2, Q2->s, j); + return; + } + i--; + ei = Q1->v[i]; + } else { + Q1->v[t] = ej; + if ( j == Q2->s ) return; + j--; + ej = Q2->v[j]; + } + t--; + } +} +void QUEUE_merge (QUEUE *Q1, QUEUE *Q2){ + QUEUE_ID i=Q1->t, j=Q2->t; + QUEUE_INT ei, ej; + QUEUE_ID t = (Q1->t + QUEUE_LENGTH(*Q2)-1) % Q1->end; + if ( QUEUE_LENGTH(*Q1) + QUEUE_LENGTH(*Q2) >= Q1->end ){ + print_err ("QUEUE_merge: overflow Q1->end="QUEUE_INTF", Q1length="QUEUE_INTF", Q2length="QUEUE_INTF"\n", Q1->end, QUEUE_LENGTH(*Q1), QUEUE_LENGTH(*Q2)); + exit (1); + } + if ( i == Q1->s || j == Q2->s ){ + QUEUE_concat (Q1, Q2); + return; + } + + Q1->t = t; + QUEUE_DECREMENT(*Q1,i); + QUEUE_DECREMENT(*Q2,j); + ei = Q1->v[i]; + ej = Q2->v[j]; + while (1){ + if ( ei > ej ){ + Q1->v[t] = ei; + if ( i == Q1->s ){ + QUEUE_subcpy (Q1, Q1->s, Q2, Q2->s, (j+Q2->end-Q2->s)%Q2->end); + return; + } + QUEUE_DECREMENT(*Q1,i); + ei = Q1->v[i]; + } else { + Q1->v[t] = ej; + if ( j == Q2->s ) return; + QUEUE_DECREMENT(*Q2,j); + ej = Q2->v[j]; + } + QUEUE_DECREMENT(*Q1,t); + } +} + +/* delete all elements of Q1 included in Q2. + both Q1 and Q2 have to be sorted in increasing order */ +void QUEUE_minus_ (QUEUE *Q1, QUEUE *Q2){ + QUEUE_ID i=Q1->s, i2 = Q2->s, ii=Q1->s; + while ( i != Q1->t && i2 != Q2->t){ + if (Q1->v[i] > Q2->v[i2] ) i2++; + else { + if (Q1->v[i] < Q2->v[i2] ){ + Q1->v[ii] = Q1->v[i]; + ii++; + } + i++; + } + } + while ( i != Q1->t ){ + Q1->v[ii] = Q1->v[i]; + i++; + ii++; + } + Q1->t = ii; +} +void QUEUE_minus (QUEUE *Q1, QUEUE *Q2){ + QUEUE_ID i=Q1->s, i2 = Q2->s, ii=Q1->s; + while ( i != Q1->t && i2 != Q2->t ){ + if ( Q1->v[i] > Q2->v[i2] ) QUEUE_INCREMENT (*Q2, i2); + else { + if ( Q1->v[i] < Q2->v[i2] ){ + Q1->v[ii] = Q1->v[i]; + QUEUE_INCREMENT (*Q1, ii); + } + QUEUE_INCREMENT (*Q1, i); + } + } + while ( i != Q1->t ){ + Q1->v[ii] = Q1->v[i]; + QUEUE_INCREMENT (*Q1, i); + QUEUE_INCREMENT (*Q1, ii); + } + Q1->t = ii; +} + +/* Delete all elements of Q1 which are not included in Q2. + both Q1 and Q2 have to be sorted in increasing order */ +QUEUE_ID QUEUE_intsec_ (QUEUE *Q1, QUEUE *Q2){ + QUEUE_ID i=Q1->s, i2 = Q2->s, c=0; + while ( i != Q1->t ){ + if ( Q1->v[i] > Q2->v[i2] ){ + if ( ++i2 == Q2->t ) break; + } else { + if ( Q1->v[i] == Q2->v[i2] ) c++; + i++; + } + } + return (c); +} +void QUEUE_and_ (QUEUE *Q1, QUEUE *Q2){ + QUEUE_ID i=Q1->s, i2 = Q2->s, ii=Q1->s; + while ( i != Q1->t ){ + if ( Q1->v[i] > Q2->v[i2] ){ + if ( ++i2 == Q2->t ) break; + } else { + if ( Q1->v[i] == Q2->v[i2] ) Q1->v[ii++] = Q1->v[i]; + i++; + } + } + Q1->t = ii; +} +void QUEUE_and (QUEUE *Q1, QUEUE *Q2){ + QUEUE_ID i=Q1->s, i2 = Q2->s, ii=Q1->s; + while ( i != Q1->t && i2 != Q2->t){ + if ( Q1->v[i] > Q2->v[i2] ) QUEUE_INCREMENT (*Q2, i2); + else { + if ( Q1->v[i] == Q2->v[i2] ){ + Q1->v[ii] = Q1->v[i]; + QUEUE_INCREMENT (*Q1, ii); + } + QUEUE_INCREMENT (*Q1, i); + } + } + Q1->t = ii; +} + +/* insertion sort */ +void QUEUE_sort (QUEUE *Q){ + QUEUE_ID i = Q->s, j, jj; + QUEUE_INT e; + if ( i== Q->t ) return; + QUEUE_INCREMENT(*Q,i); + for ( ; i!=Q->t ; QUEUE_INCREMENT(*Q,i) ){ + e=Q->v[i]; + j=i; + while (1){ + jj = j; + QUEUE_DECREMENT(*Q,j); + if ( Q->v[j] <= e ) { Q->v[jj] = e; break; } + Q->v[jj] = Q->v[j]; + if ( j == Q->s) { Q->v[j] = e; break; } + } + } +} + + +/* print a queue */ +void QUEUE_print (QUEUE *Q){ + QUEUE_ID i; + for ( i=Q->s ; i!=Q->t ; ){ + printf (QUEUE_INTF" ", Q->v[i]); + QUEUE_INCREMENT(*Q,i); + } + printf ("\n"); +} +/* permutation version */ +void QUEUE_perm_print (QUEUE *Q, QUEUE_ID *q){ + QUEUE_ID i; + for ( i=Q->s ; i!=Q->t ; ){ + printf (QUEUE_INTF" ", q[Q->v[i]]); + QUEUE_INCREMENT(*Q,i); + } + printf ("\n"); +} +void QUEUE_printn (QUEUE *Q){ + QUEUE_ID i; + for ( i=Q->s ; i!=Q->t ; ){ + printf (QUEUE_INTF" ", Q->v[i]); + QUEUE_INCREMENT(*Q,i); + } +} +void QUEUE_perm_printn (QUEUE *Q, QUEUE_ID *q){ + QUEUE_ID i; + for ( i=Q->s ; i!=Q->t ; ){ + printf (QUEUE_INTF" ",q[Q->v[i]]); + QUEUE_INCREMENT(*Q,i); + } +} +void QUEUE_print_ (QUEUE *Q){ + QUEUE_ID i; + printf("s="QUEUE_IDF",t="QUEUE_INTF": ", Q->s, Q->t); + for ( i=Q->s ; i!=Q->t ; ){ + printf (QUEUE_INTF" ",Q->v[i]); + QUEUE_INCREMENT(*Q,i); + } + printf ("\n"); +} + +void QUEUE_print__ (QUEUE *Q){ + QUEUE_ID i; + printf("s="QUEUE_IDF",t="QUEUE_IDF": ", Q->s, Q->t); + for ( i=Q->s ; i!=Q->t ; i++ ) printf (QUEUE_INTF" ",Q->v[i]); + printf ("\n"); +} + +#endif diff --git a/rql-backend/shd31/queue.h b/rql-backend/shd31/queue.h new file mode 100644 index 0000000..39c2797 --- /dev/null +++ b/rql-backend/shd31/queue.h @@ -0,0 +1,176 @@ +/* Library of queue: spped priority implementation + 12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +#ifndef _queue_h_ +#define _queue_h_ + +#include"stdlib2.h" + +#ifndef QUEUE_INT + #ifdef QUEUE_INT_LONG + #define QUEUE_INT LONG // define the type before if change is needed + #define QUEUE_INTHUGE LONGHUGE // comment out if QUEUE_INT is "short" + #define QUEUE_INTF LONGF + #else + #define QUEUE_INT int // define the type before if change is needed + #define QUEUE_INTHUGE INTHUGE // comment out if QUEUE_INT is "short" + #define QUEUE_INTF "%d" + #endif +#endif + +#ifndef QUEUE_ID + #ifdef QUEUE_ID_LONG + #define QUEUE_ID LONG // define the type before if change is needed + #define QUEUE_IDHUGE LONGHUGE // comment out if QUEUE_INT is "short" + #define QUEUE_IDF LONGF + #else + #define QUEUE_ID int // define the type before if change is needed + #define QUEUE_IDHUGE INTHUGE // comment out if QUEUE_INT is "short" + #define QUEUE_IDF "%d" + #endif +#endif +#define SWAP_QUEUE_INT(a,b) (common_QUEUE_INT=a,a=b,b=common_QUEUE_INT) +#define SWAP_QUEUE_ID(a,b) (common_QUEUE_ID=a,a=b,b=common_QUEUE_ID) + +typedef struct { + unsigned char type; // type of the structure + QUEUE_INT *v; // pointer to the array + QUEUE_ID end; // the length of the array + QUEUE_ID t; // end position+1 + QUEUE_ID s; // start position +} QUEUE; + +/* QUEUE stores at most end-1 elements. Overflow occurs after inserting end-1 elements */ + +#define QUEUE_INCREMENT(Q,i) ((i)=((i)>=(Q).end-1)?0:(i)+1) +#define QUEUE_DECREMENT(Q,i) ((i)=(i)==0?(Q).end-1:(i)-1) +#define QUEUE_LENGTH(Q) (((Q).t-(Q).s+(Q).end)%(Q).end) +#define QUEUE_LENGTH_(Q) ((Q).t-(Q).s) + +/* macro for loop w.r.t., QUEUE */ +#define QUEUE_F_LOOP(Q,i) for((i)=(Q).s;(i)!=(Q).t;((i)=((i)>=(Q).end-1)?0:(i)+1)) +#define QUEUE_F_LOOP_(Q,i) for((i)=(Q).s;(i)<(Q).t;(i)++) +#define QUEUE_FE_LOOP(Q,i,x) for((i)=(Q).s,x=(Q).v[i];(i)!=(Q).t;((i)=((i)>=(Q).end-1)?0:(i)+1),x=(Q).v[i]) +#define QUEUE_FE_LOOP_(Q,i,x) for((i)=(Q).s,x=(Q).v[i];(i)<(Q).t;(i)++,x=(Q).v[i]) +#define QUEUE_B_LOOP(Q,i) for((i)=(Q).t==0?(Q).end-1:(Q).t-1;(i)!=(Q).s;(i)=(i)==0?(Q).end-1:(i)-1) +#define QUEUE_B_LOOP_(Q,i) for((i)=(Q).t-1;(i)>=(Q).s;(i)--) +#define QUEUE_BE_LOOP(Q,i,x) for((i)=(Q).t==0?(Q).end-1:(Q).t-1,x=(Q).v[i];(i)!=(Q).s;(i)=(i)==0?(Q).end-1:(i)-1,x=(Q).v[i]) +#define QUEUE_BE_LOOP_(Q,i,x) for((i)=(Q).t-1;((i)>=(Q).s)?((x=(Q).v[i])||1):0;(i)--) + +#define QUEUE_RMALL(Q) ((Q).t=(Q).s) +#define QUEUE_RMALL_(Q) ((Q).t=0) +#define QUEUE_HEAD(Q) ((Q).v[(Q).s]) +#define QUEUE_TAIL_(Q) ((Q).v[(Q).t-1]) + +extern QUEUE INIT_QUEUE; +extern QUEUE_INT common_QUEUE_INT, *common_QUEUE_INTp; +QSORT_TYPE_HEADER(QUEUE_INT, QUEUE_INT) +QSORT_TYPE_HEADER(QUEUE_ID, QUEUE_ID) + + +/* initialization, not fill the memory by 0 */ +void QUEUE_alloc (QUEUE *Q, QUEUE_ID siz); + +/* termination processing */ +void QUEUE_end (QUEUE *Q); + +/* delivery: transpose that matrinx (transaction database) Q. Each row of the + transposed matrix is called occurrence. + +variables to be set. +OQ:array for occurrences, c: for counting frequency, jump: list of items with non-empty OQ +if c!=NULL, count the frequency and set to c, and set occurrences to OQ, otherwise. +if jump==NULL, then the list of non-empty item will not be generated +Q:matrix, of an array of QUEUE, occ: list of rows of Q to be scaned, t; maximum ID of the + row to be scaned; if occ==NULL, occ will be ignored, otherwise t will be ignored. + M: end mark of each QUEUE. */ +void QUEUE_delivery(QUEUE *OQ, VEC_ID *c, QUEUE *jump, QUEUE *Q, QUEUE *occ, VEC_ID t, QUEUE_INT M); +/* sort a QUEUE with WEIGHT, with already allocated memory (size have to no less than the size of QUEUE) */ +void QUEUE_perm_WEIGHT (QUEUE *Q, WEIGHT *w, PERM *invperm, int flag); + +/* remove (or unify) the consecutive same ID's in a QUEUE (duplication delete, if sorted) */ +void QUEUE_rm_dup_WEIGHT (QUEUE *Q, WEIGHT *w); + +/***********************************************************************/ +/* duplicate occ's in jump, ( copy occ's to allocated QUEUE array) */ +/* Q[i].end := original item, clear each original occ */ +/* buffer size is multiplied by u */ +/*******************************************************/ + + +void QUEUE_occ_dup (QUEUE *jump, QUEUE **QQ, QUEUE *Q, WEIGHT **ww, WEIGHT *w, WEIGHT **ppw, WEIGHT *pw, int u); + +/* return the position of the first element having value e. return -1 if no such element exists */ +LONG QUEUE_ele (QUEUE *Q, QUEUE_INT e); + +/* insert an element to the tail/head */ +void QUEUE_ins_ (QUEUE *Q, QUEUE_INT e); +void QUEUE_ins (QUEUE *Q, QUEUE_INT e); +void QUEUE_ins_head_ (QUEUE *Q, QUEUE_INT e); +void QUEUE_ins_head (QUEUE *Q, QUEUE_INT e); + +/* extract an element from the head/tail, without checking the underflow */ +QUEUE_INT QUEUE_ext_ (QUEUE *Q); +QUEUE_INT QUEUE_ext (QUEUE *Q); +QUEUE_INT QUEUE_ext_tail_ (QUEUE *Q); +QUEUE_INT QUEUE_ext_tail (QUEUE *Q); + +/* remove the j-th element and replace it by the tail/head or shift */ +void QUEUE_rm_ (QUEUE *Q, QUEUE_ID j); +void QUEUE_rm (QUEUE *Q, QUEUE_ID j); +void QUEUE_rm_head_ (QUEUE *Q, QUEUE_ID j); +void QUEUE_rm_head (QUEUE *Q, QUEUE_ID j); +int QUEUE_rm_ele_ (QUEUE *Q, QUEUE_INT e); + +/* Append Q2 to the tail of Q1. Q2 will (not) be deleted */ +void QUEUE_append_ (QUEUE *Q1, QUEUE *Q2); +void QUEUE_append (QUEUE *Q1, QUEUE *Q2); +void QUEUE_concat_ (QUEUE *Q1, QUEUE *Q2); +void QUEUE_concat (QUEUE *Q1, QUEUE *Q2); + +/* Append from j to jj th elements to the tail of Q1. Q2 will not be deleted */ +void QUEUE_subconcat_ (QUEUE *Q1, QUEUE *Q2, QUEUE_ID j, QUEUE_ID jj); +void QUEUE_subconcat (QUEUE *Q1, QUEUE *Q2, QUEUE_ID j, QUEUE_ID jj); + +/* initialize Q1 by length of Q2, and copy Q2 to Q1 */ +void QUEUE_store_ (QUEUE *Q1, QUEUE *Q2); +void QUEUE_store (QUEUE *Q1, QUEUE *Q2); +/* copy Q2 to Q1 and delete Q2 */ +void QUEUE_restore_ (QUEUE *Q1, QUEUE *Q2); +void QUEUE_restore (QUEUE *Q1, QUEUE *Q2); + +/* copy Q2 to Q1 */ +void QUEUE_cpy_ (QUEUE *Q1, QUEUE *Q2); +void QUEUE_cpy (QUEUE *Q1, QUEUE *Q2); +QUEUE QUEUE_dup_ (QUEUE *Q); +/* copy l elements of Q2 starting from s2 to the s1th position of Q1. + size of Q1 is not increasing */ +void QUEUE_subcpy_ (QUEUE *Q1, QUEUE_ID s1, QUEUE *Q2, QUEUE_ID s2, QUEUE_ID l); +void QUEUE_subcpy (QUEUE *Q1, QUEUE_ID s1, QUEUE *Q2, QUEUE_ID s2, QUEUE_ID l); + +/* merge/minum/intersection of Q1 and Q2, and set Q1 to it. + Both Q1 and Q2 have to be sorted in increasing order */ +void QUEUE_merge_ (QUEUE *Q1, QUEUE *Q2); +void QUEUE_merge (QUEUE *Q1, QUEUE *Q2); +void QUEUE_minus_ (QUEUE *Q1, QUEUE *Q2); +void QUEUE_minus (QUEUE *Q1, QUEUE *Q2); +void QUEUE_and_ (QUEUE *Q1, QUEUE *Q2); +void QUEUE_and (QUEUE *Q1, QUEUE *Q2); + +/* insertion sort */ +void QUEUE_sort (QUEUE *Q); + + /* print */ +void QUEUE_print (QUEUE *Q); +void QUEUE_print_ (QUEUE *Q); + + +#endif diff --git a/rql-backend/shd31/readme.txt b/rql-backend/shd31/readme.txt new file mode 100644 index 0000000..91afdb2 --- /dev/null +++ b/rql-backend/shd31/readme.txt @@ -0,0 +1,603 @@ +###################################################################### +SHD: Sparse Hypergraph Dualization Aug/8/2007 + Coded by Takeaki Uno, e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html +###################################################################### + +** This program is available for only academic use, basically. ** +** Anyone can modify this program, but he/she has to write down ** +** the change of the modification on the top of the source code. ** +** Neither contact nor appointment to Takeaki Uno is needed. ** +** If one wants to re-distribute this code, do not forget to ** +** refer the newest code, and show the link to homepage ** +** of Takeaki Uno, to notify the news about SHD for the users. ** +** For the commercial use, please make a contact to Takeaki Uno. ** + +################################ +#### Problem Definition #### +################################ + +(The readers who are not familiar to the notion of hypergraph, see the +equivalent problems written below.) + +Let H=(V,F) be a hypergraph with vertex set V and hyperedge set F. +A hyperedge is a subset of vertex set V, thus F is a subset family +defined on V. F may include several identical hyperedges. A subset H +of V is called a hitting set of F if the intersection of H and any is +non-empty. A hitting set is called minimal if it is not included in +any other hitting set. The dual H'=(V,F') of H is the hypergraph such +that F' is the correction of minimal hitting sets of F. For example, +when V={1,2,3,4}, F={ {1,2}, {1,3}, {2,3,4} }, {1,3,4} is a hitting set +but not minimal, and {2,3} is a minimal hitting set. The dual of H=(V,F) +is given by F'={ {1,2}, {1,3}, {1,4}, {2,3} }. The problem dualization +is to compute the dual of the given hypergraph H=(V,F). + +Dualization is equivalent to the following problems: + +== (1) minimal hitting set enumeration == +Let V be a set of items. A transaction is a subset of V. A transaction +database is a collection of transactions which may include several +identical transactions. A transaction database is a subset family +defined on V. The problem is to output all minimal hitting sets of +given transaction database (or equivalently subset family). + +== (2) minimal set covering enumeration == +For a subset family Y defined on a set X, a set cover S is a subset of +Y such that the union of the member of S is equal to Y (Y=\cup_{A\in S}). +A set covering is called minimal if it is included in no other set +covering. Let us regard Y as a vertex set, and consider a hyperedge +B(x) for each element x of X such that B(x) is the collection of +subsets in X which include x. Then, for the hyperedge set (set family) +F={B(x) | x\in X}, a hitting set of F is a set cover of Y, and vice versa. +Thus, enumerating minimal set coverings is equivalent to the dualization. + +== (3) minimal uncovered set enumeration == +For a subset family Y defined on a set X, let an uncovered set +be a subset of X which is not included in any member of Y. A minimal +uncovered set is one which is included in no other uncovered set. +The problem is to enumerate minimal uncovered sets of Y. +Let !Y be the complement of Y, which is the collection of the complement +of subsets in Y, that is, !Y = {!y | y\in Y}, where !y = X-y is the +complement of y. For a subset y and S, S is not included in y if and +only if S and !y have non-empty intersection. Thus, an uncovered set +of Y is a hitting set of !Y, and vice versa, thus the minimal uncovered +set enumeration is equivalent to the minimal hitting set enumeration. + +== (4) circuit enumeration for independent system == +A subset family F is called an independent system if for any member X +of F, any its subset is also a member of F. A member of F is called an +independent set. An independent set is called a maximal independent set +if it is included in no other independent set. A set is called dependent +if it is not in F. A circuit is a minimal dependent set, i.e., a dependent +set which properly contains no other dependent set. If an independent +system is given by the set of maximal independent sets of F, then +the enumeration of circuits of F is equivalent to the enumeration of +uncovered set of F. The problem of enumerating maximal independent +sets from the set of circuits is also equivalent to dualization, +because for !F, the circuit set of !F is the set of maximal independent +sets of F, and the set of maximal independent sets of !F is the circuit +set of F. + +== (5) Computing negative border from positive border == +A function is called Boolean function if it maps members of sets 2^V +to 0 or 1. A Boolean function B is called monotone (resp., anti-monotone) +if it satisfies that for any set X with B(X)=0 (resp., B(X)=1), +any subset X' of X satisfies B(X)=0 (resp., B(X)=1). +For a monotone function B, a subset X is called positive border +if B(X)=0 and no Y, B(Y)=0 properly includes X, and is called negative +border if B(X)=1 and no Y, B(Y)=1 is properly included in X. For given +the set of positive borders, the problem of enumerating negative borders +is equivalent to dualization, because the problem is equivalent to +uncovered set enumeration (3) and circuit enumeration (4). +The enumeration of positive borders from the negative borders can be +done by enumerating uncovered sets for the collection of the complement +of negative borders. + +== (6) DNF<->CNS transformation == +A DNF is a formula all whose clauses are composed of literals +connected by "or", and all clauses are connected by "and". A CNF is a +formula all whose clauses are composed of literals connected by "and", +and all clauses are connected by "or". Any formula can be represented +in both DNF formula and CNF formula. Let D be a DNF formula composed +of variables x1,...,xn and clauses C1,...,Cm. A DNF/CNF is called +monotone if no clause contains literal with ``not''. Then, S is a +hitting set to the clauses of D if and only if the assignment obtained +by setting literals in S to true gives a true assignment of D. Let H +be a minimal CNF formula equivalent to D. H has to include any minimal +hitting set as its clause, since any clause has to contain at least +one literal of each clause of D. Thus, computing minimal CNF +equivalent H has to include all minimal hitting sets of D. In the +same reason, computing the minimal DNF from a CNF is equivalent to +the dualization. + + +################################## +#### Mathematical Aspects #### +################################## + +- Finding the minimum cardinality hitting set is known to be NP-hard, + it is the same for finding the minimum cardinality set covering. +- Finding one minimal hitting set is done in O(||F||) time. +- There is no known output polynomial time algorithm for dualization. + Its existence is a famous open problem. + + +##################### +#### Usage #### +##################### + + ==== How to Compile ==== +Unzip the file into arbitrary directory, and execute "make". +Then you can see "shd" (or shd.exe) in the same directory. + + ==== Command Line Options ==== +To execute SHD, just type shd and give some parameters as follows. + +% shd 09Dcq input-filename [output-filename] + +"%" is not needed to type. It is a symbol to represent command line. +To see a simple explanation, just execute "shd" without parameters. + +"input-filename" is the filename of the input transaction database. +The 1st letter of input-filename must not be '-'. Otherwise it is +regarded as an option. The input file format is written below. +"output-filename" is the name of file to write the hyperedge (minimal +hitting set) the program finds. You can omit the output file to +see only the number of minimal hitting sets classified by the +cardinality. If the output file name is "-", the solutions will be +output to the standard output. + +The first parameter is given to the program to indicate the task and +the method. + + _: no output to standard output (including messages w.r.t. input data) + (solve uncovered set enumeration problem) + %: show progress of the computation + +: if the output file exists, append the solutions to the output file + 0: normal version (reverse search approach) + 9: straightforward version + D: depth-first search version + P: do not execute the pruning algorithm + c: take the complement of the input file + t: transpose the database so that item i will be transaction i, thus + if item i is included in j-th transaction, then item j will be + included in i-th transaction. + +0 and 9 can not be given simultaneously, but any other combination +is accepted. D command switches to the algorithm to a branch-and-bound +type depth first search algorithm, and P and R inactivate puring +algorithm and data reduction algorithm, respectively. These commands +are basically for evaluating the performance of the algorithm, thus +usually just giving 0 or D is sufficient. + + -# [num]:stop after outputting [num] solutions + -, [char]: give the separator of the numbers in the output + the numbers in the output file are separated by the given + character [char]. + -Q [filename]: replace the output numbers + according to the permutation table written in the file of + [filename], replace the numbers in the output. The numbers in the + file can be separated by any non-numeric character such as newline + character. + -l [num]:output trees/graphs with at least [num] vertices + -u [num]:output trees/graphs with at most [num] vertices + +Examples) + +- dualize "tt.dat" by normal version, and output to "out" + +% shd 0 tt.dat out + +- dualize "ttt.dat" by straightforward depth-first search version, and +make no output file + +% shd 9D ttt.dat + +- enumerate minimal uncovered sets of "tt.dat" and output to "min.out" + by depth-first search version + +% shd Dc tt.dat min.out + + +############################### +#### Input File Format #### +############################### + +The vertex set must be numbers ranging from 0 to n. They do not have to be +consecutive numbers from 0 to n, but the program considers that the vertex +set is {0,...,n}, thus uses memory linear in n. Thus they should be +consecutive, for the efficiency. In the case of uncovered set enumeration, +all numbers from 0 to n can be a part of uncovered sets. + +Each line (row) of the input file is corresponding to a hyperedge (subset, +or transaction). The vertices (items, or elements) included in a hyperedge +is listed in a line. The separator of numbers can be any non-numeric letter, +such as "," " " ":" "a", etc. + +Example) ( "[EOF]" is the end of file ) +0 1 2 +1 +2 3 4 +4,1 2 3 +2,1 +[EOF] + +################################################################# +#### Use General Names for Variables and Other Formats #### +################################################################# + +We can transform variable names in general strings to numbers so that we +can input the data to the program, by some script files. + +-- transnum.pl table-file [separator] < input-file > output-file +Read file from standard input, and give a unique number to each name written +by general strings (such as ABC, ttt), and transform every string name to +a number, and output it to standard output. The mapping from string names to +numbers is output to table-file. The default character for the separator of +the string names is " "(space). It can be changed by giving a character for +the option [separator]. For example, A,B is a string name, if the separator +is space, but if we set the separator to ",", it is regarded as two names +A and B. This is executed by "transnum.pl table-file "," < input-file...". + +-- untransnum.pl table-file < input-file > output-file +According to the table-file output by transnum.pl, un-transform numbers to +string names. The output of the program is composed of numbers, thus +it is used if we want to transform to the original string names. +It reads file from standard output, and output to the standard output. + +-- appendnum.pl +When we want to distinct the same words in different columns, use this +script. This append column number to each words, so we can distinct them. +Then, by using transnum.pl, we transform the strings to numbers. + +-- transpose.pl +Transpose the file. In the other words, consider the file as an adjacency +matrix of a bipartite graph, and output the transposed matrix, or exchange +the positions of vertices and hyperedges. For an input file, output the +file in which the i-th line corresponds to item i, and includes the +numbers j such that i is included in the j-th line of the input file. + +######################################### +#### Batch Files for Simple use #### +######################################### + +For general string names, we have several batch files scripts for basic usages +"exec_shd", "exec_shd_", "sep_shd", or "sep_shd_". For example, when a hypergraph +with "general item names" is, + +dog pig cat +cat mouse +cat mouse dog pig +cow horse +horse mouse dog +[EOF] + +All these replace strings in the input database by numbers, execute SHD, +and replace the numbers in the output file by the original strings. +The usage of the scripts are + +% exec_shd [FCMfIq] input-filename support output-filename [options] + +You have to specify F, C or M, and output filename. The separator of the +items is " " (blank, space). If you want to use other character as a +separator, use "sep_shd". The usage is + +% sep_shd separator [FCMfIq] input-filename support output-filename [options] + +Almost same as "exec_shd" but you have to specify separator at the fourth +parameter. "exec_lcm_" and "sep_lcm_" are both for the aim to distinct +the same items in the different columns. For example, it is used to the +database such that different items are there in different columns, but +some special symbols, such as "- is for missing data", are used commonly. +An example is; + +A true small +C true - +A false middle +B - - +C - middle +A true - +[EOF] + +In the output file, the items are followed by "." and numbers where +the numbers are the column number. For example, "dog.0" means the item +"dog" on the 0th(first) column. + +The usage of them are the same as "exec_shd" and "sep_shd", respectively. +The scripts use files of the names "__tmp1__", "__tmp2__", and "__tmp3__", +The file of these names will be deleted after the execution. + +Example) + +% exec_shd 0 test2.dat out.dat + +% sep_shd_ "," Dc test3.dat out.dat + + +############################# +#### Output Format #### +############################# + +When the program is executed, the program prints out the #items, +#transactions, and other features of the input database to standard +error. After the termination of the enumeration, it outputs the total +number of itemsets found (frequent/closed/maximal itemsets), and the +numbers of itemsets of each size. For example, if there are 4 frequent +itemsets of size 1, 2 frequent itemsets of size 3, and 1 frequent itemset +of size 3, then the output to standard output will be, + +9 <= total #hyperedges +0 <= #hyperedges of size 0 +4 <= #hyperedges of size 1 +3 <= #hyperedges of size 2 +1 <= #hyperedges of size 3 + +If "q" is given in the first parameter, these do not appear in the +standard output. + +If output-filename was given, then the hyperedges found are written to +the output file. Each line of the output file is the list of vertices +included in a hyperedge, separated by " ". For example, + +1 5 10 2 4 + +which means hyperedge {1,2,4,5,10} is in the dual. +In the output file, the vertices in each row are not sorted. If you want +to sort it, use the script "sortout.pl". The usage is just, + +% sortout.pl < input-file > output-file + +"input-file" is the name of file to which SHD outputs, and the sorted +output will be written in the file of the name "output-file". +The vertices of each hyperedge will be sorted in the increasing order of +the vertex ID's, and all the hyperedges (lines) will be also sorted, by the +lexicographical order (considered as a string). +(Actually, you can specify separator like sortout.pl ","). + + + +########################### +#### Performance #### +########################### + +The performance of SHD is stable, for both computation time and memory use. +The initialization and preprocess time of SHD is linear in the size of +input hypergraph. The computation time is intuitively linear in the product +of (output hyperedges) and (number of input hyperedges). + +Memory usage of SHD is very stable. It is an advantage compared to other +implementations. The memory usage of SHD is almost linear in the size of +the input database. Approximately SHD uses integers at most three times +as much as the database size, which is the sum of the sizes of each hyperedge. +The memory usage of the other implementations increases as the increase +of the number of hyperedges, but that of SHD does not. + + +\###################################################### +#### Introductions to Hypergraph Dualization #### +####################################################### + +under construction. + + + +################################################### +#### Algorithms and Implementation Issue #### +################################################### + +The algorithm consists two search methods and one fast minimality +checking algorithm. First we explain fast minimality check. + + + === minimality check === + +When we have a set S, it is easy to confirm that S is a hitting set of F +or not. First, put a mark to all vertices included in S, and for each +hyperedge, look at the marks of all vertices included in it. In this way, +the computation time is O(||F||) where ||F|| is the sum of the sizes +of the hyperedges in F. +If there is a hyperedge such that no vertex of it has a mark, then +S is not a hitting set. Confirming that S is a minimal hitting set or +not is the next task. A straightforward method for the task is to check +whether S-v is a hitting set or not for all vertices v in S. In this way +we need O(||F|| \times |S|) time. Instead of that, we use a +characterization for the minimality. For a vertex v in S, if a hyperedge H +includes only v among vertices of S, i.e., S\cap H = {v}, we call H +"critical hyperedge" of v. If v has no critical hyperedge, S-v is also +a hitting set, thus the existence of critical hyperedge assures that +v can not remove from the set. Thus, S is a minimal hitting set if and +only if every vertex in S has a critical hyperedge. + +Let us see an example. Suppose that hypergraph H=(V,F) is +V={1,2,3,4}, F={ {1,2}, {1,3}, {2,3,4} }, and S = {1,3,4} is a hitting set. +{1,2} is a critical hyperedge of 1, {1,3} is a critical hyperedge of 3, +but 4 has no critical hyperedge. It means that {1,3,4} - 4 has intersection +to all hyperedges. Actually, {1,3} is a hitting set. For {1,3}, again, +1 has a critical hyperedge {1,2}, and 3 has a critical hyperedge {1,3}, +then the removal of any vertex from {1,3} yields non-hitting set, thus +{1,3} is a minimal hitting set. + +We denote the set of critical hyperedges of vertex v by crit(v,S). +A hyperedge can be a critical hyperedge for at most one vertex, thus +the sum ||crit()|| of the sizes of crit() for all vertices does not +exceed |F|. For a hyperedge H, computing the vertex v such that H is a +critical hyperedge of v, or confirm that H is critical hyperedge of no +vertex, can be done in O(|H|) time by computing S\cap H (by looking at +marks on each vertex of H). Thus, computing all critical hyperedges +for all vertices can be done in O(||F||) time. + +For each vertex v, let Occ(v) be the set of hyperedges including v. +For a vertex set S, let uncov(S) be the set of hyperedges having empty +intersection to S. S is a hitting set if and only if uncov(S) is an +empty set. Suppose that S is not a hitting set, and each vertex in S +has at least one critical hyperedge, i.e., for any u in S, crit(u) != +emptyset, and consider an addition of vertex v to S. Then, we can see +(a) uncov(S+v) = uncov(S) - Occ(v) +(b) crit(v,S+v) = uncov(S) \cap Occ(v) +(c) for u in S, crit(u,S+v) = crit(u,S) - Occ(v) +Then, by marking all hyperedges in Occ(v), we can compute all crit() +in O(|Occ(v)| + ||crit()|| ). + +Let us see an example. Suppose that hypergraph H=(V,F) is +V={1,2,3,4,5}, F = { {1,3}, {1,4}, {1,2,3}, {2,3}, {2,4,5}, {3,4}, {4,5} }, +and S={1,2}, v=3. Then, uncov(S) = { {3,4}, {4,5} }, crit(1,S) = +{ {1,3}, {1,4} }, crit(2,S) = { {2,3}, {2,4,5} }, and Occ(v) = +{ {1,3}, {1,2,3}, {2,3}, {3,4} }. Then, for S+3, + +(a) uncov(S+3) = {{3,4}, {4,5}} - {{1,3}, {1,2,3}, {2,3}, {3,4}} = {{4,5}} +(b) crit(3,S+3) = {{3,4}, {4,5}} \cap {{1,3}, {1,2,3}, {2,3}, {3,4}} = {{3,4}} +(c) crit(1,S+3) = {{1,3}, {1,4}} - {{1,3}, {1,2,3}, {2,3}, {3,4}} = {{1,4}} +(c) crit(2,S+3) = {{2,3}, {2,4,5}} - {{1,3}, {1,2,3}, {2,3}, {3,4}} = {{2,4,5}} + + + === simple depth-first search method === +Using the above minimality check, we develop an depth-first search +type algorithm. The strategy is very simple. We start by setting S to +an empty set, and adding a vertex to S one by one, with keeping the +condition that any vertex in S has at least one critical hyperedge. +When S is a hitting set, S is a minimal hitting set, thus we output it. +To avoid the duplication, in each iteration, we add only vertices +larger than the maximum index vertex in S, denoted by tail(S). +The algorithm is written as follows. + +Algorithm SHDdfs_straight (S, crit(), uncov(S)) +1. if uncov(S) is empty, then output S and return; +2. for each vertex v>tail(S), + 2-1. compute uncov(S+v) and crit() for S+v, + 2-2. if crit(u,S+v) is non-empty for any vertex u in S + then call SHDdfs_straight (S+v, crit(), uncov(S+v)) + +We can examine this algorithm by giving options 9D for SHD, i.e., + execute "shd 9D input-file output-file". +To improve the efficiency, we use several techniques for maintaining crit, +explained as follows, and a pruning technique. Their combination gives +our first algorithm. + +The correctness of the algorithm is as follows. For hypergraph H=(V,F), +let Z(H) be the set of vertex sets S such that any vertex in S has at +least one critical hyperedge. Observe that by removing a vertex from S, +no vertex loses its critical hyperedge, i.e., crit(u,S) is included in +crit(u, S-v) for any vertex v. This comes from above property (c). +Thus, any X in Z(H), any subset of X is also in Z(H), thereby monotone. +For example, for hypergraph H(V,E), V={1,2,3,4}, F={ {1,2}, {1,3}, {2,3,4} }, + Z(H) = { {1}, {2} , {3}, {4}, {1,2}, {1,3}, {1,4}, {2,3} } +A minimal hitting set is a maximal element (positive border) in Z(H). +Thus, by the algorithm, any X in Z(H) is generated by X-tail(X), thus +it enumerates all the elements in Z(H). + + === finding violating vertices === +For vertex set S in Z(H), we call a vertex v addible if S+v is in Z(H). +The algorithm adds vertices and update crit, +to check whether the addition is in Z(H) or not. Here we show an efficient +way for the check. For a vertex u in S and v not in S, crit(u, S+v) is +an empty set if and only if any critical hyperedge of u includes v, i.e., +crit(u,S)\subseteq Occ(v), equivalently crit(u,S)\cap Occ(v) = crit(u,S). +For given u, computing crit(u,S)\cap Occ(v) for all v can be done +in O(||cirt(u,S)||) time by occurrence deliver. Thus, by performing +occurrence deliver for critical hyperedges of all vertices in S, +we can obtain the vertices v satisfying that S+v is in Z(H). +This can be done O(||cirt()||) time, which is faster than +computing crit() for each vertex v not in S. + + + === pruning technique === +Suppose that we have a set S each whose vertex has at least one critical +hyperedge, and E={v1,...,vk} be a hyperedge in uncov(S). Then, we know +that any minimal hitting set includes at least one vertex in E. Thus, +we can divide the minimal hitting sets into several groups G1,...,Gk +where Gi is the group of minimal hitting sets including vi but not +including v1,...,v{i-1}. For enumerating minimal hitting sets in Gi, +we put marks on vertices v1,...,v{i-1} not to choose them. Then, the +algorithm is written as follows. The marks of vertices are cleared at +the initialization. + +Algorithm SHDdfs (S, crit(), uncov(S)) +1. if uncov(S) is empty, then output S and return +2. compute all unmarked addible vertices to S +3. choose a hyperedge E from uncov(S) which includes the least + unmarked addible vertices +4. for each unmarked addible vertex v in E, put a mark +5. compute crit\cap Occ(v) ,uncov(S)\cap Occ(v) for all addible + unmarked vertices by occurrence deliver +6. for each unmarked addible vertex v in E, + 6-1 call SHDdfs_straight (S+v, crit(), uncov(S+v)) + 6-2 clear bucket of v, and erase mark on v + +We can execute this algorithm by giving option as +"shd D input-file output-file". + + + === reverse search method === +The next search strategy is based on a technique so called reverse search. +Suppose that hyperedges of H is {E1,...,Em}, and we denote the hypergraph +having hyperedges E1,...,Ei by Hi. Let mincrit(v,S) be the minimum index +hyperedge in crit(v,S). For a vertex subset S in Z(H), +we define the core hyperedge core_h(S) by the hyperedge Ei such that +For hyperedges E1,...,Ei, S is not in Z(H{i-1}) but is in Z(Hi). +Ei is maximum one among the minimum critical hyperedges of all vertices, +i.e., Ei = max_{u\in S} mincrit (u,S), thus core_h(S) is +defined uniquely. Thereby, the core hyperedge is always a critical +hyperedge of a vertex. We say the vertex core vertex and denote it by +core_v(S). We define the parent P(S) of S by S - core_v(S). + +For example, for hypergraph H(V,E), V={1,2,3,4}, F={ {1,2}, {1,3}, {2,3,4} }, + Z(H) = { emptyset, {1}, {2} , {3}, {4}, {1,2}, {1,3}, {1,4}, {2,3} }, +the parent of {1}, {2}, {3}, {4} is the emptyset, and the parent of {1,2}, +{1,3}, {1,4} is {1}, and the parent of {2,3} is {2}. +The core hyperedge of {2,3} is {1,3}, and the core vertex is 3. + +This parent child relation is acyclic, and except for the empty set, +any vertex set in Z(H) has its parent, thus it forms a tree. +Here we consider a search method which moves from parent to children +recursively in a depth-first search manner. Suppose that S+v is a child +of S. Then, the core hyperedge of S+v is the minimum index hyperedge E in +uncov(S). Thus, v has to be included in E. Conversely, for S in Z(H), +let E be the minimum index hyperedge in uncov(S). Then, any child of S +is obtained by adding a vertex v in E to S. Suppose that v is a vertex +in E. If S+v is in Z(H), then mincrit(v,S) = Ei. When hyperedge set +F = { {1,2}, {1,3}, {2,3,4} } and S={2}, the minimum hyperedge in +uncov(S) is {1,3}. Both S+1 and S+3 are in Z(H). The core hyperedge of +{2,3} is {1,3} and the core vertex is 3, thus {2} is the parent of {2,3}. +However, the core hyperedge of {1,2} is {2,3,4}, it differs from {1,3}. +The core vertex of {1,2} is 2, thus the parent of {1,2} is {1}. +Therefore, S+v is a child of S if and only if mincrit(u,S+v) has no larger +index than mincrit(u,S+v). This holds when no vertex u in S loses all +its critical hyperedges by adding v, i.e., for each vertex u in S, +at least one critical hyperedge whose index is less than mincrit(v,S+v) +(minimum hyperedge in uncov(S)) does not include v. This can be checked +by occurrence deliver in the same way. The following algorithm traverses +the tree induced by this parent child relation. + +Algorithm SHD (S, crit(), uncov(S)) +1. if uncov(S) is empty, then output S and return; +2. Ei := minimum index hyperedge in uncov(S) +3. for each vertex v in Ei, + 3-1. compute uncov(S+v) and crit() for S+v, + 3-2. if crit(u,S+v) is non-empty for any vertex u in S + and mincrit(u,S+v) is less than Ei, + then call SHD (S+v, crit(), uncov(S+v)) + +We can examine this algorithm by giving options 9 for SHD, i.e., + execute "shd 9 input-file output-file". +To improve the efficiency, we use the same technique above. +We can examine the improved algorithm by giving options 0 for SHD, i.e., + execute "shd 0 input-file output-file". + + +############################### +#### Acknowledgments #### +############################### + +We thank to Ken Satoh of National Institute of Informatics Japan, Hiroki +Arimura of Hokkaido University for their contribution for the research, +A part of the research of SHD is supported by Grant-in-aid from the +Ministry of Education, Science, Sport and Culture of Japan +(Monbu-Kagaku-Sho). We also thank Dr. Renato Vimieiro for a bug report. + + + +########################## +#### References #### +########################## + + diff --git a/rql-backend/shd31/sep_shd b/rql-backend/shd31/sep_shd new file mode 100644 index 0000000..3be5bc2 --- /dev/null +++ b/rql-backend/shd31/sep_shd @@ -0,0 +1,5 @@ +./transnum.pl __tmp1__ $1 < $3 > __tmp2__ +./shd $2 $5 $6 $7 $8 $9 __tmp2__ __tmp3__ +touch __tmp3__ +./untransnum.pl __tmp1__ < __tmp3__ > $4 +rm -f __tmp1__ __tmp2__ __tmp3__ diff --git a/rql-backend/shd31/sep_shd_ b/rql-backend/shd31/sep_shd_ new file mode 100644 index 0000000..2467ad6 --- /dev/null +++ b/rql-backend/shd31/sep_shd_ @@ -0,0 +1,7 @@ +./appendnum.pl $1 < $3 > __tmp4__ +./transnum.pl __tmp1__ $1 < __tmp4__ > __tmp2__ +rm -f __tmp4__ +./shd $2 $5 $6 $7 $8 $9 __tmp2__ __tmp3__ +touch __tmp3__ +./untransnum.pl __tmp1__ < __tmp3__ > $4 +rm -f __tmp1__ __tmp2__ __tmp3__ diff --git a/rql-backend/shd31/shd.c b/rql-backend/shd31/shd.c new file mode 100644 index 0000000..ba9ae49 --- /dev/null +++ b/rql-backend/shd31/shd.c @@ -0,0 +1,788 @@ +/* Scalable Hypergraph Dualization algorithm */ +/* 2004/4/10 Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, do not forget to + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about SHD for the users. + For the commercial use, please make a contact to Takeaki Uno. */ + + + +#ifndef _shd_c_ +#define _shd_c_ + +#include"alist.c" +#include"barray.c" +#include"vec.c" +#include"barray.c" +#include"problem.c" + +#define SHD_STRAIGHT 1 +#define SHD_DFS 2 +#define SHD_COMPLEMENT 4 +#define SHD_NO_BITMAP 16 +#define SHD_PRUNE 32 + +void SHD_error (){ + ERROR_MES = "command explanation"; + print_err ("SHD: 09DSqc [options] input-filename [output-filename]\n\ +%%:show progress, _:no message, +:write solutions in append mode\n\ +c:complement input, P:no pruning, B:no bitmap\n\ +0:normal version, D:dfs version, 9:naive-minimality-check version\n\ +t:transpose the database so that i-th transaction will be item i\n\ +[options]\n\ +-l [num]:output itemsets with size at least [num]\n\ +-u [num]:output itemsets with size at most [num]\n\ +-S [num]:stop after outputting [num] solutions\n\ +-, [char]:give the separator of the numbers in the output\n\ +-Q [filename]:replace the output numbers according to the permutation table given by [filename]\n\ +# the 1st letter of input-filename cannot be '-'.n\ +# if the output file name is -, the solutions will be output to standard output.\n"); + EXIT; +} + + +/***********************************************************************/ +/* read parameters given by command line */ +/***********************************************************************/ +void SHD_read_param (int argc, char *argv[], PROBLEM *PP){ + ITEMSET *II = &PP->II; + int c=1; + if ( argc < c+2 ){ SHD_error (); return; } + PP->problem |= SHD_PRUNE; + if ( !strchr (argv[c], '_') ){ II->flag |= SHOW_MESSAGE; PP->FF.flag |= SHOW_MESSAGE; } + if ( strchr (argv[c], '%') ) II->flag |= SHOW_PROGRESS; + if ( strchr (argv[c], '+') ) II->flag |= ITEMSET_APPEND; + if ( strchr (argv[c], '9') ) PP->problem |= SHD_STRAIGHT; + if ( strchr (argv[c], 'D') ) PP->problem |= SHD_DFS; + if ( strchr (argv[c], 's') ) PP->FF.flag |= (LOAD_SIZSORT + LOAD_DECROWSORT); // sort trsacts + else if ( strchr(argv[c], 'S') ) PP->FF.flag |= LOAD_SIZSORT; // sort trsacts increase order + if ( strchr (argv[c], 'c') ) PP->problem |= SHD_COMPLEMENT; + if ( strchr (argv[c], 't') ) PP->FF.flag |= LOAD_TPOSE; + if ( strchr (argv[c], 'P') ) PP->problem -= SHD_PRUNE; + if ( strchr (argv[c], 'B') ) PP->problem |= SHD_NO_BITMAP; + c++; + + while ( argv[c][0] == '-' ){ + switch (argv[c][1]){ + case 'K': II->topk.end = atoi (argv[c+1]); + break; case 'l': II->lb = atoi (argv[c+1]); + break; case 'u': II->ub = atoi(argv[c+1]); + break; case '#': II->max_solutions = atoi(argv[c+1]); + break; case ',': II->separator = argv[c+1][0]; + break; case 'Q': PP->outperm_fname = argv[c+1]; + break; default: goto NEXT; + } + c += 2; + if ( argc < c+1 ){ SHD_error (); return; } + } + + NEXT:; + PP->FF.fname = argv[c]; + if ( argc>c+1 ) PP->output_fname = argv[c+1]; +} + +int SHD_redundant_check (PROBLEM *PP, QUEUE_ID v, VEC_ID tt){ + QUEUE_INT i, *x, *y, *y_end = PP->OQ[v].v+PP->OQ[v].t, flag = 1, t; + for (y_end=PP->OQ[v].v ; *y_endOQ[v].v+PP->OQ[v].t ; y_end++); + FLOOP (i, 0, PP->FF.clms){ + if ( i == v ) continue; + y = PP->OQ[v].v; t= -1; + MQUE_FLOOP (PP->OQ[i], x){ + if ( *x>=tt ) break; + if ( y >= y_end ) goto END; + if ( *x != *y ) goto END; + t = *x; + y++; + } +// if ( y == y_end ){ flag++; printf ("OK(%d %d) %d\n", v, i, y_end-PP->OQ[v].v); continue; } + if ( y == y_end ){ flag++; continue; } + END:; +//if ( t>-1 && t<1000) printf ("fail (%d %d) = %d %d %d\n", v, i, t, *x, *y); + } + return (flag); +} + +/***************************************************************************/ +/***************************************************************************/ +/***************************************************************************/ + +/**************************************/ +/* straightforward minimality check */ +/* if a subset II->itemset - {i} has intersection to any subset from + 0 to tt, return 0. Otherwise, II->itemset is minimal hitting set + and return 1 */ +/**************************************/ +int SHDstraight_minimality_check (PROBLEM *PP, VEC_ID tt){ + VEC_ID j; + QUEUE_INT *x, *xx, *y; + MQUE_FLOOP (PP->II.itemset, x){ // for each item e, + ARY_FILL (PP->vecmark, 0, tt+1, 0); + MQUE_FLOOP (PP->II.itemset, xx){ // for each item ee!=e + if ( x==xx ) continue; + MQUE_FLOOP ( PP->OQ[*xx], y){ + if ( *y>tt ) break; + PP->vecmark[*y] = 1; // mark transaction including ee + } + } + FLOOP (j, 0, tt+1) if ( PP->vecmark[j]==0 ) goto END; // if a transaction includes no item, then II->itemset-{e} is not minimal +// printf ("okasii %d\n", tt); + return (0); + END:; + } + return (1); +} + +int SHD_minimality_check (PROBLEM *PP, VEC_ID tt){ + VEC_ID i, flag = 1; + QUEUE_ID m; + QUEUE_INT *x, mm=0; + MQUE_FLOOP (PP->II.itemset, x) PP->itemchr[*x] = 2; + + FLOOP (i, 0, tt+1){ + m=0; MQUE_FLOOP (PP->FF.v[i], x) + if ( PP->itemchr[*x] > 1 ){ m++; mm=*x; } + if ( m == 1 ) PP->itemchr[mm] = 3; + } + MQUE_FLOOP (PP->II.itemset, x){ + if ( PP->itemchr[*x] == 2 ) flag = 0; + PP->itemchr[*x] = 1; + } + return (flag); +} +LONG SHD_hitting_check (PROBLEM *PP, VEC_ID tt){ + VEC_ID i; + QUEUE_INT *x; + + MQUE_FLOOP (PP->II.itemset, x) PP->itemchr[*x] = 2; + FLOOP (i, 0, tt+1){ + MQUE_FLOOP (PP->FF.v[i], x) + if ( PP->itemchr[*x] > 1 ) goto END; + printf ("not a hitting set\n"); return (i); + END:; + } + MQUE_FLOOP (PP->II.itemset, x) PP->itemchr[*x] = 1; + return (-1); +} + +/*************************************************************************/ +/* iteration of SHD reverse search with straightforward minimality check */ +/*************************************************************************/ +void SHDstraight (PROBLEM *PP, VEC_ID tt){ + ITEMSET *II = &PP->II; + QUEUE_INT *x; + II->iters++; + + if ( tt == PP->FF.t ){ ITEMSET_output_itemset (II, NULL, 0); return; } + MQUE_FLOOP (PP->FF.v[tt], x) + if ( PP->itemchr[*x] == 1 ){ SHDstraight (PP, tt+1); return; } // tt includes an item of II->itemset, thus go to lower level. + MQUE_FLOOP (PP->FF.v[tt], x){ + QUE_INS (II->itemset, *x); + PP->itemchr[*x] = 1; + if ( SHD_minimality_check(PP, tt) ) SHDstraight (PP, tt+1); + PP->itemchr[*x] = 0; + II->itemset.t--; + } +} + + + +/**************************************/ +/* straightforward minimality check for complement */ +/* if a subset II->itemset - {i} has intersection to any subset from + 0 to tt, return 0. Otherwise, II->itemset is minimal hitting set + and return 1 */ +/* return 1 if minimal */ +/**************************************/ +int SHDstraight_minimality_check_ (PROBLEM *PP, VEC_ID tt){ + QUEUE_INT *x, *xx, *y; + VEC_ID i; +//printf ("########### "); QUEUE_print__ (&PP->II.itemset); + MQUE_FLOOP (PP->II.itemset, x){ // for each item *x, + ARY_FILL (PP->vecmark, 0, tt+1, 0); // clear transaction counter + MQUE_FLOOP (PP->II.itemset, xx){ // for each item *xx!=*x + if ( x==xx ) continue; + MQUE_FLOOP (PP->OQ[*xx], y){ + if ( *y>tt ) break; + PP->vecmark[*y]++; // increase the counter of transaction including ee + } + } +// FLOOP (i, 0, tt+1) printf ("(%d): %d<%d\n", *x, PP->vecmark[i], PP->II.itemset.t-1); + FLOOP (i, 0, tt+1) if ( PP->vecmark[i]==PP->II.itemset.t-1 ) goto END; // if counter is |II->itemset|-1 (including all except for e), then transaction ii includes II->itemset + return (0); + END:; + } + return (1); +} + + +/*************************************************************************/ +/* iteration of SHD (complement) reverse search with straightforward minimality check */ +/* find all minimal itemsets included in no transactions */ +/*************************************************************************/ +void SHDstraight_ (PROBLEM *PP, VEC_ID tt){ + ITEMSET *II = &PP->II; + QUEUE_INT *x, e; + QUEUE_ID i=0, k=0; + + II->iters++; + if ( tt == PP->FF.t ){ ITEMSET_output_itemset (II, NULL, 0); return; } + MQUE_FLOOP (PP->FF.v[tt], x) if ( PP->itemchr[*x]==1 ) k++; + if ( kitemset.t ){ SHDstraight_ (PP, tt+1); return; } // transaction tt does not include II->itemset + FLOOP (e, 0, PP->FF.clms){ + if ( PP->FF.v[tt].v[i]==e ){ i++; continue; } + QUE_INS (II->itemset, e); + if ( SHDstraight_minimality_check_(PP, tt) ){ + PP->itemchr[e] = 1; + SHDstraight_ (PP, tt+1); + PP->itemchr[e] = 0; + } + II->itemset.t--; + } +} + + + +/*************************************************************************/ +/*************************************************************************/ + +/*************************************************************************/ +/* return (minimum) transaction having no intersection to II->itemset */ +/* return -1 if any transaction has non-empty intersection to II->itemset */ +/*************************************************************************/ +LONG SHDdfs_straight_bottom_check (PROBLEM *PP){ + QUEUE_INT *x, *xx; + VEC_ID i; + ARY_FILL (PP->vecmark, 0, PP->FF.t, 1); + MQUE_FLOOP (PP->II.itemset, x) + MQUE_FLOOP (PP->OQ[*x], xx) PP->vecmark[*xx] = 0; + FLOOP (i, 0, PP->FF.t) if ( PP->vecmark[i] ) return (i); + return (-1); +} + +/*************************************************************************/ +/* iteration of SHD backtrack with straightforward minimality check */ +/*************************************************************************/ +void SHDdfs_straight (PROBLEM *PP, QUEUE_INT item){ + ITEMSET *II = &PP->II; + QUEUE_INT i; + II->iters++; + if ( SHDdfs_straight_bottom_check(PP) == -1 ) + { ITEMSET_output_itemset (II, NULL, 0); return; } + FLOOP (i, 0, item){ + QUE_INS (II->itemset, i); + if ( SHDstraight_minimality_check(PP, PP->FF.t-1) ) + SHDdfs_straight (PP, i); + II->itemset.t--; + } +} + + + +/**************************************************************/ +/**************************************************************/ +/**************************************************************/ +/**************************************************************/ + +void SHD_clear_flag (PROBLEM *PP, QUEUE_ID js){ + while (PP->itemjump.t > PP->itemjump.s ) + PP->itemchr[PP->itemjump.v[--PP->itemjump.t]] = 0; + PP->itemjump.s = js; +} + +/*************************************************************************/ +/* return (minimum) transaction including II->itemset */ +/* return -1 if any transaction has non-empty intersection to II->itemset */ +/*************************************************************************/ + +LONG SHDdfs_straight_bottom_check_ (PROBLEM *PP){ + VEC_ID i; + QUEUE_INT *x, *xx; + ARY_FILL (PP->vecmark, 0, PP->FF.t, 0); + MQUE_FLOOP (PP->II.itemset, x) + MQUE_FLOOP (PP->OQ[*x], xx) PP->vecmark[*xx]++; + FLOOP (i, 0, PP->FF.t) + if ( PP->vecmark[i]==PP->II.itemset.t ) return (i); + return (-1); +} + +/*************************************************************************/ +/* iteration of SHD backtrack with straightforward minimality check + for complement input */ +/*************************************************************************/ +void SHDdfs_straight_ (PROBLEM *PP, QUEUE_INT item){ + QUEUE_INT i; + PP->II.iters++; +//printf ("%d :::", item); QUEUE_print__ ( &PP->II.itemset ); + if ( SHDdfs_straight_bottom_check_(PP) == -1 ) + { ITEMSET_output_itemset (&PP->II, NULL, 0); return; } + FLOOP (i, 0, item){ + QUE_INS (PP->II.itemset, i); + if ( SHDstraight_minimality_check_ (PP, PP->FF.t-1) ) + SHDdfs_straight_ (PP, i); + PP->II.itemset.t--; + } +} + + + + + +/*****************************************************/ +/* SHD with simple crit update */ +/*****************************************************/ + +/* check minimality condition */ +void SHD_crit_check (PROBLEM *PP, QUEUE_INT tt){ + MALIST *A = &PP->occ; + QUEUE_INT *x, *t, j, m=0, th = MALIST_HEAD (*A, PP->FF.clms); + unsigned long *a; + + MQUE_FLOOP (PP->FF.v[tt], x){ + if ( PP->itemchr[*x] ){ if ( PP->itemchr[*x]==4 ) PP->II.iters3++; continue; } + PP->II.iters2++; + if ( PP->BA.v && PP->num < PP->OQ[*x].t ){ + m=0; MQUE_FLOOP (PP->II.itemset, t){ + a = &PP->BA.v[(*x) * PP->BA.xend]; + for (j=MALIST_HEAD(*A, *t) ; jend ; j=A->nxt[j]){ +// if ( !(a[j/32]&BITMASK_1[j%32]) ){ + if ( !(a[j/32]&(1<<(j&31))) ){ + ENMAX (m, j); + if ( m > th ) goto END; + goto NEXT; + } + } + m = A->end; + goto END; + NEXT:; + } + } else { + MQUE_FLOOP (PP->OQ[*x], t) PP->FF.v[*t].end = *x; + m=0; MQUE_FLOOP (PP->II.itemset, t){ + for (j=MALIST_HEAD(*A, *t) ; jend ; j=A->nxt[j]){ + if ( PP->FF.v[j].end != *x ){ + ENMAX (m, j); + if ( m > th ) goto END; + goto NEXT2; + } + } + m = A->end; + goto END; + NEXT2:; + } + } + END:; + + if ( m <= th ){ + m=0; MALIST_DO_FORWARD (*A, PP->FF.clms, j) + if ( PP->FF.v[j].end != *x ){ m = 1; break; } + if ( m == 0 ){ + QUE_INS (PP->II.itemset, *x); + ITEMSET_output_itemset (&PP->II, NULL, 0); + PP->II.itemset.t--; + PP->itemchr[*x] = 4; + QUE_INS (PP->itemjump, *x); + } + } else if ( m >= PP->FF.t ){ PP->itemchr[*x] = 4; QUE_INS (PP->itemjump, *x); } + else PP->itemchr[*x] = 1; + } +} + + +/* crit update */ +int SHD_update (PROBLEM *PP, QUEUE_INT e){ + MALIST *A = &PP->occ; + QUEUE_INT j, *t, ttt = MALIST_HEAD(*A, PP->FF.clms); + ALIST_ID tail = A->end + e; // anchor element of list e + unsigned long *a; + + if ( (PP->problem&(SHD_DFS+SHD_PRUNE)) != SHD_PRUNE ) PP->II.iters2++; + if ( PP->BA.v && PP->num < PP->OQ[e].t ){ // bitmap version, when bitmap matrix exists, and PP->OQ[e] is larger than crit + a = &PP->BA.v[e * PP->BA.xend]; + MALIST_DO_FORWARD (*A, PP->FF.clms, j){ + if ( a[j/32]&(1<<(j&31)) ){ + A->list[j] = e; + QUE_INS (PP->vecjump, A->prv[j]); // undo list for uncov + A->nxt[A->prv[j]] = A->nxt[j]; + A->prv[A->nxt[j]] = A->prv[j]; + A->prv[j] = tail; + A->nxt[tail] = j; + tail = j; + } + } + MQUE_FLOOP (PP->II.itemset, t){ + MALIST_DO_FORWARD (*A, *t, j){ + if ( a[j/32]&(1<<(j&31)) ){ + A->nxt[A->prv[j]] = A->nxt[j]; + A->prv[A->nxt[j]] = A->prv[j]; + PP->vecchr[j] = 1; + QUE_INS (PP->veccand, j); // undo list for crit + } + } + } + } else { // set operation version + MQUE_FLOOP (PP->OQ[e], t){ // loop for hyperedges including e + if ( A->list[*t] == PP->FF.clms ){ // t is covered by no item in ITEMSET + A->list[*t] = e; // insert t to the crit list of e + QUE_INS (PP->vecjump, A->prv[*t]); // undo list for uncov + A->nxt[A->prv[*t]] = A->nxt[*t]; + A->prv[A->nxt[*t]] = A->prv[*t]; + A->prv[*t] = tail; + A->nxt[tail] = *t; + tail = *t; + } else if ( PP->vecchr[*t] ) continue; + else { + A->nxt[A->prv[*t]] = A->nxt[*t]; + A->prv[A->nxt[*t]] = A->prv[*t]; + PP->vecchr[*t] = 1; + QUE_INS (PP->veccand, *t); // undo list for crit + } + } + } + PP->num -= PP->veccand.t - PP->veccand.s; // update #hyperedges in (crit+uncov) + A->nxt[tail] = A->end + e; A->prv[A->end + e] = tail; + if ( (PP->problem&(SHD_DFS+SHD_PRUNE)) == SHD_PRUNE ) return(0); + MQUE_FLOOP (PP->II.itemset, t) + if ( MALIST_HEAD (*A, *t) >= PP->FF.t ) return (PP->FF.t); + if ( !(PP->problem&SHD_DFS) ) MQUE_FLOOP (PP->II.itemset, t){ + if ( MALIST_HEAD (*A, *t) > ttt ) return (1); + } + return (0); +} + + +/* recover the update of crit */ +void SHD_recov (PROBLEM *PP, QUEUE_INT e){ + QUEUE_INT *x; + MALIST *A = &PP->occ; + ALIST_ID tt=MALIST_TAIL(*A, e), ttt=A->prv[tt]; // anchor of list e + + MQUE_SBLOOP (PP->vecjump, x){ // for uncov + A->list[tt] = PP->FF.clms; + A->nxt[tt] = A->nxt[*x]; A->nxt[*x] = tt; + A->prv[tt] = *x; A->prv[A->nxt[tt]] = tt; + tt = ttt; ttt = A->prv[tt]; + } + PP->vecjump.t = PP->vecjump.s; + MQUE_SBLOOP (PP->veccand, x){ // for crit + A->nxt[A->prv[*x]] = *x; A->prv[A->nxt[*x]] = *x; + PP->vecchr[*x] = 0; + } + PP->num += PP->veccand.t - PP->veccand.s; // update #hyperedges in (crit+uncov) + PP->veccand.t = PP->veccand.s; +} + + +/* main routine for SHD with simple crit update */ +void SHD (PROBLEM *PP){ + QUEUE *CAND = &PP->itemcand; + VEC_ID tt = MALIST_HEAD (PP->occ, PP->FF.clms); + QUEUE_INT *x, flag, f=PP->problem&SHD_DFS, item; + QUEUE_ID jt, js=PP->itemjump.s, cs=CAND->s, vs=PP->veccand.s, us=PP->vecjump.s; + + // find the transaction with minimum un-deleted vertices, and check whether there is a hyperedge with no un-deleted vertex +QUEUE_INT i, ii; +if (f){ + item = PP->FF.clms; + ii=0; MALIST_DO_FORWARD (PP->occ, PP->FF.clms, i){ + flag = 0; + MQUE_FLOOP (PP->FF.v[i], x) if ( PP->itemchr[*x] == 0 ) flag++; +// if ( f ){ + if ( flag < item ){ item = flag; tt = i; if ( flag==1 ) break;} +// } else { +// if ( flag==0 ){ +// MQUE_FLOOP (PP->FF.v[tt], x) if ( PP->itemchr[*x] == 1 ) PP->itemchr[*x] = 0; +// goto END; +// } +// } + } +} + +// ITEMSET_output_itemset (&PP->II, NULL, 0); // output a solution + +///////// redundancy counting +//item = 1; MQUE_FLOOP (PP->II.itemset, x) item *= SHD_redundant_check (PP, *x, tt); +//if ( item>1 ){ printf ("redandancy %d %d::: ", item, tt); QUEUE_print__ (&PP->II.itemset); } +//////// + + PP->II.outputs2 += PP->II.itemset.t; + PP->II.iters++; // + CAND->s = CAND->t; PP->itemjump.s = PP->itemjump.t; + PP->veccand.s = PP->veccand.t; PP->vecjump.s = PP->vecjump.t; + + if ( (PP->problem&(SHD_DFS+SHD_PRUNE)) == SHD_PRUNE ) SHD_crit_check (PP, tt); + + // make the list of the vertices to be added (recover the vertex mark, when 0 mode) +PP->II.solutions += PP->FF.v[tt].t; // counter + ARY_REALLOCZ (*CAND, PP->FF.v[tt].t + CAND->t, EXIT); + MQUE_FLOOP (PP->FF.v[tt], x){ + if ( PP->itemchr[*x] == 0 ){ + QUE_INS (*CAND, *x); + if ( f ) PP->itemchr[*x] = 4; + } else if ( PP->itemchr[*x] == 1 ) PP->itemchr[*x] = 0; + else if ( (PP->problem&(SHD_DFS+SHD_PRUNE)) != SHD_PRUNE ) PP->II.iters3++; + } + + for (jt=CAND->t ; jt > CAND->s ; ){ +//printf ("call %d: %d\n", *x, PP->itemchr[*x]); + // update crit // + item = CAND->v[--jt]; + + flag = SHD_update (PP, item); // +PP->II.solutions2 += PP->OQ[item].t; // counter + if ( flag >= PP->FF.t && (PP->problem&SHD_PRUNE) ){ + PP->itemchr[item] = 4; QUE_INS (PP->itemjump, item); + } else if ( flag ){ PP->itemchr[item] = 0; + } else { + QUE_INS (PP->II.itemset, item); PP->itemchr[item] = 4; + if ( MALIST_IS_ELM (PP->occ, MALIST_HEAD(PP->occ, PP->FF.clms)) ) SHD (PP); // recursion + else ITEMSET_output_itemset (&PP->II, NULL, 0); // output a solution + PP->itemchr[item] = 0; PP->II.itemset.t--; + } + SHD_recov (PP, item); + } + + MQUE_SLOOP (PP->itemjump, x) PP->itemchr[*x] = 0; + CAND->t = CAND->s; CAND->s = cs; + PP->itemjump.t = PP->itemjump.s; PP->itemjump.s = js; + PP->veccand.s = vs; PP->vecjump.s = us; +} + +/*************************************************************************/ +/* SHD for complement input */ +/*************************************************************************/ + +/* check minimality condition */ +void SHDC_crit_check (PROBLEM *PP, QUEUE_INT tt, QUEUE_INT prv){ + QUEUE_INT *x = PP->FF.v[tt].v, *t, item, m, u, b=PP->II.itemset.t-1; + + FLOOP (item, 0, PP->FF.clms){ + if ( item == *x ){ x++; continue; } + if ( PP->itemchr[item] ){ if ( PP->itemchr[*x]==4 ) PP->II.iters3++; continue; } + PP->II.iters2++; + u = PP->FF.t; MQUE_FLOOP (PP->II.itemset, t) PP->itemary[*t] = PP->FF.t; + MQUE_FLOOP (PP->OQ[item], t){ + if ( PP->vecflag[*t] < b ) continue; + if ( PP->vecflag[*t] == b ){ // for crit + if ( PP->vecmark[*t] == PP->FF.clms ) ENMIN (PP->itemary[prv], *t); + else ENMIN (PP->itemary[PP->vecmark[*t]], *t); + } else ENMIN (u, *t); // for uncov + } + m = 0; MQUE_FLOOP (PP->II.itemset, t) ENMAX (m, PP->itemary[*t]); + if ( m <= tt ){ + if ( u == PP->FF.t ){ + QUE_INS (PP->II.itemset, item); + ITEMSET_output_itemset (&PP->II, NULL, 0); + PP->II.itemset.t--; + PP->itemchr[item] = 4; + QUE_INS (PP->itemjump, item); + } + } else if ( m >= PP->FF.t ){ PP->itemchr[item] = 4; QUE_INS (PP->itemjump, item); } + else PP->itemchr[item] = 1; + } +} + +/* crit update for DFS version */ +int SHDC_update (PROBLEM *PP, QUEUE_INT e, QUEUE_INT *u, QUEUE_INT *h, QUEUE_INT prv){ + QUEUE_INT *t, z, b=PP->II.itemset.t-1; + + if ( (PP->problem&(SHD_DFS+SHD_PRUNE)) != SHD_PRUNE ) PP->II.iters2++; + *u = PP->FF.t; + MQUE_FLOOP (PP->II.itemset, t) PP->itemary[*t] = PP->FF.t; +//fprintf (stderr, "%d::: ", e); QUEUE_print__ (&PP->OQ[e]); + MQUE_FLOOP (PP->OQ[e], t){ + if ( PP->vecflag[*t] < b ) continue; + if ( PP->vecflag[*t] == b ){ // for crit + if ( PP->vecmark[*t] == PP->FF.clms ) PP->vecmark[*t] = prv; + ENMIN (PP->itemary[PP->vecmark[*t]], *t); + } else ENMIN (*u, *t); // for uncov + PP->vecflag[*t]++; // increament to write "latest" + } + z = 0; MQUE_FLOOP (PP->II.itemset, t) ENMAX (z, PP->itemary[*t]); +//printf ("flag=%d, *u=%d\n", z, *u); + return (z); +} + +/* recover the update of crit, for DFS version (simpler) */ +void SHDC_recov (PROBLEM *PP, QUEUE_INT e, QUEUE_INT prv){ + QUEUE_INT *t, b=PP->II.itemset.t; + MQUE_FLOOP (PP->OQ[e], t){ + if ( PP->vecflag[*t] < b ) continue; + PP->vecflag[*t]--; + if ( PP->vecmark[*t] == prv ) PP->vecmark[*t] = PP->FF.clms; + } +} + +/* main routine for SHD with simple crit update */ +void SHDC (PROBLEM *PP, QUEUE_INT prv, VEC_ID tt){ + QUEUE *CAND = &PP->itemcand; + QUEUE_INT u=0, *x, flag, f=PP->problem&SHD_DFS, item;// *y; + QUEUE_ID jt, js=PP->itemjump.s, cs=CAND->s; // vt=PP->veccand.t; + +// printf ("ITEMSET "); QUEUE_print__ (&PP->II.itemset); +// printf ("tt=%d\n", tt); +// FLOOP (flag, 0, 6) printf (" %d", PP->itemchr[flag]); printf ("\n"); + PP->II.iters++; // + CAND->s = CAND->t; PP->itemjump.s = PP->itemjump.t; + + if ( (PP->problem&(SHD_DFS+SHD_PRUNE)) == SHD_PRUNE ) SHDC_crit_check (PP, tt, prv); + + ARY_REALLOCZ (*CAND, (PP->FF.clms-PP->FF.v[tt].t) + CAND->t, EXIT); + +PP->II.solutions += PP->FF.clms; // counter + x = PP->FF.v[tt].v; + FLOOP (item, 0, PP->FF.clms){ + if ( item == *x ){ x++; continue; } + if ( PP->itemchr[item] == 0 ){ + QUE_INS (*CAND, item); + if ( f ) PP->itemchr[item] = 4; + } else if ( PP->itemchr[item] == 1 ) PP->itemchr[item] = 0; + else if ( (PP->problem&(SHD_DFS+SHD_PRUNE)) != SHD_PRUNE ) PP->II.iters3++; + } + + if ( f ) tt = PP->FF.t-1; + for ( jt=CAND->t ; jt > CAND->s ; ){ +//printf ("call %d: %d\n", *x, PP->itemchr[*x]); + // update crit // + item = CAND->v[--jt]; +PP->II.solutions2 += PP->OQ[item].t; // counter + if ((flag=SHDC_update (PP,item,&u,&PP->OQ[item].t,prv))>=PP->FF.t && (PP->problem&SHD_PRUNE)){ + PP->itemchr[item] = 4; QUE_INS (PP->itemjump, item); + } else if ( flag > tt ){ PP->itemchr[item] = 0; + } else { + QUE_INS (PP->II.itemset, item); PP->itemchr[item] = 4; + if ( u < PP->FF.t ) SHDC (PP, item, u); // recursion + else ITEMSET_output_itemset (&PP->II, NULL, 0); // output a solution + PP->itemchr[item] = 0; PP->II.itemset.t--; + } + SHDC_recov (PP, item, prv); + } + + MQUE_SLOOP (PP->itemjump, x) PP->itemchr[*x] = 0; + CAND->t = CAND->s; CAND->s = cs; + PP->itemjump.t = PP->itemjump.s; PP->itemjump.s = js; // PP->veccand.t = vt; +} + +/* find all hitting set of size 1, and remove them from the data */ +void SHD_output_single (PROBLEM *PP){ + QUEUE_INT item, *xx, *x; + VEC_ID t; + + FLOOP (item, 0, PP->FF.clms){ + if ( ( !(PP->problem&SHD_COMPLEMENT) && PP->OQ[item].t == PP->FF.t ) + || ( (PP->problem&SHD_COMPLEMENT) && PP->OQ[item].t == 0) ){ + QUE_INS (PP->II.itemset, item); + ITEMSET_output_itemset (&PP->II, NULL, 0); // output a solution + PP->II.itemset.t--; + PP->itemchr[item] = 4; // forbid to add + } + } + FLOOP (t, 0, PP->FF.t){ + xx = PP->FF.v[t].v; + MQUE_FLOOP (PP->FF.v[t], x){ + if ( PP->itemchr[*x] == 0 ){ + if ( x != xx ) *xx = *x; + xx++; + } + } + PP->FF.v[t].t = xx - PP->FF.v[t].v; + } +} + + +/*************************************************************************/ +/* main of SHD */ +/*************************************************************************/ +int SHD_main (int argc, char *argv[]){ + PROBLEM PP; + int f=0; + QUEUE_INT i; + + PROBLEM_init (&PP); + SHD_read_param (argc, argv, &PP); +if ( ERROR_MES ) return (1); + + PP.FF.flag |= LOAD_RM_DUP + LOAD_INCSORT; +// + TRSACT_DELIVERY; + PROBLEM_load (&PP); +if ( ERROR_MES ) goto END; + if ( PP.problem & SHD_STRAIGHT ) f |= PROBLEM_VECMARK; + else { + f |= PROBLEM_ITEMJUMP; + if ( PP.problem & SHD_COMPLEMENT ) f |= PROBLEM_VECMARK +PROBLEM_VECFLAG +PROBLEM_ITEMARY; + else f |= PROBLEM_VECCHR + PROBLEM_VECCAND + PROBLEM_VECJUMP; + } + PROBLEM_alloc (&PP, PP.FF.clms, PP.FF.t, PP.FF.t, NULL, PROBLEM_ITEMCHR + PROBLEM_ITEMCAND + f); + +// delivery + ARY_FILL (PP.itemcand.v, 0, PP.FF.clms+1, 0); + QUEUE_delivery(NULL, PP.itemcand.v, NULL, PP.FF.v, NULL, PP.FF.t, PP.FF.clms); + MQUE_ALLOC (PP.OQ, PP.FF.clms, PP.itemcand.v, 0, 1, EXIT); + QUEUE_delivery (PP.OQ, NULL, NULL, PP.FF.v, NULL, PP.FF.t, PP.FF.clms); + FLOOP (i, 0, PP.FF.clms) PP.OQ[i].v[PP.OQ[i].t] = PP.FF.t; // put endmark + if ( (PP.problem&(SHD_DFS+SHD_PRUNE)) == SHD_PRUNE ) + FLOOP (i, 0, PP.FF.t) PP.FF.v[i].end = PP.FF.clms; + if ( !(PP.problem&SHD_STRAIGHT) ) SHD_output_single (&PP); // output all minimal hitting sets of size one + PP.num = PP.FF.t; // #hyperedges in ( crit and uncov) + + // initialization for bitmap matrix + if ( !(PP.problem&(SHD_NO_BITMAP+SHD_COMPLEMENT)) && ((size_t)PP.FF.clms)*PP.FF.t/64 <= PP.FF.eles ){ + BARRAY_init (&PP.BA, PP.FF.t, PP.FF.clms); + i=0; FLOOP (f, 0, PP.FF.clms){ + BARRAY_set_subset (&PP.BA.v[i], &PP.OQ[f]); + i += PP.BA.xend; + } + } // SETFAMILY_to_BARRAY (&PP.BA, &PP.FF); + + if ( (PP.problem & SHD_STRAIGHT) == 0 ){ + if ( PP.problem & SHD_COMPLEMENT ){ + ARY_FILL (PP.vecmark, 0, PP.FF.t, PP.FF.clms); +// QUEUE_alloc (&PP.veccand, PP.FF.clms); +// FLOOP (i, 0, PP.FF.clms) QUE_INS (PP.veccand, i); + } else { + MALIST_alloc (&PP.occ, PP.FF.t, PP.FF.clms+2); // element=> + FLOOP (i, 0, PP.FF.t) MALIST_ins_tail (&PP.occ, PP.FF.clms, i, 0); + } + } + +/////// +//FLOOP (i, 0, PP.FF.clms) SHD_redundant_check (&PP, i, PP.FF.t); + +////// + +// main routines + if ( PP.problem&SHD_STRAIGHT ){ + if ( PP.problem&SHD_DFS ) + if ( PP.problem&SHD_COMPLEMENT ) SHDdfs_straight_(&PP, PP.FF.clms); + else SHDdfs_straight (&PP, PP.FF.clms); + else if ( PP.problem&SHD_COMPLEMENT ) SHDstraight_(&PP, 0); else SHDstraight (&PP, 0); + } else { + if ( PP.problem&SHD_COMPLEMENT ) SHDC (&PP, 0, 0); + else SHD (&PP); + } + + ITEMSET_last_output (&PP.II); + print_mes (&PP.II, "#iterations= %lld ,#min_check= %lld ,#pruning= %lld\n", PP.II.iters, PP.II.iters2, PP.II.iters3); + print_mes (&PP.II, "ave_cost_for_F(e)= %f ,ave_cost_for_CAND= %f ,ave_internal_sol.= %f\n", ((double)PP.II.solutions2)/PP.II.iters, ((double)PP.II.solutions)/PP.II.iters, ((double)PP.II.outputs2)/PP.II.iters); + END:; + PROBLEM_end (&PP); + + return (ERROR_MES?1:0); +} + +/*******************************************************************************/ +#ifndef _NO_MAIN_ +#define _NO_MAIN_ +int main (int argc, char *argv[]){ + return (SHD_main (argc, argv)); +} +#endif +/*******************************************************************************/ + +#endif + + diff --git a/rql-backend/shd31/sortout.pl b/rql-backend/shd31/sortout.pl new file mode 100644 index 0000000..7f7e8c6 --- /dev/null +++ b/rql-backend/shd31/sortout.pl @@ -0,0 +1,41 @@ +#!/usr/bin/perl + +# input: a file each whose line is a sequence of numbers +# output: the file obtained by (1) sorting each line in increasing order, +# (2) sort the lines in the increasing order (as strings ) +# the input file is read from standard input, and the result is output to +# the standard output +# We can specify the separator of the number, by the first parameter + +$ARGC = @ARGV; +if ( $ARGC < 0 ){ + printf ("sortout.pl: [separator] < input-file > output-file\nif separator is '-', do not sort the lines"); + exit (1); +} +$count = 0; +%numbers = (); +$m=0; +$linesort = 1; + +$sep = " "; +if ( $ARGC > 0 ){ + if ( $ARGV[0] eq "-" ){ $linesort = 0; } + else { $sep = $ARGV[0]; } +} +while (){ + chomp; + @eles = split($sep, $_); + @eles = sort { $a <=> $b } (@eles); + foreach $cell(@eles){ + if ( $cell == 0 ){ + if (index ( $cell, "0") >= 0 ){ $lines2[$m] .= $cell." "; } + } else { $lines2[$m] .= $cell." "; } + } + $m++; +} +if ( $linesort == 1 ){ @lines2 = sort (@lines2); } +for ( $mm=0 ; $mm<$m ; $mm++ ){ + print "$lines2[$mm]\n"; +} + + diff --git a/rql-backend/shd31/stdlib2.c b/rql-backend/shd31/stdlib2.c new file mode 100644 index 0000000..5473d12 --- /dev/null +++ b/rql-backend/shd31/stdlib2.c @@ -0,0 +1,1282 @@ +/* library for standard macros and functions */ +/* by Takeaki Uno 2/22/2002, e-mail: uno@nii.jp + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + +#ifndef _stdlib2_c_ +#define _stdlib2_c_ + +#include"stdlib2.h" +#ifdef MTWISTER +#include"dSFMT.c" +#endif + +size_t common_size_t; +INT common_INT, common_INT2; +char *common_charp, *common_pnt; +FILE *common_FILE; +FILE2 common_FILE2; +PERM common_PERM; +char common_comm[1024], common_comm2[1024], *common_argv[100]; // max. command length = 2048, max. #params = 100 + +char *ERROR_MES = NULL; +int print_time_flag=0; +PARAMS internal_params; +#ifdef MULTI_CORE +int SPIN_LOCK_dummy; +#endif +FILE2 INIT_FILE2 = {TYPE_FILE2,NULL,NULL,NULL,NULL,0}; +VEC INIT_VEC = {TYPE_VEC,NULL,0,0}; +FILE_COUNT INIT_FILE_COUNT = {0,0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,0,0,NULL,NULL,0,0,NULL,NULL}; +short FILE2_POW[5] = {1, 10, 100, 1000, 10000}; + +QSORT_TYPE (int, int) +QSORT_TYPE (uint, unsigned int) +QSORT_TYPE (double, double) +QSORT_TYPE (char, char) +QSORT_TYPE (uchar, unsigned char) +QSORT_TYPE (short, short) +QSORT_TYPE (ushort, unsigned short) +QSORT_TYPE (WEIGHT, WEIGHT) +QSORT_TYPE (LONG, LONG) +QSORT_TYPE (VEC_ID, VEC_ID) +QSORT_TYPE (VEC_VAL, VEC_VAL) +QSORT_TYPE (VEC_VAL2, VEC_VAL2) +QSORT_TYPE (FILE_COUNT_INT, FILE_COUNT_INT) + + /* bitmasks, used for bit operations */ +int BITMASK_UPPER1[32] = { 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, + 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, + 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, + 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, + 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, + 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, + 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, + 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000 }; +int BITMASK_UPPER1_[32] = { 0xfffffffe, 0xfffffffc, 0xfffffff8, 0xfffffff0, + 0xffffffe0, 0xffffffc0, 0xffffff80, 0xffffff00, + 0xfffffe00, 0xfffffc00, 0xfffff800, 0xfffff000, + 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000, + 0xfffe0000, 0xfffc0000, 0xfff80000, 0xfff00000, + 0xffe00000, 0xffc00000, 0xff800000, 0xff000000, + 0xfe000000, 0xfc000000, 0xf8000000, 0xf0000000, + 0xe0000000, 0xc0000000, 0x80000000, 0x00000000 }; + +int BITMASK_LOWER1[32] = { 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, + 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, + 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, + 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, + 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff }; +int BITMASK_LOWER1_[32] = { 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, + 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, + 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, + 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, + 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, + 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, + 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff }; + +int BITMASK_1[32] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x00000100, 0x00000200, 0x00000400, 0x00000800, + 0x00001000, 0x00002000, 0x00004000, 0x00008000, + 0x00010000, 0x00020000, 0x00040000, 0x00080000, + 0x00100000, 0x00200000, 0x00400000, 0x00800000, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000 }; +int BITMASK_31[32] = { 0xfffffffe, 0xfffffffd, 0xfffffffb, 0xfffffff7, + 0xffffffef, 0xffffffdf, 0xffffffbf, 0xffffff7f, + 0xfffffeff, 0xfffffdff, 0xfffffbff, 0xfffff7ff, + 0xffffefff, 0xffffdfff, 0xffffbfff, 0xffff7fff, + 0xfffeffff, 0xfffdffff, 0xfffbffff, 0xfff7ffff, + 0xffefffff, 0xffdfffff, 0xffbfffff, 0xff7fffff, + 0xfeffffff, 0xfdffffff, 0xfbffffff, 0xf7ffffff, + 0xefffffff, 0xdfffffff, 0xbfffffff, 0x7fffffff }; + +int BITMASK_16[8] = { 0x0000000f, 0x000000f0, 0x00000f00, 0x0000f000, + 0x000f0000, 0x00f00000, 0x0f000000, 0xf0000000 }; +int BITMASK_UPPER16[8] = { 0xffffffff, 0xfffffff0, 0xffffff00, 0xfffff000, + 0xffff0000, 0xfff00000, 0xff000000, 0xf0000000 }; +int BITMASK_LOWER16[8] = { 0x0000000f, 0x000000ff, 0x00000fff, 0x0000ffff, + 0x000fffff, 0x00ffffff, 0x0fffffff, 0xffffffff }; +int BITMASK_FACT16[8] = { 0x1, 0x10, 0x100, 0x1000, + 0x10000, 0x100000, 0x1000000,0x10000000 }; + + +/* free many pointers */ +void mfree_(void *x, ...){ + va_list argp; + void *a; + va_start (argp, x); + while((a = va_arg(argp, void *)) != (void*)1){ free2 (a); } + va_end (argp); +} +/* free many pointers */ +void mfree2_(void *x, ...){ + va_list argp; + void *a; + va_start (argp, x); + while((a = va_arg(argp, void *)) != (void*)1){ free2 (*((char **)a)); } + va_end (argp); +} +/* remove many files */ +void mremove_ (char *x, ...){ + va_list argp; + char *a; + va_start (argp, x); + while((a = va_arg(argp, char *))){ + sprintf (common_comm, "%s%s", x, a); + remove (common_comm); + } + va_end (argp); +} + +/* compute the minimum prime no less than n */ +#define MINPRIME_END 6000 +LONG min_prime (LONG n){ + LONG i, j=30, k; + char f[MINPRIME_END]; + while(1) { + FLOOP (i, 0, j) f[i]=0; + for ( i=3 ; i*i < n+j ; i+=2 ) + for ( k=((n+i-1)/i)*i ; k>19))^(t^(t>>8)) ); +} + +/***********************************************************************/ +/***********************************************************************/ +#ifdef USE_MATH +#define NORMAL_RAND_BASE 2147483648LL + +double SQRT(double x){ +#ifdef USE_SIMD + __m128d a; + a = _mm_load1_pd (&x); + _mm_sqrt_pd (a); + _mm_storel_pd (&x, a); +#else + x = sqrt (x); +#endif + return (x); +} +/* make two random numbers under normal distribution N(0,1) */ +void rand_mk_2normal (double *a, double *b){ + double r1, r2; + do { + r1 = RAND1; + } while (r1==0); + r2 = RAND1; + r1 = sqrt(-log(r1)*2); + r2 *= 2*PI; + *a = r1*sin(r2); + *b = r1*cos(r2); +} + +/* make a random point on a supersphere of d-dim., and set to double array already allocated */ +void rand_d_gaussian (double *p, int d){ + int i; + double a, b; + for (i=0 ; i 0.000001 ){ + if ( sphere_prob (d, (t+s)/2) > m ) s = (t+s)/2; + else t = (t+s)/2; + } + return (s); +} + + +#endif + +/******************** file I/O routines ********************************/ + +int FILE_err; /* signals 0: for normal termination + 1: read a number, then encountered a newline, + 2: read a number, then encountered the end-of-file + 5: read no number, and encountered a newline + 6: read no number, and encountered the end-of-file */ + + +void FILE2_flush (FILE2 *fp){ + if ( fp->buf > fp->buf_org+FILE2_BUFSIZ/2 ){ + fwrite (fp->buf_org, fp->buf-fp->buf_org, 1, fp->fp); + *fp->buf_org = *fp->buf; + fp->buf = fp->buf_org; + } +} +void FILE2_flush_last (FILE2 *fp){ + if ( fp->bit > 0 ) fp->buf++; + if ( fp->buf > fp->buf_org ){ + fwrite ( fp->buf_org, fp->buf-fp->buf_org, 1, fp->fp); + fp->buf = fp->buf_org; + } +} +void FILE2_close (FILE2 *fp){ + fclose2 (fp->fp); + free2 (fp->buf_org); + fp->buf = fp->buf_end = 0; +} +void FILE2_closew (FILE2 *fp){ + FILE2_flush_last (fp); + fclose2 (fp->fp); + free2 (fp->buf_org); + fp->buf = fp->buf_end = 0; +} +void FILE2_reset (FILE2 *fp){ + fp->buf = fp->buf_org; + fp->buf_end = fp->buf_org-1; + fseek (fp->fp, 0, SEEK_SET); +} +/* fast file routine, getc, putc, puts, */ +int FILE2_getc (FILE2 *fp){ + int c; + if ( fp->buf >= fp->buf_end ){ + if ( (fp->buf_end < fp->buf_org+FILE2_BUFSIZ) && (fp->buf_end>=fp->buf_org) ){ FILE_err=2; return (-1); } + fp->buf = fp->buf_org; + fp->buf_end = fp->buf_org + fread (fp->buf, 1, FILE2_BUFSIZ, fp->fp); + return (FILE2_getc (fp)); + } + c = (unsigned char)(*(fp->buf)); + fp->buf++; + return (c); +} +void FILE2_puts (FILE2 *fp, char *s){ + while ( *s != 0 ){ + *(fp->buf) = *s; + s++; + fp->buf++; + } +} +void FILE2_putc (FILE2 *fp, char c){ + *(fp->buf) = c; + fp->buf++; +} +int FILE2_getbit (FILE2 *fp){ + int a; + unsigned char *p; + if ( fp->buf >= fp->buf_end ){ + if ( (fp->buf_end < fp->buf_org+FILE2_BUFSIZ) && (fp->buf_end>=fp->buf_org) ){ FILE_err=2; return (-1); } + fp->buf = fp->buf_org; + fp->buf_end = fp->buf_org + fread (fp->buf, 1, FILE2_BUFSIZ, fp->fp); + } + p = (unsigned char *)fp->buf; a = (*p) %2; (*p) /=2; + if ( (++fp->bit) == 8 ){ fp->bit = 0; fp->buf++; } + return (a); +} +void FILE2_putbit (FILE2 *fp, int a){ // a is non-zero => 1 + if ( a ){ + a = 1 << fp->bit; + *fp->buf |= a; + } + if ( (++fp->bit) == 8 ){ + fp->bit = 0; + fp->buf++; + FILE2_flush (fp); + *fp->buf = 0; + } +} + +/* fast file routine, print number, c is the char to be printed preceding to the number + if c==0, nothing will be printed preceding the number + if len<0 then the #digits following '.' does not change (filed by '0') */ +void STR_print_int (char **s, LONG n, char c){ + LONG nn = n; + char *ss; + if ( c ){ **s = c; (*s)++; } + if ( n == 0 ){ **s = '0'; (*s)++; return; } + if ( n < 0 ){ **s = '-'; (*s)++; n = -n; } + while ( nn>99999 ){ nn /= 1000000; (*s)+=6; } + while ( nn>99 ){ nn /= 1000; (*s)+=3; } + while ( nn>0 ){ nn /= 10; (*s)++; } + ss = (*s)-1; + **s = 0; + while ( n>0 ){ *ss = '0'+(char)(n%10); ss--; n/=10; } +} +void STR_print_int_ (char **s, LONG n, int len, char c){ + char *ss; + if ( c ){ **s = c; (*s)++; } + if ( n == 0 ){ **s = '0'; (*s)++; return; } + if ( n < 0 ){ **s = '-'; (*s)++; n = -n; } + (*s)+=len; + ss = (*s)-1; + **s = 0; + while ( len>0 ){ *ss = '0'+(char)(n%10); ss--; n/=10; len--; } +} +void FILE2_print_int (FILE2 *fp, LONG n, char c){ + STR_print_int (&(fp->buf), n, c); +} +/* print a real number to string pointed by *s, + (print_reale prints in format "x.xxxxxe+10e" + [len] is #decimal digits to be printed + for speeding up, give 10^{len} as [len], when len >1 */ +void STR_print_reale (char **s, double n, int len, char c){ + int flag=0, d=0, dd; + LONG nn; + + if ( len >= 100 ) nn = len; + else { + nn = 1; + while ( len >= 9 ){ nn *= 1000000000; len -= 9; } + while ( len >= 3 ){ nn *= 1000; len -= 3; } + while ( len >= 1 ){ nn *= 10; len --; } + } + + if ( c ){ **s = c; (*s)++; } + if ( n<0 ){ **s = c; (*s)++; n = -n; } + if ( n<1 ){ + flag = 1; + while ( n < 0.00000001 ){ d+=9; n *= 1000000000;} + while ( n < 0.01 ){ d+=3; n *= 1000;} + while ( n < 1 ){ d++; n *= 10;} + } else { + while ( n >= 1000000000 ){ d+=9; n /= 1000000000;} + while ( n >= 1000 ){ d+=3; n /= 1000;} + while ( n >= 10 ){ d++; n /= 10;} + } + + dd = n; **s = '0' + dd; (*s)++; n -= dd; + **s = '.'; (*s)++; + nn = n*nn; STR_print_int (s, nn, 0); + while ( *(*s -1) == '0' ) (*s)--; + if ( *(*s -1) == '.' ) (*s)--; + **s = 'e'; (*s)++; **s = flag? '-': '+'; (*s)++; + STR_print_int (s, d, 0); + **s = 0; +} +void FILE2_print_reale (FILE2 *fp, double n, int len, char c){ + STR_print_reale (&(fp->buf), n, len, c); +} +/* print a real number to string pointed by *s */ +void STR_print_real (char **s, double n, int len, char c){ + int flag=1, d=0, dd, ll = len; + LONG nn; + + if ( c ){ **s = c; (*s)++; } + if ( n<0 ){ **s = '-'; (*s)++; n = -n; } + if ( n<1 ){ **s = '0'; (*s)++; } + else { + while ( n > (1LL<<60) ){ d++; n /= (1000000000000000000LL);} + nn = n; STR_print_int (s, nn, 0); + BLOOP (d, d, 0) FLOOP (dd, 0, 18){ **s = '0'; (*s)++; } + n -= nn; + } + if ( len == 0 ) return; // no decimal digits + **s = '.'; (*s)++; + if ( len<0 ){ len = -len; flag = 0; } + nn = 1; + if ( len >= 100 ) nn = len; + else { + while ( len >= 6 ){ nn *= 1000000; len -= 6; } + while ( len >= 3 ){ nn *= 1000; len -= 3; } + while ( len >= 1 ){ nn *= 10; len --; } + } + nn = n*nn; + STR_print_int_ (s, nn, ll, 0); + if ( flag ){ + while ( *(*s -1) == '0' ) (*s)--; + if ( *(*s -1) == '.' ) (*s)--; + } + **s = 0; +} +void FILE2_print_real (FILE2 *fp, double n, int len, char c){ + STR_print_real (&(fp->buf), n, len, c); +} +void FILE2_print_real__ (FILE2 *fp, double n, int len, char c){ + int i=0, flag=1, d=0, dd=0; + char *back; + LONG nn; + + if ( c ) FILE2_putc (fp, c); + if ( n<0 ){ FILE2_putc (fp, '-'); n *= -1; } + if ( n<1 ){ *(fp->buf) = '0'; fp->buf++; } + else { + while ( n > (1LL<<60) ){ d++; n /= (1000000000000000000LL);} + nn = n; FILE2_print_int (fp, nn, 0); + BLOOP (d, d, 0) FLOOP (dd, 0, 18) FILE2_putc (fp, '0'); + n -= nn; + } + if ( len == 0 ) return; // no digits smaller than 1 + *(fp->buf) = '.'; back = fp->buf; + fp->buf++; + if ( len<0 ){ len = -len; flag = 0; } + for (d=0 ; len>0 ; len--){ + if ( d==0 ){ + d = 4; + n *= 10000.0; + dd = n; + n -= dd; + } + if ( --d > 0 ){ + i = dd/FILE2_POW[d]; + dd -= i*FILE2_POW[d]; + } + *(fp->buf) = '0'+i; + fp->buf++; + if ( i>0 ) back = fp->buf; + } + if ( flag ) fp->buf = back; +} +void FILE2_print_real_ (FILE2 *fp, double n, int len, char c){ + int i=0, flag=1; + double j=1; + char *back; + + if ( c ) FILE2_putc (fp, c); + if ( n<0 ){ FILE2_putc (fp, '-'); n *= -1; } + while ( n >= j ) j*=10; + if ( j==1 ){ *(fp->buf) = '0'; fp->buf++; } + else while ( j>1 ){ + j /= 10; + i = (int)(n/j); + *(fp->buf) = '0'+i; + n -= j*i; + fp->buf++; + } + *(fp->buf) = '.'; back = fp->buf; + fp->buf++; + if ( len<0 ){ len = -len; flag = 0; } + for ( ; len>0 ; len--){ + n *= 10.0; + i = (int)n; + *(fp->buf) = '0'+i; + n -= i; + fp->buf++; + if ( i>0 ) back = fp->buf; + } + if ( flag ) fp->buf = back; +} +/******/ +void FILE2_print_WEIGHT (FILE2 *fp, WEIGHT w, int len, char c){ +#ifdef WEIGHT_DOUBLE + FILE2_print_real(fp, w, len, c); +#else + FILE2_print_int(fp, w, c); +#endif +} + +// print integer to file in a bit string manner +// first bit 0 -> 0to127 +// 10 -> 128 to 16384+127 +// 110 -> 16384+128 to 32*65536+16384+127 +// 1110 -> ... to 16* +// max: limit of the bit length +void FILE2_print_mpint (FILE2 *fp, LONG a, int max, int skip){ + int i=0, bb; + LONG b, x=0; + bb = 1<= b ){ x += b; b *= bb; i++; if ( (i+1)*skip >= max ) break; } + a -= x; + FLOOP (x, 0, i) FILE2_putbit (fp, 1); // length of the integer + if ( (i+1)*skip < max ) FILE2_putbit (fp, 0); // end mark + else for ( ; max < (i+1)*skip ; max++, b/=2); + for (b/=2 ; b>0 ; b/=2) FILE2_putbit (fp, (a&b)>0); +} + +LONG FILE2_read_mpint (FILE2 *fp, int max, int skip){ + LONG a, b, x=0; + int i=0, j, bb; + for (b=bb=1<= max ){ + for ( ; max < (i+2)*skip ; max++, b/=2); + break; + } + } + for (a=0 ; b>1 ; b/=2) a = a*2 + FILE2_getbit(fp); + return (a+x); +} +/* print lowest k bits to file */ +void FILE2_print_intbit (FILE2 *fp, LONG a, int k){ + LONG b= 1LL << (k-1); + while (b>0){ FILE2_putbit (fp, (a&b)>0); b /= 2; } +} +/* read k bits from file as integer */ +LONG FILE2_read_intbit (FILE2 *fp, int k){ + LONG a=0; + while (k-->0){ a = a*2 + FILE2_getbit (fp); } + return (a); +} + +#define FILE2_READ_CH(v) \ + +//#define FILE2_READ_(v) + +/* Read an integer/a double from the file and return it, + with read through the non-numeric letters. + If it reaches to the end-of-file just after reading a number, then set FILE_err=2, + if it reads a newline just after reading a number, then set FILE_err=1. + If read either the end-of-file or newline before reading an integer, + return 5, and 6 */ +FILE_LONG FILE2_read_int (FILE2 *fp){ + FILE_LONG item; + int sign=1, ch; + FILE_err = 0; + while (1){ + ch = FILE2_getc(fp); + if ( ch>='0' && ch<='9' ) break; + if ( ch == '\n' ){ FILE_err = 5; return (-INTHUGE); } + if ( ch < 0 ){ FILE_err = 6; return (-INTHUGE); } + if ( ch=='-' ) sign = -1; + } + for (item=ch-'0' ; 1 ; item=item*10 +ch-'0'){ + ch = FILE2_getc(fp); + if ( ch<'0' || ch>'9' ){ + if ( ch == '\n' ) FILE_err = 1; + if ( ch < 0 ) FILE_err = 2; + return (item*sign); + } + } +} +double FILE2_read_double (FILE2 *fp){ + double item, geta=1; + int sign=1, ch, n=0, d, flag=0; + FILE_err = 0; + while (1){ + ch = FILE2_getc(fp); + if ( ch<'0' || ch>'9' ){ + if ( ch == '\n' ){ FILE_err = 5; return (-DOUBLEHUGE); } + if ( ch < 0 ){ FILE_err = 6; return (-DOUBLEHUGE); } + if ( ch=='-' ) sign = -1; + else if ( ch=='.' ){ flag = 1; geta = 0.1; } + else { sign = 1; geta = 1; flag = 0; } + } else break; + } + item = 0; d = 0; item = ch-'0'; if ( flag ) item /= 10; + + while (1){ + ch = FILE2_getc(fp); + if ( ch < '0' || ch > '9' ){ + if ( ch == '\n' ){ FILE_err = 1; break; } + else if ( ch < 0 ){ FILE_err = 2; break; } + else if ( ch == '.' ){ // decimal + if ( flag ) break; // second decimal; illigal syntax + if ( d ) item = item * FILE2_POW[d] + n; + flag = 1; n = 0; d = 0; + } else if ( (ch & 0xdf) == 'E' ){ // power + if ( d ){ + if ( flag ) item += geta * n / FILE2_POW[d]; + else item = item * FILE2_POW[d] + n; + } + flag = n = 0; + ch = FILE2_getc(fp); + if ( ch == '-' ){ flag = 1; ch = FILE2_getc(fp); } // power is minus + else if ( ch == '+' ) ch = FILE2_getc(fp); // power is plus + else if ( ch < '0' || ch > '9') break; + for ( n=ch-'0' ; 1 ; n=n*10 + ch-'0' ){ + ch = FILE2_getc(fp); + if ( ch<'0' || ch>'9' ){ + if ( ch == '\n' ) FILE_err = 1; + if ( ch < 0 ) FILE_err = 2; + if ( flag ){ + while ( n>=9 ){ item /= 1000000000.0; n -= 9; } + while ( n>=3 ){ item /= 1000.0; n -= 3; } + while ( n>=1 ){ item /= 10.0; n --; } + } else { + while ( n>=9 ){ item *= 1000000000.0; n -= 9; } + while ( n>=3 ){ item *= 1000.0; n -= 3; } + while ( n>=1 ){ item *= 10.0; n --; } + } + return (item*sign); + } + } + } else break; + } else { + if ( n>0 ) n *= 10; + n += ch - '0'; + if ( ++d == 5 ){ + if ( flag ){ + geta /= 100000.0; + item += geta * n; + } else item = item * 100000.0 + n; + n = d = 0; + } + } + } + if ( d ){ + if ( flag ) item += geta * n / FILE2_POW[d]; + else item = item * FILE2_POW[d] + n; + } + return (item*sign); +} +double FILE2_read_double_ (FILE2 *fp){ + double item, geta=1; + int sign=1, ch; + FILE_err = 0; + while (1){ + ch = FILE2_getc(fp); + if ( ch < 0 ){ FILE_err = 6; return (-DOUBLEHUGE); } + if ( ch == '\n' ){ FILE_err = 5; return (-DOUBLEHUGE); } + if ( ch=='-' ) sign *= -1; + else if ( ch=='.' ) geta = 0.1; + else if ( ch>='0' && ch<='9' ) break; + else { sign = 1; geta = 1; } + } + + item = geta * (ch-'0'); + if ( geta < 1.0 ) geta *= .1; + while (1){ + ch = FILE2_getc(fp); + if ( ch == '\n' ){ FILE_err = 1; return (item*sign); } + if ( ch<0 ){ FILE_err = 2; return (item*sign); } + if ( ch == '.' ) geta = .1; + else if ( (ch < '0') || (ch > '9')) return (item*sign); + else if ( geta < 1.0 ){ + item += geta*(ch-'0'); + geta *= 0.1; + } else item = item*10 + (ch-'0'); + } +} + +/* string has to have non-numeric alphabet until its end */ +FILE_LONG STR_read_int (char **s){ + FILE_LONG item; + int flag =1; + FILE_err = 0; + while (1) { + if ( **s == '\n' ){ FILE_err = 5; return (-INTHUGE); } + if ( **s=='-' ) flag = -1; + if ( **s >= '0' && **s <= '9' ) break; + (*s)++; + } + for ( item=(int)((**s)-'0') ; 1 ; item=item*10 +(int)((**s)-'0') ){ + (*s)++; + if ( ((**s) < '0') || ((**s) > '9')){ + if ( (**s) == '\n' ) FILE_err = 1; + return (flag*item); + } + } +} +double STR_read_double (char **s){ + double item, geta=1; + int sign=1; + FILE_err = 0; + while (1){ + if ( **s == '\n' ){ FILE_err = 5; return (-DOUBLEHUGE); } + if ( **s == '-' ) sign *= -1; + else if ( **s == '.' ) geta = 0.1; + else if ( **s >= '0' && **s <= '9' ) break; + else { sign = 1; geta = 1; } + (*s)++; + } + + item = geta * (**s-'0'); + if ( geta < 1.0 ) geta *= .1; + while (1){ + if ( **s == '\n' ){ FILE_err = 1; return (item*sign); } + if ( **s == '.' ) geta = .1; + else if ( (**s < '0') || (**s > '9')) return (item*sign); + else if ( geta < 1.0 ){ + item += geta*(**s - '0'); + geta *= 0.1; + } else item = item*10 + (**s-'0'); + (*s)++; + } +} + +/* read a WEIGHT from file */ +WEIGHT FILE2_read_WEIGHT (FILE2 *fp){ +#ifdef WEIGHT_DOUBLE + return (FILE2_read_double(fp)); +#else + return ((WEIGHT)FILE2_read_int(fp)); +#endif +} + +/* read through the file until newline or EOF */ +void FILE2_read_until_newline (FILE2 *fp){ + int ch; + if (FILE_err & 3) return; + while (1){ + ch = FILE2_getc (fp); + if ( ch == '\n' ){ FILE_err = 5; return; } + if ( ch < 0 ){ FILE_err = 6; return; } + } +} + +void STR_copy_until_newline (char **s, size_t *x, size_t *end, FILE2 *fp){ + int ch; + char *start = fp->buf; + while (1){ + if ( FILE_err & 3 ) return; + ch = FILE2_getc (fp); + if ( ch == '\n' ) FILE_err = 5; + else if ( ch < 0 ){ FILE_err = 6; if ( fp->buf == start ) return; } // + else if ( fp->buf < fp->buf_end ) continue; + + if ( start == fp->buf_end ) start = fp->buf_org; + if ( (*x) + fp->buf - start >= *end ){ + *end = MAX((*x) + fp->buf - start+64, (*end)*2); + realloc2 (*s, *end, EXIT); + } + memcpy (&(*s)[*x], start, fp->buf-start); + (*x) += fp->buf - start; + if ( FILE_err & 3 ) return; + start = fp->buf; + } +} + +void FILE2_printf (FILE2 *fp, char *mes, ...){ + va_list argp; + va_start (argp, mes); + sprintf (fp->buf, mes, argp); + va_end (argp); +} + +/* print a real number in a good style */ +void fprint_real (FILE *fp, double f){ + char s[200]; + size_t i; + i = sprintf (s, "%f", f); + while ( s[i-1] == '0' ) i--; + if ( s[i-1] == '.' ) i--; + s[i] = 0; + fprintf (fp, s); +} +void print_real (double f){ + fprint_real (stdout, f); +} + +void fprint_WEIGHT (FILE *fp, WEIGHT f){ +#ifdef WEIGHT_DOUBLE + fprint_real (fp, f); +#else + fprintf (fp, "%d", f); +#endif +} +void print_WEIGHT (WEIGHT f){ + fprint_WEIGHT (stdout, f); +} + +/* count the clms, rows, items, each row size, each column size */ +/* file types can be, array list and element list*/ +/* support transpose */ +FILE_COUNT FILE2_count (FILE2 *fp, int flag, int skip_rows, int int_rows, int skip_clms, int int_clms, FILE_COUNT_INT row_limit){ + FILE_COUNT_INT k=0, j, x, y, t=0; + int fr = flag&FILE_COUNT_ROWT, fc = flag&FILE_COUNT_CLMT; + int fe = flag&LOAD_ELE, ft = flag&LOAD_TPOSE; + FILE_COUNT C = INIT_FILE_COUNT; + C.flag = flag; + + FLOOP (j, 0, skip_rows) FILE2_read_until_newline (fp); + if ( flag & (FILE_COUNT_NUM+FILE_COUNT_GRAPHNUM) ){ + C.clms = (FILE_COUNT_INT)FILE2_read_int (fp); + C.rows = (flag & FILE_COUNT_NUM)? (FILE_COUNT_INT)FILE2_read_int (fp): C.clms; + C.eles = (FILE_COUNT_INT)FILE2_read_int (fp); + if ( !(flag & (FILE_COUNT_ROWT + FILE_COUNT_CLMT)) ) return (C); + FILE2_read_until_newline (fp); + } + do { + if ( fe ){ + FLOOP (j, 0, skip_clms){ FILE2_read_double (fp); if ( FILE_err&3 ) goto ROW_END; } + x = (FILE_COUNT_INT)FILE2_read_int (fp); if ( FILE_err&3 ) goto ROW_END; + y = (FILE_COUNT_INT)FILE2_read_int (fp); if ( FILE_err&4 ) goto ROW_END; + FILE2_read_until_newline (fp); + } else { + if ( k==0 ) FLOOP (j, 0, skip_clms){ FILE2_read_double (fp); if (FILE_err&3) goto ROW_END; } + x = t; + y = (FILE_COUNT_INT)FILE2_read_int (fp); if (FILE_err&4 ) goto ROW_END; + FLOOP (j, 0, int_clms){ FILE2_read_double (fp); if (FILE_err&3 ) break; } + k++; + } + + if ( ft ) SWAP_FILE_COUNT_INT (x, y); + if ( y >= C.clms ){ + C.clms = y+1; + if ( fc ) reallocx (C.clmt, C.clm_end, C.clms, 0, goto END); + } + if ( x >= C.rows ){ + C.rows = x+1; + if ( fr ) reallocx (C.rowt, C.row_end, C.rows, 0, goto END); + } + if ( x < C.clm_btm || C.eles == 0 ) C.clm_btm = x; + if ( y < C.row_btm || C.eles == 0 ) C.row_btm = y; + if ( fc ) C.clmt[y]++; + if ( fr ) C.rowt[x]++; + C.eles++; + + ROW_END:; + if ( !fe && (FILE_err&1) ){ + t++; C.rows = t; + ENMAX (C.clm_max, k); + ENMAX (C.clm_min, k); + FLOOP (j, 0, int_rows) FILE2_read_until_newline (fp); + if ( row_limit>0 && t>=row_limit ) break; + } else if ( row_limit>0 && C.eles>=row_limit ) break; + + } while ( (FILE_err&2)==0 ); + END:; + if ( fr ){ + reallocx (C.rowt, C.row_end, C.rows, 0, goto END); + ARY_MAX (C.row_max, k, C.rowt, 0, C.rows); + ARY_MIN (C.row_min, k, C.rowt, 0, C.rows); + } + if ( fe && C.clmt ){ + if ( fc ) reallocx (C.clmt, C.clm_end, C.clms, 0, goto END); + ARY_MAX (C.clm_max, k, C.clmt, 0, C.clms); + ARY_MIN (C.clm_min, k, C.clmt, 0, C.clms); + } + if ( ERROR_MES ) mfree (C.rowt, C.clmt); + return (C); +} + + +/* SLIST:very simple one-sided list */ +void SLIST_init (int *l, int num, int siz){ + malloc2 (l, num+siz, EXIT); + ARY_FILL (l, num, num+siz, -1); +} +void SLIST_end (int *l){ free (l); } +#define SLIST_INS(l,m,e) (l[e]=l[m],l[m]=e); + +/* qsort according to "->t" */ +int qsort_cmp_VECt (const void *x, const void *y){ + if ( ((VEC *)x)->t < ((VEC *)y)->t ) return (-1); + else return ( ((VEC *)x)->t > ((VEC *)y)->t); +} +int qsort_cmp__VECt (const void *x, const void *y){ + if ( ((VEC *)x)->t > ((VEC *)y)->t ) return (-1); + else return ( ((VEC *)x)->t < ((VEC *)y)->t); +} +void qsort_VECt (VEC *v, size_t siz, int unit){ + if ( unit == 1 || unit==-1 ) unit *= sizeof (VEC); + if ( unit < 0 ) qsort (v, siz, -unit, qsort_cmp__VECt); + else qsort (v, siz, unit, qsort_cmp_VECt); +} + +int qqsort_cmp_VECt (const void *x, const void *y){ + if ( QQSORT_ELEt(VEC,x) < QQSORT_ELEt(VEC,y) ) return (-1); + else return ( QQSORT_ELEt(VEC,x) > QQSORT_ELEt(VEC,y) ); +} +int qqsort_cmp__VECt (const void *x, const void *y){ + if ( QQSORT_ELEt(VEC,x) > QQSORT_ELEt(VEC,y) ) return (-1); + else return ( QQSORT_ELEt(VEC,x) < QQSORT_ELEt(VEC,y) ); +} +void qsort_perm__VECt (VEC *v, size_t siz, PERM *perm, int unit){ + if ( unit == 1 || unit==-1 ) unit *= sizeof(VEC); + common_int=MAX(unit,-unit); common_pnt=(char *)v; + if (unit<0) qsort (perm, siz, sizeof(PERM), qqsort_cmp__VECt); + else qsort (perm, siz, sizeof(PERM), qqsort_cmp_VECt); +} + +PERM *qsort_perm_VECt (VEC *v, size_t siz, int unit){ + PERM *perm; + malloc2 (perm, siz, EXIT0); + ARY_INIT_PERM (perm, siz); + qsort_perm__VECt (v, siz, perm, unit); + return(perm); +} + +#ifdef STDLIB2_RADIX_SORT // radix sort with 1M byte static memory + +#define RADIX_SORT_BUCKET_SIZ 2048 +/* sort of integer array with combination of radix sort and quick sort */ +/* flag&1: sort in decreasing order */ + +// sort by lower bits +void intarray_sort_iter (unsigned int *a, size_t siz, int unit){ + static size_t cnt[RADIX_SORT_BUCKET_SIZ], cnt2[RADIX_SORT_BUCKET_SIZ], init_flag = 1; + size_t k, x; + int i, ii, j, flag=1; + static char bbuf[1000], bbuf2[1000]; + char *aa, *aaa, *aa_end, *buf, *buf2; + + if ( siz<1000 ){ qsort_uint ( a, siz, unit); return; } + if ( unit <0 ){ unit = -unit; flag = -1; } + if ( unit == 1 ) unit = sizeof (int); + buf = bbuf; buf2 = bbuf2; + if ( init_flag == 1 ){ + init_flag = 0; + ARY_FILL (cnt, 0, RADIX_SORT_BUCKET_SIZ, 0); + } + // count elements of each number + for ( aa=(char*)a,aa_end=aa+siz*unit ; aalet_cnt[dep][cc], S->let_cnt[dep+1][cc]); + memcpy ( buf2, aaa, unit); + memcpy ( aaa, buf, unit); + SWAP_PNT ( buf, buf2); + cnt2[j]++; + } + memcpy ( aa, buf, unit); + } + cnt[i]=0; // difference!! + } +} +// sort by middle bits +void intarray_sort_iter_ ( unsigned int *a, size_t siz, int unit){ + static size_t cnt[RADIX_SORT_BUCKET_SIZ], cnt2[RADIX_SORT_BUCKET_SIZ], init_flag = 1; + int i, ii, j, flag=1; + size_t k, x; + static char bbuf[1000], bbuf2[1000]; + char *aa, *aaa, *aa_end, *buf, *buf2; + + if ( siz<1000 ){ qsort_uint ( a, siz, unit); return; } + buf = bbuf; buf2 = bbuf2; + if ( unit <0 ){ unit = -unit; flag = -1; } + if ( unit == 1 ) unit = sizeof (int); + if ( init_flag == 1 ){ + init_flag = 0; + ARY_FILL ( cnt, 0, RADIX_SORT_BUCKET_SIZ, 0); + } + // count elements of each number + for ( aa=(char*)a,aa_end=aa+siz*unit ; aalet_cnt[dep][cc], S->let_cnt[dep+1][cc]); + memcpy (buf2, aaa, unit); + memcpy (aaa, buf, unit); + SWAP_PNT (buf, buf2); + cnt2[j]++; + } + memcpy (aa, buf, unit); + } + } + k=0; FLOOP (i, 0, RADIX_SORT_BUCKET_SIZ){ + ii = flag==1? i: RADIX_SORT_BUCKET_SIZ-i-1; + intarray_sort_iter ( (unsigned int*)(((char*)a)+unit*k), cnt[ii]-k, unit*flag); + k = cnt[ii]; + cnt[i]=0; + } +} + +// sort by upper bits +void intarray_sort ( unsigned int *a, size_t siz, int unit){ + static size_t cnt[RADIX_SORT_BUCKET_SIZ], cnt2[RADIX_SORT_BUCKET_SIZ], init_flag = 1; + int i, ii, j, flag=1; + size_t k, x; + static char bbuf[1000], bbuf2[1000]; + char *aa, *aaa, *aa_end, *buf, *buf2; + + if ( siz<1000 ){ qsort_uint ( a, siz, unit); return; } + if ( unit <0 ){ unit = -unit; flag = -1; } + if ( unit == 1 ) unit = sizeof (int); + buf = bbuf; buf2 = bbuf2; + if ( init_flag == 1){ + init_flag = 0; + ARY_FILL (cnt, 0, RADIX_SORT_BUCKET_SIZ, 0); + } + // count elements of each number + for ( aa=(char*)a,aa_end=aa+siz*unit ; aalet_cnt[dep][cc], S->let_cnt[dep+1][cc]); + memcpy (buf2, aaa, unit); + memcpy (aaa, buf, unit); + SWAP_PNT (buf, buf2); + cnt2[j]++; + } + memcpy ( aa, buf, unit); + } + } + k=0; FLOOP (i, 0, RADIX_SORT_BUCKET_SIZ){ + ii = flag==1? i: RADIX_SORT_BUCKET_SIZ-i-1; + intarray_sort_iter_ ( (unsigned int*)(((char*)a)+unit*k), cnt[ii]-k, unit*flag); + k = cnt[ii]; + cnt[i]=0; + } + +/* + for ( i=0 ; i= 0 ){ + t = l[k]; + l[k] = ll[t]; + ll[t] = perm[i]; + i++; + } + } + memcpy (perm, ll, sizeof(int)*siz); + free ( ll); + free ( l); + return ( perm); + } else { + i=0; FLOOP (k, 0, m-mm){ + while ( l[k] >= 0 ){ + t = l[k]; + l[k] = ll[t]; + ll[t] = i; + i++; + } + } + free (l); + return (ll); + } +} + +/* permutate structure array *tt of unit size unit of size num, according to perm array *pp */ +/* num has to be +#include +#include +#include +#include +#include + +#ifdef USE_SIMD +#include // use MMX-SSE2; +#endif + + +#if defined(__cplusplus) && defined(__GNUC__) + #define _cplusplus_ +#endif + +#ifdef MULTI_CORE +#include +#include +#endif +#define CORE_MAX 16 + +/* comment out the following line if no error check is needed */ +//#define ERROR_CHECK +/* comment out the following if exit is not needed after each error routine */ +//#define ERROR_RET + +#ifdef ERROR_RET // definition of the process for errors + #define EXIT return + #define EXIT0 return(0) +#else + #define EXIT exit(1) + #define EXIT0 exit(1) +#endif + +// for dealing with files more than 2GB +#define _LARGEFILE_SOURCE +#define _FILE_OFFSET_BITS 64 + +#ifndef NULL + #define NULL 0 +#endif + +#ifdef MTWISTER + #define RANDOM ((long)(dsfmt_gv_genrand_close_open()*2147483648LL)) + #define RAND1 dsfmt_gv_genrand_close_open() + #define RAND_INIT dsfmt_gv_init_gen_rand(514346237) +#elif defined(__GNUC__) + #define RANDOM xor128() + #define RAND1 ((double)xor128())/4294967296.0 + #define RAND_INIT xor128() +#else + #define RANDOM rand() + #define RAND1 ((double)rand())/2147483648.0 + #define RAND_INIT srand(0) +#endif + + +// 64bit integer +#ifdef LONG_32 + #define LONG int + #define LONGHUGE INTHUGE + #define LONGF "%d" +#elif !defined(LONG) + #define LONG long long + #define LONGHUGE 9000000000000000000LL + #define LONGF "%lld" +#endif + +// actual int (most proper sized integer, for the processor) +#ifdef INT_64 + #define INT LONG + #define INTF LONGF +#else + #define INT int + #define INTF "%d" +#endif + +#ifndef FILE_LONG + #define FILE_LONG LONG + #define FILE_LONGHUGE LONGHUGE + #define FILE_LONGF LONGF +#endif + +#define UINTHUGE 4000000000U +#define INTHUGE 2000000000 +#define USHORTHUGE 32767 +#define SHORTHUGE 65535 +#define DOUBLEHUGE 999999999999999999999999999999.9 +#define ISEQUAL_VALUE 0.0000001 +#define ISEQUAL_VALUE2 0.00001 +#define PI 3.1415926535897932384647950288 +#define PI_INT 31416 +#define NPE 2.718281828459045235360287471352 +#define NPE_INT 27183 + +#ifndef WEIGHT + #ifdef WEIGHT_DOUBLE + #define WEIGHT double + #define WEIGHTHUGE DOUBLEHUGE + #define WEIGHTF "%f" + #else // define WEIGHT by int if it's undefined + #define WEIGHT int + #define WEIGHTHUGE INTHUGE + #define WEIGHTF "%d" + #endif +#endif + +#ifndef PERM + #ifdef PERM_LONG + #define PERM LONG + #define PERMHUGE LONGHUGE + #define PERMF LONGF + #else + #define PERM int + #define PERMHUGE INTHUGE + #define PERMF "%d" + #endif +#endif + + +extern size_t common_size_t; +extern INT common_INT, common_INT2; +extern char *common_pnt, *common_charp; +extern FILE *common_FILE; +extern WEIGHT common_WEIGHT, *common_WEIGHTp; +extern char *ERROR_MES; +extern int print_time_flag; +extern char common_comm[], common_comm2[], *common_argv[]; +typedef struct { + int i1, i2, i3, i4, i5, i6, i7, i8, i9; + LONG l1, l2, l3, l4, l5, l6, l7, l8, l9; + double d1, d2, d3, d4, d5, d6, d7, d8, d9; + char *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9; + void *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9; +} PARAMS; +extern PARAMS internal_params; + +/* lock&unlock for multi-core mode */ +#ifdef MULTI_CORE + extern int SPIN_LOCK_dummy; + #define SPIN_LOCK(b,a) (SPIN_LOCK_dummy=(((b)>1)&&pthread_spin_lock(&(a)))) + #define SPIN_UNLOCK(b,a) (SPIN_LOCK_dummy=(((b)>1)&&pthread_spin_unlock(&(a)))) +#else + #define SPIN_LOCK(b,a) + #define SPIN_UNLOCK(b,a) +#endif + +#define TYPE_VEC 1 +#define TYPE_MAT 2 +#define TYPE_SVEC 3 +#define TYPE_SMAT 4 +#define TYPE_QUEUE 5 +#define TYPE_SETFAMILY 6 +#define TYPE_TRSACT 7 +#define TYPE_ALIST 8 +#define TYPE_MALIST 9 +#define TYPE_AGRAPH 10 +#define TYPE_SGRAPH 11 +#define TYPE_AHEAP 12 +#define TYPE_BASE 13 +#define TYPE_FSTAR 14 +#define TYPE_SEQ 15 +#define TYPE_BARRAY 16 + +#define TYPE_FILE2 32 + +#define ADDR_FLOOR16(x) do{common_charp=((char *)x)+15;x=(typeof(x))(common_charp-(((size_t)common_charp)&15));}while(0) +double SQRT(double x); + +/* random */ +#define rnd(a) (random()%(a)) +#define prob(a) ((random()%65536)<(int)((a)*65536.0)) + +#define MARK 1 +#define UNMARK 0 +#define TRUE 1 +#define FALSE 0 + +/* equal/inequal with allowing numerical error for double */ +#define ISEQUAL(a,b) ((a)-(b)ISEQUAL_VALUE) +#define ISLESS(a,b) ((b)-(a)>ISEQUAL_VALUE) +#define RANGE(a,b,c) (((a)<=(b))&&((b)<=(c))) +#define BITRM(a,b) ((a)-=((a)&(b))); + +/* macro for getting maximum/minimum of two values */ +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define ENMAX(a,b) ((a)=(((a)>(b))?(a):(b))) +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define ENMIN(a,b) ((a)=(((a)<(b))?(a):(b))) + +/* error routine */ +#define error(mes,x) do{ERROR_MES=mes;fprintf(stderr,"%s\n",mes);x;}while(0) +#define error_num(mes,n,x) do{ERROR_MES=mes;fprintf(stderr,"%s: %g\n",mes,(double)(n));x;}while(0) +#define error_range(f,x,y,mes) do{if(!RANGE((x),(f),(y))){ERROR_MES=mes;fprintf(stderr,"%s: %g\n",mes,(double)(f));EXIT;}}while(0) +#define error_str(mes,s,x) do{ERROR_MES=mes;fprintf(stderr,"%s: %s\n",mes,s);x;}while(0) +#define print_err(...) fprintf(stderr,__VA_ARGS__) +#define print_mes(S,...) do{if(((S)->flag)&1)fprintf(stderr,__VA_ARGS__);}while(0) +//#define print_fname(s,fname,...) do{if(fname)fprintf(stderr,s,fname,__VA_ARGS__);}while(0) +#define print_fname(s,fname,...) do{if(fname)fprintf(stderr,s,fname);}while(0) +#define mfree(...) mfree_(NULL, __VA_ARGS__, (void *)1) +#define mfree2(...) mfree2_(NULL, __VA_ARGS__, (void *)1) + + +/* basic array operations and loops */ +#define ARY_FILL(f,start,end,c) do{for(common_size_t=(size_t)(start);common_size_t<(size_t)(end);common_size_t++)(f)[common_size_t]=(c);}while(0) +//#define ARY_FLOOP(V,i,x) for( (i)=0,x=(V).v[0] ; (i)<(V).t ; (i)++,x=(V).v[i]) +//#define ARY_BLOOP(V,i,x) for( (i)=(V).t-1,x=i>0?(V).v[i]:0 ; (i)>=0 ; (i)--,(x)=(i)>0?(V).v[i]:0) +#define FLOOP(i,x,y) for ((i)=(x) ; (i)<(y) ; (i)++) +#define BLOOP(i,x,y) for ((i)=(x) ; ((i)--)>(y) ; ) +#define MLOOP(z,x,M) for ((z)=(x) ; *(z)<(M) ; (z)++) +/* binary search: return maximum index no larger than c */ +#define BIN_SRCH(x,a,s,t,c) \ + do {\ + x=s; common_size_t=t; while ( x=(size_t)(end)){reallocx_(f,end,MAX((end)*2+16,(i)+1),e,x);end=MAX((end)*2,(i)+1);}}while(0) +#define reallocz(f,end,i,x) do{if((size_t)(i)>=(size_t)(end)){end=MAX((end)*2,(i)+1);realloc2(f,end,x);}}while(0) +#define realloci(f,i,x) do{if(!((i)&((i)-1)))realloc2(f,(i)*2+1,x);}while(0) + +/* basic array operations */ +#define ARY_REALLOCX(f,i,e,x) reallocz((f).v,(f).end,i,e,x) +#define ARY_REALLOCZ(f,i,x) reallocz((f).v,(f).end,i,x) +#define ARY_DUP(f,p,end,x) do{malloc2(f,end,x);memcpy(f,p,sizeof(*(f))*(end));}while(0) +#define ARY_MAX(m,i,f,x,y) do{(m)=(f)[x];(i)=(x);FLOOP(common_INT,(x)+1,(y))if((m)<(f)[common_INT]){(i)=common_INT;(m)=(f)[i];}}while(0) +#define ARY_MIN(m,i,f,x,y) do{(m)=(f)[x];(i)=(x);FLOOP(common_INT,(x)+1,y)if((m)>(f)[common_INT]){(i)=common_INT;(m)=(f)[i];}}while(0) +#define ARY_SUM(f,v,x,y) do{(f)=0;FLOOP(common_INT,x,y)(f)+=(v)[common_INT];}while(0) +#define ARY_NORM(f,v,b) do{(f)=0;FLOOP(common_INT,0,b)(f)+=(v)[common_INT]*(v)[common_INT];(f)=sqrt(f);}while(0) +#define ARY_NORMALIZE(v,b) do{ARY_NORM(common_double,v,b);FLOOP(common_INT,0,b)(v)[common_INT]/=common_double;}while(0) +#define ARY_INPRO(f,u,v,b) do{(f)=0;for (common_INT=0 ; common_INT<(b)-3 ; common_INT+=4) (f)+=(u)[common_INT]*(v)[common_INT] + (u)[common_INT+1]*(v)[common_INT+1] + (u)[common_INT+2]*(v)[common_INT+2] + (u)[common_INT+3]*(v)[common_INT+3]; if (common_INT+1<(b)){(f)+=(u)[common_INT]*v[common_INT]+(u)[common_INT+1]*(v)[common_INT+1]; if (common_INT+2<(b)) (f)+=(u)[common_INT+2]*(v)[common_INT+2];} else if (common_INT<(b)) (f)+=(u)[common_INT]*(v)[common_INT];}while(0) +#define ARY_DIST(f,u,v,b) do{(f)=0;for (common_INT=0 ; common_INT<(b) ; common_INT++) (f)+=((u)[common_INT]-(v)[common_INT])*((u)[common_INT]-(v)[common_INT]); (f)=sqrt(f);}while(0) + + +/* macros for permutation arrays */ +#define ARY_INIT_PERM(f,end) do{FLOOP(common_INT,0,(INT)end)(f)[common_INT]=common_INT;}while(0) +#define ARY_INV_PERM_(f,p,end) do{ARY_FILL(f,0,end,-1);FLOOP(common_INT,0,end)if((p)[common_INT]>=0&&(p)[common_INT]<(end))(f)[(p)[common_INT]]=common_INT;}while(0) +#define ARY_INV_PERM(f,p,end,x) do{malloc2(f,end,x);ARY_INV_PERM_(f,p,end);}while(0) +#define ARY_RND_PERM_(f,end) do{(f)[0]=0;FLOOP(common_INT,1,end){common_INT2=rnd(common_INT+1);(f)[common_INT]=(f)[common_INT2];(f)[common_INT2]=common_INT;}}while(0) +#define ARY_RND_PERM(f,end,x) do{malloc2(f,end,x);ARY_RND_PERM_(f,end);}while(0) + /* permute f so that f[i]=f[p[i]] (inverse perm). p will be destroyed (filled by end) */ +#define ARY_INVPERMUTE_(f,p,s,end) do{ FLOOP(common_INT,0,end){ if ( (p)[common_INT]<(end) ){ (s)=(f)[common_INT]; do { common_INT2=common_INT; common_INT=(p)[common_INT]; (f)[common_INT2]=(f)[common_INT]; (p)[common_INT2]=end; }while ( (p)[common_INT]<(end) ); (f)[common_INT2] = (s);}}}while(0) + /* permute f so that f[i]=f[p[i]] (inverse perm). not destroy p by allocating tmp memory */ +#define ARY_INVPERMUTE(f,p,s,end,x) do{ calloc2(common_pnt,end,x);FLOOP(common_INT,0,end){ if ( common_pnt[common_INT]==0 ){ (s)=(f)[common_INT]; do{ common_INT2=common_INT; common_INT=(p)[common_INT]; (f)[common_INT2]=(f)[common_INT]; common_pnt[common_INT2]=1; }while( common_pnt[common_INT]==0 ); (f)[common_INT2] = (s);}} free(common_pnt); }while(0) +//#define ARY_PERM(f,p,s,mark,end) do{FLOOP(common_size_t,0,end){ }}while(0) + +/* macros for printing (writing to file) arrays */ +#define ARY_PRINT(f,x,y,a) do{FLOOP(common_size_t,x,y)printf(a,(f)[common_size_t]);printf("\n");}while(0) +#define ARY_FPRINT(fp,f,x,y,a) do{FLOOP(common_size_t,(size_t)x,(size_t)y)fprintf((FILE *)fp,a,(f)[common_size_t]);fputc('\n',(FILE *)fp);}while(0) + +#define ST_MAX(m,i,S,a,x,y) do{(m)=(S)[x].a;(i)=(x);FLOOP(common_INT,(x)+1,y)if((m)<(S)[common_INT].a){(i)=common_INT;(m)=(S)[i].a;}}while(0) +#define ST_MIN(m,i,S,a,x,y) do{(m)=(S)[x].a;(i)=(x);FLOOP(common_INT,(x)+1,y)if((m)>(S)[common_INT].a){(i)=common_INT;(m)=(S)[i].a;}}while(0) +#define ST_SUM(k,S,a,x,y) do{(k)=0;FLOOP(common_INT,x,y)(k)+=(S)[common_INT].a;}while(0) +#define ST_FILL(S,a,start,end,c) do{for(common_INT=(start);common_INT<(end);common_INT++)(S)[common_INT].a = (c);}while(0) +#define ST_PRINT(S,a,x,y,f) do{FLOOP(common_size_t,x,y)printf(f,(S)[common_size_t].a );printf("\n");}while(0) + + +/* macros for QUE type structure (have .s, .t, .v) */ +#define QUE_EXP(f,a,x) do{reallocx((f).v,a,(f).end,(f).t,e,x);}while(0) +#define QUE_INS(f,b) do{(f).v[(f).t++]=(b);}while(0) +#define QUE_INSZ(f,a,x) do{reallocz((f).v,(f).end,(f).t+1,x);ARY_INS(f,a);}while(0) +#define QUE_INIT_PERM(f,end) do{ARY_INIT_PERM((f).v,(end));(f).t=(end);(f).s=0;}while(0) + +/* a macro for open files with exiting if an error occurs */ +#ifdef _MSC_ + #define fopen2(f,a,b,x) do{fopen_s(&f,a,b);if(!f){ERROR_MES="file open error";fprintf(stderr,"file open error: file name %s, open mode %s\n",a,b);x;}}while(0) +#else + #define fopen2(f,a,b,x) do{if(!((f)=fopen(a,b))){ERROR_MES="file open error";fprintf(stderr,"file open error: file name %s, open mode %s\n",a,b);x;}}while(0) +#endif +#define FILE2_open(f,a,b,x) do{if(a)fopen2((f).fp,a,b,x);else(f).fp=NULL;malloc2((f).buf_org,FILE2_BUFSIZ+1,x);(f).buf=(f).buf_org;(f).buf_end=(f).buf_org-1;(f).bit=0;*(f).buf=0;}while(0) +#define FILE2_open_(f,a,x) do{(f).fp=a;malloc2((f).buf_org,FILE2_BUFSIZ+1,x);(f).buf=(f).buf_org;(f).buf_end=(f).buf_org-1;(f).bit=0;*(f).buf=0;}while(0) + +/* macros for allocating memory with exiting if an error occurs */ +#define free2(a) do{if(a){free(a);(a)=NULL;}}while(0) +#define free2d(a) do{if(a){free2((a)[0]);free(a);(a)=NULL;}}while(0) +#define fclose2(a) do{if(a){fclose(a);(a)=NULL;}}while(0) + +/* macros for reading integers from file, d=0 read one-line, d=1 read all file */ +//#define ARY_SCAN(k,a,fp,d) do{(k)=0;do{do{FILE2_read_##a(&(fp));}while((FILE_err&6)==8-(d)*4);if(FILE_err&(4-2*(d)))break;(k)++;}while((FILE_err&(3-(d)))==0);}while(0) +#define ARY_SCAN(num,type,fp,d) do{(num)=0;do{do{FILE2_read_##type(&(fp));}while((FILE_err&((d)*5))==5);if(RANGE(5+(int)(d),FILE_err,6))break;(num)++;}while((FILE_err&(3-(int)(d)))==0);}while(0) +#define ARY_READ_LINE(f,type,num,fp) do{(num)=0;do{(f)[num]=FILE2_read_##type(&(fp));(num)+=(FILE_err&4)?0:1;}while((FILE_err&3)==0);}while(0) +#define ARY_READ(f,type,num,fp) do{FLOOP(common_size_t,0,(size_t)num){do{(f)[common_size_t]=FILE2_read_##type(&(fp));}while((FILE_err&6)==4);if(FILE_err&2)break;}}while(0) +#define ARY_LOAD(f,type,num,fname,d,x) do{FILE2_open(common_FILE2,fname,"r",x);ARY_SCAN(num,type,common_FILE2,d);malloc2(f,(num)+1,x);FILE2_reset(&common_FILE2);ARY_READ(f,type,num,common_FILE2);FILE2_close(&common_FILE2);}while(0) +#define ARY_WRITE(n,f,num,q,x) do{fopen2(common_FILE,n,"w",x);ARY_FPRINT(common_FILE,f,0,num,q);fclose(common_FILE);}while(0) + +#ifndef MQUE_ONEMORE + #define MQUE_ONEMORE 1 +#endif + +/* macros for generalized queue; end mark is necessary for INTSEC */ +#define MQUE_FLOOP(V,z) for((z)=(V).v;(z)<(V).v+(V).t ; (z)++) +#define MQUE_FLOOP2(V,z,zz) for((z)=(V).v,(zz)=(z)+(V).t;(z)<(zz) ; (z)++) +#define MQUE_BLOOP(V,z) for((z)=(V).v+(V).t-1;(z)>=(V).v ; (z)--) +#define MQUE_SLOOP(V,z) for((z)=(V).v+(V).s;(z)<(V).v+(V).t ; (z)++) +#define MQUE_SLOOP2(V,z,zz) for((z)=(V).v+(V).s,(zz)=(z)+(V).t;(z)<(zz) ; (z)++) +#define MQUE_SBLOOP(V,z) for((z)=(V).v+(V).t-1;(z)>=(V).v+(V).s ; (z)--) + +#ifdef _cplusplus_ + #define MQUE_FLOOP_(V,z,s) for((z)=(V).v ; (char *)(z)<((char *)(V).v)+(V).t*(s) ; (z)=(typeof(z))(((char *)(z))+(s))) +#else + #define MQUE_FLOOP_(V,z,s) for((z)=(V).v ; (char *)(z)<((char *)(V).v)+(V).t*(s) ; (z)=(void *)(((char *)(z))+(s))) +#endif + +#define MQUE_MLOOP(V,z,M) for((z)=(V).v; *((QUEUE_INT *)z)<(M) ; (z)++) + +/// !!! errr MQUE_INTSEC !!!!! +#define MQUE_INTSEC(f,U,V) do{\ +common_INT=0;(f)=0;\ +FLOOP(common_INT2,0,(U).t){\ + while(*((QUEUE_INT *)(&((V).v[common_INT])))<*((QUEUE_INT *)(&((U).v[common_INT2])))&&common_INT<(V).t){ \ + if (++common_INT >= (V).t) break;\ + }if(*((QUEUE_INT *)(&((V).v[common_INT])))==*((QUEUE_INT *)(&((U).v[common_INT2]))))(f)++;\ +}}while(0) +#define MQUE_UNION(f,U,V) do{MQUE_INTSEC(f,U,V);(f)=(U).t+(V).t-(f);}while(0) +#define MQUE_DIF(f,U,V) do{MQUE_INTSEC(f,U,V);(f)=(U).t+(V).t-(f)-(f);}while(0) +#define MQUE_RM_DUP(V) do{\ +if((V).t>1){\ + common_INT=1;\ + FLOOP(common_INT2,1,(V).t){\ + if ( *((QUEUE_INT *)(&((V).v[common_INT2-1]))) != *((QUEUE_INT *)(&((V).v[common_INT2]))) ) (V).v[common_INT++]=(V).v[common_INT2];\ + } (V).t=common_INT;\ + }\ +}while(0) + +#define MQUE_UNIFY(V,a) do{\ +if((V).t>1){\ + common_INT=0;\ + FLOOP(common_INT2,1,(V).t){\ + if ( *((QUEUE_INT *)(&((V).v[common_INT2-1]))) != *((QUEUE_INT *)(&((V).v[common_INT2]))) ) (V).v[++common_INT]=(V).v[common_INT2];\ + else *((a*)(((QUEUE_INT *)(&((V).v[common_INT2])))+1)) += *((a*)(((QUEUE_INT *)(&((V).v[common_INT2])))+1));\ + } (V).t=common_INT+1;\ +}}while(0) + + + + +#ifndef VEC_VAL + #ifdef VEC_VAL_CHAR + #define VEC_VAL char + #define VEC_VAL2 LONG + #define VEC_VAL_END 128 + #define VEC_VAL2_END LONGHUGE + #define VEC_VALF "%hhd" + #elif defined(VEC_VAL_UCHAR) + #define VEC_VAL unsigned char + #define VEC_VAL2 LONG + #define VEC_VAL_END 256 + #define VEC_VAL2_END LONGHUGE + #define VEC_VALF "%hhu" + #elif defined(VEC_VAL_INT) + #define VEC_VAL int + #define VEC_VAL2 LONG + #define VEC_VAL_END INTHUGE + #define VEC_VAL2_END LONGHUGE + #define VEC_VALF "%d" + #else + #define VEC_VAL double + #define VEC_VAL2 double + #define VEC_VAL_END DOUBLEHUGE + #define VEC_VAL2_END DOUBLEHUGE + #define VEC_VALF "%f" + #endif +#endif + +#ifndef VEC_ID + #ifdef VEC_ID_LONG + #define VEC_ID LONG + #define VEC_ID_END LONGHUGE + #define VEC_IDF LONGF + #else + #define VEC_ID int + #define VEC_ID_END INTHUGE + #define VEC_IDF "%d" + #endif +#endif + +/* vector */ +typedef struct { + unsigned char type; // mark to identify type of the structure + VEC_VAL *v; + VEC_ID end; + VEC_ID t; +} VEC; + +extern VEC INIT_VEC; +extern PERM common_PERM, *common_PERMp; +extern VEC_VAL common_VEC_VAL, *common_VEC_VALp; +extern VEC_ID common_VEC_ID; + +/* tranpose the matrix ; counting/transpose/memory_allocate */ +#define MQUE_DELIVERY_CNT(c,jump,f,y,M) do{ \ +FLOOP(common_VEC_ID, 0, (f).t){ \ + MQUE_MLOOP( (f).v[common_VEC_ID], y, M){ \ + if( (c)[*((QUEUE_INT *)y)] == 0 ) ARY_INS(jump, *((QUEUE_INT *)y)); \ + (c)[*((QUEUE_INT *)y)]++; \ + } \ +}}while(0) +#define MQUE_DELIVERY(occ,jump,f,y,M) do{ \ +FLOOP (common_VEC_ID, 0, (f).t){ \ + MQUE_MLOOP ((f).v[common_VEC_ID], y, M){ \ + if( (occ)[*((QUEUE_INT *)y)].t == 0 ) ARY_INS( jump, *((QUEUE_INT *)y)); \ + ARY_INS( (occ)[*((QUEUE_INT *)y)], common_VEC_ID); \ + } \ +}}while(0) + + // allocate QUEUE of QUEUE, according to rows (cells of "ext" will be add to each row) +#ifdef _cplusplus_ +#define MQUE_ALLOC(Q,rows,rowt,unit,ext,x) do{ \ +common_size_t=0; \ +FLOOP (common_VEC_ID, 0, rows) common_size_t += rowt[common_VEC_ID]; \ +calloc2 (Q, (rows)+1, x); \ +malloc2 (common_pnt, (common_size_t+(rows)*(ext)+2)*((unit)internal) of rows and columns +} FILE_COUNT; + +extern FILE_COUNT INIT_FILE_COUNT; + +/* count the clms, rows, items, each row size, each column size */ +/* file types can be, array list and element list*/ +/* support transpose */ +FILE_COUNT FILE2_count (FILE2 *fp, int flag, int skip_rows, int int_rows, int skip_clms, int int_clms, FILE_COUNT_INT row_limit); + +/******************* integer array routines **************************/ + +/******************************* permutation routines ****************/ +/* permutation is given by an integer array */ + +/* sort an array of size "siz", composed of a structure of size "unit" byte + in the order of perm */ +/* use temporary memory of siz*unit byte */ +//void perm_struct (void *a, int unit, int *perm, size_t siz); + +/* SLIST:very simple one-sided list */ +void SLIST_init (int *l, int num, int siz); +void SLIST_end (int *l); +#define SLIST_INS(l,m,e) (l[e]=l[m],l[m]=e); + +#define QQSORT_ELE(a,x) ((a *)(&(common_pnt[(*((PERM *)(x)))*common_int]))) +#define QQSORT_ELEt(a,x) (((a *)&(common_pnt[(*((PERM *)(x)))*common_int]))->t) +/* quick sort macros */ +#define QSORT_TYPE(a,b) \ +b common_##a; \ +int qsort_cmp_##a (const void *x, const void *y){ \ + if ( *((b *)x) < *((b *)y) ) return (-1); else return ( *((b *)x) > *((b *)y) ); \ +} \ +int qsort_cmp__##a (const void *x, const void *y){ \ + if ( *((b *)x) > *((b *)y) ) return (-1); else return ( *((b *)x) < *((b *)y) ); \ +} \ +int qqsort_cmp_##a (const void *x, const void *y){ \ + b *xx=QQSORT_ELE(b,x), *yy=QQSORT_ELE(b,y); \ + if ( *xx < *yy ) return (-1); \ + else return ( *xx > *yy ); \ +} \ +int qqsort_cmp__##a (const void *x, const void *y){ \ + b *xx=QQSORT_ELE(b,x), *yy=QQSORT_ELE(b,y); \ + if ( *xx > *yy ) return (-1); \ + else return ( *xx < *yy ); \ +} \ +void qsort_##a (b *v, size_t siz, int unit){ \ + if ( unit == 1 || unit==-1 ) unit *= sizeof (b); \ + if (unit<0) qsort (v, siz, -unit, qsort_cmp__##a); else qsort (v, siz, unit, qsort_cmp_##a); \ +} \ +void qsort_perm__##a (b *v, size_t siz, PERM *perm, int unit){ \ + ARY_INIT_PERM(perm,(INT)siz); \ + if ( unit == 1 || unit==-1 ) unit *= sizeof (b); \ + common_int=MAX(unit,-unit); common_pnt=(char *)v; \ + if (unit<0) qsort (perm, siz, sizeof(PERM), qqsort_cmp__##a); \ + else qsort (perm, siz, sizeof(PERM), qqsort_cmp_##a); \ +} \ +PERM *qsort_perm_##a (b *v, size_t siz, int unit){ \ + PERM *perm; malloc2(perm, siz, EXIT0); \ + qsort_perm__##a (v, siz, perm, unit); return(perm); \ +} \ +size_t bin_search_##a (b *v, b u, size_t siz, int unit){ \ + size_t s=0, t; \ + b n; \ + if ( unit == 1 ) unit *= sizeof (b); \ + while (1){ \ + if ( siz-s <= 2 ){ \ + if ( u <= *((b *)(((char *)v)+unit*s)) ) return (s);\ + if ( siz == s+1 || u <= *((b *)(((char *)v)+unit*(s+1))) ) return (s+1);\ + return (s+2);\ + }\ + t = (s+siz) /2; \ + n = *((b *)(((char *)v)+unit*t));\ + if ( u < n ) siz = t; else s = t;\ + }\ +} +// bin search returns the position that is equal to u, or the smallest in larger's + +#define QSORT_TYPE_HEADER(a,b) \ +extern b common_##a; \ +int qsort_cmp_##a (const void *x, const void *y); \ +int qsort_cmp__##a (const void *x, const void *y); \ +int qqsort_cmp_##a (const void *x, const void *y); \ +int qqsort_cmp__##a (const void *x, const void *y); \ +void qsort_##a(b *v, size_t siz, int unit); \ +void qsort_perm__##a (b *v, size_t siz, PERM *perm, int unit); \ +PERM *qsort_perm_##a (b *v, size_t siz, int unit); \ +size_t bin_search_##a (b *v, b u, size_t siz, int unit); + +QSORT_TYPE_HEADER(int, int) +QSORT_TYPE_HEADER(uint, unsigned int) +QSORT_TYPE_HEADER(double, double) +QSORT_TYPE_HEADER(char, char) +QSORT_TYPE_HEADER(uchar, unsigned char) +QSORT_TYPE_HEADER(short, short) +QSORT_TYPE_HEADER(ushort, unsigned short) +QSORT_TYPE_HEADER(WEIGHT, WEIGHT) +QSORT_TYPE_HEADER(LONG, LONG) +QSORT_TYPE_HEADER(VEC_ID, VEC_ID) +QSORT_TYPE_HEADER(VEC_VAL, VEC_VAL) +QSORT_TYPE_HEADER(VEC_VAL2, VEC_VAL2) +QSORT_TYPE_HEADER(FILE_COUNT_INT, FILE_COUNT_INT) + +int qsort_cmp_VECt (const void *x, const void *y); +int qsort_cmp__VECt (const void *x, const void *y); +void qsort_VECt (VEC *v, size_t siz, int unit); +int qqsort_cmp_VECt (const void *x, const void *y); +int qqsort_cmp__VECt (const void *x, const void *y); +void qsort_perm__VECt (VEC *v, size_t siz, PERM *perm, int unit); +PERM *qsort_perm_VECt (VEC *v, size_t siz, int unit); + +/* swap macro for integer, double, char, and pointer */ +#define SWAP_INT(a,b) (common_LONG=a,a=b,b=common_LONG) +#define SWAP_DOUBLE(a,b) (common_double=a,a=b,b=common_double) +#define SWAP_size_t(a,b) (common_size_t=a,a=b,b=common_size_t) +#ifdef _cplusplus_ + #define SWAP_PNT(a,b) (common_pnt=(typeof(common_pnt))a,a=(typeof(a))b,b=(typeof(b))common_pnt) +#else + #define SWAP_PNT(a,b) (common_pnt=(void *)a,a=(void *)b,b=(void *)common_pnt) +#endif + +#define SWAP_VEC_ID(a,b) (common_VEC_ID=a,a=b,b=common_VEC_ID) +#define SWAP_FILE_COUNT_INT(a,b) (common_FILE_COUNT_INT=a,a=b,b=common_FILE_COUNT_INT) + +/* sort index(int)/WEIGHT array and return the indices of the result */ +/* perm[i*2] := rank of ith cell */ +/* perm[i*2+1] := index of ith smallest cell */ +/* flag!=NULL => opposite direction sort */ + +//int *int_index_sort (int *w, size_t siz, int flag); +//int *WEIGHT_index_sort (WEIGHT *w, size_t siz, int flag); + +/* radix sort for array of structures, by their integer members + ranging from mm to m */ +/* sort array "perm" according to (int/void*) array "a". + if perm==NULL, allocate memory and for perm */ +/* return the permutation array of the result of the sorting + in the decreasing order if unit<0 (unimplemented!!!) */ +int *radix_sort (void *a, size_t siz, int unit, int mm, int m, int *perm); + +/* permutate structure array *tt of unit size unit of size num, according to perm array *pp */ +/* num has to be output-file\n"); + exit (1); +} +open ( TABLEFILE, ">$ARGV[0]" ); +#@lines = ; +$count = 1; +%numbers = (); +$c=1; +$numflag=0; + +$sep = " "; +$ignore[1] = $ignore[2] = $ignore[3] = $ignore[4] = $ignore[5] = $ignore[6] = $ignore[7] = $ignore[8] = $ignore[9] = 0; + +while ( $ARGC > $c ){ + if ( $ARGV[$c] eq "-1" ){ $ignore[1] = 1; } + elsif ( $ARGV[$c] eq "-2" ){ $ignore[2] = 1; } + elsif ( $ARGV[$c] eq "-3" ){ $ignore[3] = 1; } + elsif ( $ARGV[$c] eq "-4" ){ $ignore[4] = 1; } + elsif ( $ARGV[$c] eq "-5" ){ $ignore[5] = 1; } + elsif ( $ARGV[$c] eq "-6" ){ $ignore[6] = 1; } + elsif ( $ARGV[$c] eq "-7" ){ $ignore[7] = 1; } + elsif ( $ARGV[$c] eq "-8" ){ $ignore[8] = 1; } + elsif ( $ARGV[$c] eq "-9" ){ $ignore[9] = 1; } + elsif ( $ARGV[$c] eq "-n" ){ + $numflag = 1; + $count = 2; + print TABLEFILE "1 __numbers__\n"; + } + else { $sep = $ARGV[$c]; } + $c++; +} + +while (){ + $_ =~ s/[\r\n]//g; + chomp; + $_ =~ s/$sep$sep/$sep/g; + $_ =~ s/\t/$sep/g; + @eles = split($sep, $_); + $all = @eles; + $c = 1; + foreach $item( @eles ) { + if ( $c < 10 && $ignore[$c] == 1 ){ + if ( $item ne "" ){ + print $item; + if ($c<$all){ print " ";} + $c++; + } + } else { + if ( $item ne "" ){ + if ( $numflag==1 ){ + $item2 = $item; + $item2 =~ s/[0-9]//g; + if ( $item2 eq "" ){ + print "1"; + if ($c<$all){ print " ";} + $c++; + next; + } + } + if (!exists $numbers{$item}) { + $numbers{$item} = $count; + print TABLEFILE "$count $item\n"; + $count++; + } + print "$numbers{$item}"; + if ($c<$all){ print " ";} + $c++; + } + } + } + print "\n" +} diff --git a/rql-backend/shd31/transpose.pl b/rql-backend/shd31/transpose.pl new file mode 100644 index 0000000..625f48e --- /dev/null +++ b/rql-backend/shd31/transpose.pl @@ -0,0 +1,33 @@ +#!/usr/bin/perl + +#transpose.pl transposes the set-family-file/01 matrix)/transaction-data +# from horizontal representation to virtical representation +# if a number x is wrtten in yth line in the input file, then y is written in +# the xth line in the output file. +# Both input and output file are from/to standard input/output + +$ARGC = @ARGV; +if ( $ARGC < 0 ){ + printf ("transpose.pl [separator] < input-file > output-file\n"); + exit (1); +} +$count = 0; +$m = 0; + +$sep = " "; +if ( $ARGC > 0 ){ $sep = $ARGV[0]; } + +while (){ + chomp; + @eles = split($sep, $_); + $all = @eles; + foreach $item( @eles ){ + push ( @{$t[$item]}, $count ); + if ( $item > $m ){ $m = $item; } + } + $count++; +} + +for ( $i=0 ; $i<=$m ; $i++ ){ print "@{$t[$i]}\n";} + + diff --git a/rql-backend/shd31/undo.c b/rql-backend/shd31/undo.c new file mode 100644 index 0000000..011a696 --- /dev/null +++ b/rql-backend/shd31/undo.c @@ -0,0 +1,95 @@ +/****************************/ + +/* ALIST-based UNDO operators for library functions + 12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* available for ALIST and AGRAPH */ + +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + + +/* NOTICE: include all libraries before including "undo.c". + only the libraries include before is considered, and will be availabale. */ + +#ifndef _undo_c_ +#define _undo_c_ + +#include"undo.h" +#include"base.c" + +ALIST_UNDO *ALISTundo_list; +BASE ALISTundo_base; + +/* initialization of UNDO list */ +void ALISTundo_init (){ + BASE_alloc (&ALISTundo_base, sizeof(ALIST_UNDO), 16384); + ALISTundo_list = (ALIST_UNDO *)(&ALISTundo_list); +} + +/* termination */ +void ALISTundo_end (){ + BASE_end (&ALISTundo_base); +} + +/* store one operation by inserting to UNDO list */ +void ALISTundo_ins ( ALIST_TYPE type, void *s, UNDO_INT i, UNDO_INT j){ + ALIST_UNDO *m; + m = (ALIST_UNDO *)BASE_new ( &ALISTundo_base); + m->type = type; + m->s = s; + m->i = i; + m->j = j; + m->nxt = ALISTundo_list; + ALISTundo_list = m; +} + +/* One undo. return 0 if list is empty, or STOPmark appears, return non-zero otherwise. */ +int ALISTundo_iter (){ + ALIST_UNDO *m; + if ( ALISTundo_list == (ALIST_UNDO *)(&ALISTundo_list) ) return (0); + m = ALISTundo_list; + ALISTundo_list = m->nxt; + switch ( m->type ){ + case U_STOP: BASE_del (&ALISTundo_base, m); return (0); + case U_MALIST_rm: MALIST_rm ( (MALIST *)(m->s), m->i, 0); + break; case U_MALIST_ins: MALIST_ins_nxt ( (MALIST *)(m->s), m->i, m->j, 0); + break; case U_ALIST_rm: ALIST_rm ( (ALIST *)(m->s), m->i, 0); + break; case U_ALIST_ins: ALIST_ins_nxt ( (ALIST *)(m->s), m->i, m->j, 0); +#ifdef _agraph_h_ + break; case U_AGRAPH_edge_num: ((AGRAPH *)(m->s))->edge_num += m->i; + break; case U_AGRAPH_arc_num: ((AGRAPH *)(m->s))->arc_num += m->i; break; +#endif + } + BASE_del (&ALISTundo_base, m); + return (1); +} + +/* continuously undo until STOPmark appears */ +void ALISTundo (){ while ( ALISTundo_iter () ); } + +/* clear UNDO list until STOPmark appears, or become empty list */ +void ALISTundo_clear (){ + ALIST_UNDO *m; + while (1){ + if ( ALISTundo_list == (ALIST_UNDO *)(&ALISTundo_list) ) return; + m = ALISTundo_list; + ALISTundo_list = m->nxt; + if ( m->type == U_STOP ){ + BASE_del (&ALISTundo_base, m); + return; + } + BASE_del (&ALISTundo_base, m); + } +} + +/* insert STOPmark in UNDO list */ +void ALISTundo_ins_stop (){ ALISTundo_ins (U_STOP, NULL, -1, -1);} + +#endif + diff --git a/rql-backend/shd31/undo.h b/rql-backend/shd31/undo.h new file mode 100644 index 0000000..c5ed4cb --- /dev/null +++ b/rql-backend/shd31/undo.h @@ -0,0 +1,72 @@ +/* ALIST-based UNDO operators for library functions + 12/Apr/2001 by Takeaki Uno e-mail:uno@nii.jp, + homepage: http://research.nii.ac.jp/~uno/index.html */ +/* available for ALIST and AGRAPH */ + +/* This program is available for only academic use, basically. + Anyone can modify this program, but he/she has to write down + the change of the modification on the top of the source code. + Neither contact nor appointment to Takeaki Uno is needed. + If one wants to re-distribute this code, please + refer the newest code, and show the link to homepage of + Takeaki Uno, to notify the news about the codes for the users. */ + + +#ifndef _undo_h_ +#define _undo_h_ + +#ifdef ALIST_ID_LONG + #define UNDO_INT LONG + #define UNDO_INT_END LONGHUGE +#else + #define UNDO_INT int + #define UNDO_INT_END INTHUGE +#endif + +#include"base.h" +#include"alist.h" + +/* structure for Undo information */ +typedef struct _ALIST_UNDO { + struct _ALIST_UNDO *nxt; + char type; + void *s; + UNDO_INT i; + UNDO_INT j; +} ALIST_UNDO; + +/* enuemration type for Undo operations */ +typedef enum { + U_STOP, + U_MALIST_ins, + U_MALIST_rm, + U_ALIST_ins, + U_ALIST_rm, + U_AGRAPH_edge_num, + U_AGRAPH_arc_num, +} ALIST_TYPE; + +/* initialization of UNDO list */ +void ALISTundo_init (); + +/* termination */ +void ALISTundo_end (); + +/* store one operation by inserting to UNDO list */ +void ALISTundo_ins ( ALIST_TYPE type, void *s, UNDO_INT i, UNDO_INT j); + +/* One undo. return 0 if list is empty, or STOPmark appears, return non-zero otherwise. */ +int ALISTundo_iter (); + +/* continuously undo until STOPmark appears */ +void ALISTundo (); + +/* clear UNDO list until STOPmark appears, or become empty list */ +void ALISTundo_clear (); + +/* insert STOPmark in UNDO list */ +void ALISTundo_ins_stop (); + + +#endif + diff --git a/rql-backend/shd31/untransnum.pl b/rql-backend/shd31/untransnum.pl new file mode 100644 index 0000000..1690413 --- /dev/null +++ b/rql-backend/shd31/untransnum.pl @@ -0,0 +1,51 @@ +#!/usr/bin/perl + +# transform the numbers to the strings according to the table file +# basically, this script is for untransform the numbers transformed by +# the transnum.pl + +use Text::ParseWords; + +$ARGC = @ARGV; +if ( $ARGC < 1 ){ + # error routine + printf ("untransnum.pl: output-table-file [separator] < input-file > output-file\n"); + exit (1); +} + # initialization +open (TABLEFILE, "<$ARGV[0]" ); +%numbers = (); +$c=0; +$sep=" "; $sep2=" "; +if ( $ARGC >1 ){ $sep = $ARGV[1]; } # separator +if ( $ARGC >2 ){ $sep2 = $ARGV[2]; } # separator + + # read transform-table +while (){ + chomp; + $e0 = $_; $e1 = $_; + $e0 =~ s/ .*$//; + $e1 =~ s/^[^ ]* //; + $numbers{$e0} = $e1; + $c++; +} + + # read transform-file +while (){ + $_ =~ s/[\r\n]//g; + chomp; + $_ =~ s/$sep$sep/$sep/g; + @eles = split($sep, $_); + $all = @eles; + $c = 0; + foreach $item( @eles ){ + if ( $item < 0 ){ + print "*"; + } elsif (!exists $numbers{$item}) { + print "$item"; + } else { print "$numbers{$item}"; } + $c++; + if ($c<$all){ print $sep2;} + } + print "\n" +} diff --git a/rql-backend/shd31/vec.c b/rql-backend/shd31/vec.c new file mode 100644 index 0000000..e60dd60 --- /dev/null +++ b/rql-backend/shd31/vec.c @@ -0,0 +1,731 @@ +/* library for vector and sparse vector, and matrix */ +/* Takeaki Uno 27/Dec/2008 */ + +#ifndef _vec_c_ +#define _vec_c_ + +#include"vec.h" +#include"stdlib2.c" +#include"queue.c" + +MAT INIT_MAT = {TYPE_MAT,NULL,0,NULL,0,0,NULL,NULL,0,0,NULL,NULL}; +SVEC INIT_SVEC_ELE = {0,0}; +SVEC INIT_SVEC = {TYPE_SVEC,NULL,0,0}; +SMAT INIT_SMAT = {TYPE_SMAT,NULL,0,NULL,0,0,NULL,NULL,0,0,0}; +SETFAMILY INIT_SETFAMILY = INIT_SETFAMILY_; + +QSORT_TYPE (SVEC_VAL, SVEC_VAL) +QSORT_TYPE (SVEC_VAL2, SVEC_VAL2) + +/* allocate memory according to rows and rowt */ +void VEC_alloc (VEC *V, VEC_ID clms){ + *V = INIT_VEC; + V->end = clms; + calloc2 (V->v, clms+1, EXIT); +} + +/* terminate routine for VEC */ +void VEC_end (VEC *V){ + free2 (V->v); + *V = INIT_VEC; +} + +/* allocate memory according to rows and rowt */ +void MAT_alloc (MAT *M, VEC_ID rows, VEC_ID clms){ + VEC_ID i, clms2 = clms+(clms%2?1:2); + calloc2 (M->v, rows+1, EXIT); + calloc2 (M->buf_org, clms2 * (rows+1)+4, {free(M->v);EXIT;}); + M->buf = M->buf_org; ADDR_FLOOR16(M->buf); + M->end = rows; + M->clms = clms; + FLOOP (i, 0, rows){ + M->v[i].end = M->v[i].t = clms; + M->v[i].v = M->buf + i*(clms2); +// printf ("%p %p\n", M->buf, M->v[i].v); + } +} + +/* terminate routine for MAT */ +void MAT_end (MAT *M){ + free2 (M->buf_org); + free2 (M->buf2_org); + free2 (M->v); + *M = INIT_MAT; +} + +/* allocate memory */ +void SVEC_alloc (SVEC *V, VEC_ID end){ + *V = INIT_SVEC; + calloc2 (V->v, end+1, EXIT); + V->end = end; + V->t = 0; +} + +/* terminate routine for SVEC */ +void SVEC_end (SVEC *V){ + free2 (V->v); + *V = INIT_SVEC; +} + +/* allocate memory according to rows and rowt */ +void SMAT_alloc (SMAT *M, VEC_ID rows, VEC_ID *rowt, VEC_ID clms, size_t eles){ + VEC_ID i; + if ( eles == 0 ) ARY_SUM (M->ele_end, rowt, 0, rows); else M->ele_end = eles; + calloc2 (M->buf, M->ele_end*((M->flag&LOAD_DBLBUF)?2:1) +rows +2, EXIT); + malloc2 (M->v, rows+1, {free(M->buf);EXIT;}); + ARY_FILL (M->v, 0, rows, INIT_SVEC); + M->end = rows; + M->clms = clms; + if ( rowt ){ + FLOOP (i, 0, rows){ + M->v[i].v = i? M->v[i-1].v + rowt[i-1] +1: M->buf; + M->v[i].end = rowt[i]; + } + } +} + +/* terminate routine for MAT */ +void SMAT_end (SMAT *M){ + free2 (M->buf); + free2 (M->buf2); + free2 (M->v); + *M = INIT_SMAT; +} + + + +/* allocate memory according to rows and rowt */ +/* if eles == 0, compute eles from rowt and rows */ +void SETFAMILY_alloc (SETFAMILY *M, VEC_ID rows, VEC_ID *rowt, VEC_ID clms, size_t eles){ + VEC_ID i; + char *buf; + if ( eles == 0 ) ARY_SUM (M->ele_end, rowt, 0, rows); else M->ele_end = eles; + calloc2 (buf, (M->ele_end*((M->flag&LOAD_DBLBUF)?2:1) +((M->flag&LOAD_DBLBUF)?MAX(rows,clms):rows)+2)*M->unit, EXIT); + M->buf = (QUEUE_INT *)buf; + malloc2 (M->v, rows+1, {free(M->buf);EXIT;}); + ARY_FILL (M->v, 0, rows, INIT_QUEUE); + M->end = rows; + M->clms = clms; + if ( rowt ){ + FLOOP (i, 0, rows){ + M->v[i].v = (QUEUE_INT *)buf; + buf += (rowt[i] +1)*M->unit; + M->v[i].end = rowt[i]+1; + } + } +} + +/* allocate memory according to rows and rowt */ +/* if eles == 0, compute eles from rowt and rows */ +void SETFAMILY_alloc_weight (SETFAMILY *M){ + VEC_ID i; + calloc2 (M->w, M->end +1, EXIT); + calloc2 (M->wbuf, M->ele_end*((M->flag&LOAD_DBLBUF)?2:1)+1, {free(M->w);EXIT;}); + FLOOP (i, 1, M->t) M->w[i] = i? M->w[i-1] + M->v[i-1].t: M->wbuf; +} + +/* terminate routine for MAT */ +void SETFAMILY_end (SETFAMILY *M){ + mfree (M->buf, M->buf2, M->v, M->rw, M->cw, M->wbuf, M->w); + *M = INIT_SETFAMILY; +} + +/****************************************************************/ +/****************************************************************/ +/****************************************************************/ + +/* read binary file for MAT */ +/* each unit-byte will be one number. if unit<0, the sign of unit is flipped, and each value is minesed the half of the maximum */ +void MAT_load_bin (MAT *M, FILE2 *fp, int unit){ + VEC_ID flag=0, i, j, jj; + size_t siz=0; + VEC_VAL z, neg=0; + + if ( unit < 0 ){ + unit = -unit; flag = 1; neg=128; + FLOOP (jj, 0, unit-1) neg *= 256; + } + if ( M->t == 0 ){ // determine #rows if M->t is 0 (not specified) + fseek(fp->fp, 0, SEEK_END); + siz = ftell(fp->fp); + fseek(fp->fp, 0, SEEK_SET); + M->t = (VEC_ID)(siz / unit / M->clms); + if ( M->flag & LOAD_TPOSE ) SWAP_VEC_ID (M->t, M->clms); + } + MAT_alloc (M, M->t, M->clms); if (ERROR_MES) return; + M->end = M->t; + FLOOP (i, 0, M->t){ + FLOOP (j, 0, M->clms){ + z=0; FLOOP (jj, 0, unit){ z *= 256; z += FILE2_getc (fp); } + if ( flag ) z -= neg; + if ( M->flag & LOAD_TPOSE ) M->v[j].v[i] = z; + else M->v[i].v[j] = z; + } + } +} + +/* segmentation fault for illegal files */ +/* count/read the number in file for MAT */ +/* if *rows>0, only read count the numbers in a row, for the first scan. */ +void MAT_file_load (MAT *M, FILE2 *fp){ + QUEUE_ID c; + VEC_ID t=0; + double p; + + for (t=0 ; (FILE_err&2)==0 ; t++){ + ARY_SCAN (c, double, *fp, 0); + if ( M->flag & LOAD_TPOSE ){ + if ( M->t == 0 ){ M->t = c; if ( M->clms>0 ) break; } + } else if ( M->clms == 0 ){ M->clms = c; if ( M->t>0 ) break; } + if ( c == 0 ) t--; + } + if ( M->flag & LOAD_TPOSE ){ if ( M->clms==0 ) M->clms = t;} else if ( M->t==0 ) M->t = t; + FILE2_reset (fp); + M->end = M->t; + MAT_alloc (M, M->t, M->clms); if (ERROR_MES) return; + FLOOP (t, 0, (M->flag&LOAD_TPOSE)? M->clms: M->t){ + FLOOP (c, 0, (M->flag&LOAD_TPOSE)? M->t: M->clms){ + p = FILE2_read_double(fp); + if ( FILE_err==1 || FILE_err==2 ) break; + if ( M->flag&LOAD_TPOSE ) M->v[c].v[t] = p; + else M->v[t].v[c] = p; + if ( FILE_err==5 || FILE_err==6 ) break; + } + FLOOP (c, c, (M->flag&LOAD_TPOSE)? M->t: M->clms){ + if ( M->flag&LOAD_TPOSE ) M->v[c].v[t] = 0; + else M->v[t].v[c] = 0; + } + if ( !FILE_err ) FILE2_read_until_newline (fp); + } +} + +/* load file with switching the format according to the flag */ +void MAT_load (MAT *M){ + FILE2 fp = INIT_FILE2; + int unit=0; +#ifdef USE_MATH + VEC_ID i; +#endif + if ( M->flag & VEC_LOAD_BIN ) unit = 1; + else if ( M->flag & VEC_LOAD_BIN2 ) unit = 2; + else if ( M->flag & VEC_LOAD_BIN4 ) unit = 4; + if ( M->flag & VEC_LOAD_CENTERIZE ) unit = -unit; + + FILE2_open (fp, M->fname, "rb", EXIT); + if ( unit ) MAT_load_bin (M, &fp, unit); + else MAT_file_load (M, &fp); + + FILE2_close (&fp); if (ERROR_MES) EXIT; +#ifdef USE_MATH + if ( M->flag&VEC_NORMALIZE ) FLOOP (i, 0, M->t) ARY_NORMALIZE (M->v[i].v,M->v[i].t); +#endif + print_mes (M, "mat: %s ,#rows %d ,#clms %d\n", M->fname, M->t, M->clms); +} + + +/* scan file and read the numbers for SMAT */ +/* flag&1? SMAT, SETFAMILY, flag&2? tuple list format: array list :*/ +void SMAT_file_load (SMAT *M, FILE2 *fp){ + SVEC_VAL z=0; + VEC_ID flag= (M->type==TYPE_SMAT), t, x, y; + FILE_COUNT C; + + C = FILE2_count (fp, (M->flag&(LOAD_ELE+LOAD_TPOSE)) | FILE_COUNT_ROWT, 0, 0, 0, 0, 0); + if ( M->clms == 0 ) M->clms = C.clms; + if ( M->t == 0 ) M->t = C.rows; + if ( flag ) SMAT_alloc (M, M->t, C.rowt, M->clms, 0); + else SETFAMILY_alloc ((SETFAMILY *)M, M->t, C.rowt, M->clms, 0); + free2 (C.rowt); + if ( ERROR_MES ) return; + FILE2_reset (fp); + t=0; + do { + if ( M->flag&LOAD_ELE ){ + x = (VEC_ID)FILE2_read_int (fp); + y = (VEC_ID)FILE2_read_int (fp); + if ( flag ) z = FILE2_read_double (fp); + if ( FILE_err&4 ) goto LOOP_END2; + FILE2_read_until_newline (fp); + } else { + x = t; + y = (VEC_ID)FILE2_read_int (fp); + if ( FILE_err&4 ) goto LOOP_END2; + if ( flag ) z = FILE2_read_double (fp); + } + if ( M->flag&LOAD_TPOSE ) SWAP_VEC_ID (x, y); +// printf ("%d %d %d %d\n", x, M->t, y, M->clms); + if ( y >= M->clms || x >= M->t ) goto LOOP_END2; +// printf ("## %d %d\n", x, y); + if ( flag ){ + M->v[x].v[M->v[x].t].i = y; + M->v[x].v[M->v[x].t].a = z; + M->v[x].t++; + } else QUE_INS (((SETFAMILY *)M)->v[x], y); + LOOP_END2:; + if ( !(M->flag&LOAD_ELE) && (FILE_err&3) ){ t++; if ( t >= M->t ) break; } + } while ( (FILE_err&2)==0 ); +} + +/* scan file and read the numbers for SMAT */ +/* flag&1? SMAT, SETFAMILY, flag&2? tuple list format: array list :*/ +void SETFAMILY_load_weight (SETFAMILY *M){ + FILE2 fp = INIT_FILE2; + VEC_ID i; + QUEUE_ID j; + if ( M->flag&LOAD_TPOSE ) error ("transope and weight can't be specified simultaneously", EXIT); + FILE2_open (fp, M->wfname, "r", EXIT); + SETFAMILY_alloc_weight (M); + FLOOP (i, 0, M->t){ + FLOOP (j, 0, M->v[i].t) + M->w[i][j] = (WEIGHT)FILE2_read_double (&fp); + FILE2_read_until_newline (&fp); + } +} + +void SETFAMILY_load_column_weight (SETFAMILY *M){ + int i; +#ifdef WEIGHT_DOUBLE + ARY_LOAD (M->cw, double, i, M->cwfname, 1, EXIT); +#else + ARY_LOAD (M->cw, int, i, M->cwfname, 1, EXIT); +#endif + if ( i < M->clms ){ realloc2 (M->cw, M->clms+1, EXIT); ARY_FILL (M->cw, i, M->clms+1, 0); } +} + +void SETFAMILY_load_row_weight (SETFAMILY *M){ + int i; +#ifdef WEIGHT_DOUBLE + ARY_LOAD (M->rw, double, i, M->rwfname, 1, EXIT); +#else + ARY_LOAD (M->rw, int, i, M->rwfname, 1, EXIT); +#endif + if ( i < M->t ){ realloc2 (M->rw, M->t+1, EXIT); ARY_FILL (M->rw, i, M->t+1, 0); } +} + + +/* load file with switching the format according to the flag */ +void SMAT_load (SMAT *M){ + FILE2 fp = INIT_FILE2; + VEC_ID i; + M->type = TYPE_SMAT; + FILE2_open (fp, M->fname, "r", EXIT); + SMAT_file_load (M, &fp); + FILE2_close (&fp); if (ERROR_MES) EXIT; + FLOOP (i, 0, M->t) M->v[i].v[M->v[i].t].i = M->clms; // end mark + +#ifdef USE_MATH + if ( M->flag&VEC_NORMALIZE ) FLOOP (i, 0, M->t) SVEC_normalize (&M->v[i]); // normalize +#endif + if (M->flag&LOAD_INCSORT) + FLOOP (i, 0, M->t) qsort_VEC_ID ((VEC_ID *)(M->v[i].v), M->v[i].t, sizeof(SVEC_ELE)); + if (M->flag&LOAD_DECSORT) + FLOOP (i, 0, M->t) qsort_VEC_ID ((VEC_ID *)(M->v[i].v), M->v[i].t, -(int)sizeof(SVEC_ELE)); + if (M->flag&LOAD_RM_DUP) + FLOOP (i, 0, M->t) MQUE_UNIFY (M->v[i], SVEC_VAL); + M->eles = M->ele_end; + print_mes (M, "smat: %s ,#rows %d ,#clms %d ,#eles %zd\n", M->fname, M->t, M->clms, M->eles); + +} + +/* sort and duplication check */ +void SETFAMILY_sort (SETFAMILY *M){ + VEC_ID i; + PERM *p; + WEIGHT *ww; + QUEUE Q; + int flag = (M->flag&LOAD_INCSORT)? 1: ((M->flag&LOAD_DECSORT)? -1: 0); + if ( flag ){ // sort items in each row + malloc2 (p, M->clms, EXIT); + FLOOP (i, 0, M->t) + QUEUE_perm_WEIGHT (&M->v[i], M->w?M->w[i]:NULL, p, flag); + free (p); + } + flag = ((M->flag&LOAD_SIZSORT)? ((M->flag&LOAD_DECROWSORT)? -1: 1): 0) *sizeof(QUEUE); + if ( flag ){ // sort the rows + p = qsort_perm_VECt ((VEC *)M->v, M->t, flag); + if ( M->w ) ARY_INVPERMUTE_ (M->w, p, ww, M->t); + ARY_INVPERMUTE (M->v, p, Q, M->t, EXIT); + free (p); + } + if (M->flag&LOAD_RM_DUP){ // unify the duplicated edges + FLOOP (i, 0, M->t) + QUEUE_rm_dup_WEIGHT (&M->v[i], M->w?M->w[i]:NULL); + } +} + +/* scan file and load the data from file to SMAT structure */ +void SETFAMILY_load (SETFAMILY *M){ + FILE2 fp = INIT_FILE2; + VEC_ID i; + M->type = TYPE_SETFAMILY; + FILE2_open (fp, M->fname, "r", EXIT); + SMAT_file_load ((SMAT *)M, &fp); + FILE2_close (&fp); if(ERROR_MES) EXIT; + print_mes (M, "setfamily: %s ,#rows %d ,#clms %d ,#eles %zd", M->fname, M->t, M->clms, M->eles); + if ( !(M->flag&LOAD_ELE) && M->wfname ){ + SETFAMILY_load_weight (M); if ( ERROR_MES ){ SETFAMILY_end (M); EXIT; } + print_mes (M, " ,weightfile %s", M->wfname); + } + print_mes (M, "\n"); + + SETFAMILY_sort (M); + FLOOP (i, 0, M->t) M->v[i].v[M->v[i].t] = M->clms; // end mark + M->eles = M->ele_end; + +} + +/* print routines */ +void MAT_print (FILE *fp, MAT *M){ + VEC *V; + MQUE_FLOOP (*M, V) ARY_FPRINT (fp, V->v, 0, V->t, VEC_VALF" "); +} +void SVEC_print (FILE *fp, SVEC *V){ + SVEC_ELE *x; + MQUE_FLOOP (*V, x) fprintf (fp, "("QUEUE_IDF","SVEC_VALF") ", (*x).i, (*x).a); + fputc ('\n', fp); +} +void SMAT_print (FILE *fp, SMAT *M){ + SVEC *V; + MQUE_FLOOP (*M, V) SVEC_print (fp, V); +} +void SETFAMILY_print (FILE *fp, SETFAMILY *M){ + QUEUE *V; + MQUE_FLOOP (*M, V) ARY_FPRINT (fp, V->v, 0, V->t, QUEUE_INTF" "); +} + +/* +void SETFAMILY_print_WEIGHT (FILE *fp, SETFAMILY *M){ + if ( M->w ){ + printf (","); fprint_WEIGHT (stdout, M->w[i][j]); } + printf ("\n"); +} +*/ + +/****************************************************************/ +/** Inner product routines **************************************/ +/****************************************************************/ +SVEC_VAL2 SVEC_inpro (SVEC *V1, SVEC *V2){ + VEC_ID i1, i2=0; + SVEC_VAL2 sum=0; + FLOOP (i1, 0, V1->t){ + while (V2->v[i2].i < V1->v[i1].i) i2++; + if (V2->v[i2].i == V1->v[i1].i) sum += ((SVEC_VAL2)V2->v[i2].a)*V1->v[i1].a; + } + return (sum); +} + + +/* get ith vector */ +void *MVEC_getvec (void *M, int i, int flag){ + MAT *MM = (MAT *)M; + if (MM->type==TYPE_MAT) return (&MM->v[i]); + if (MM->type==TYPE_SMAT) return (&((SVEC *)M)->v[i]); + if (MM->type==TYPE_SETFAMILY) return (&((QUEUE *)M)->v[i]); + return (NULL); +} + +/* compute the inner product of two vectors */ +double VEC_inpro (VEC *V1, VEC *V2){ + VEC_VAL sum=0; + VEC_VAL *v1 = V1->v, *v2 = V2->v, *v_end = v1 + MIN (V1->end, V2->end), *vv=v_end-1; +#ifdef USE_SIMD + __m128d u1, u2, u3; + double r[2]; + if ( v1 < vv ){ + u3 = _mm_load_pd (v1); v1 += 2; + u2 = _mm_load_pd (v2); v2 += 2; + u3 = _mm_mul_pd (u3, u2); + while ( v1 < vv ){ + u1 = _mm_load_pd (v1); v1 += 2; + u2 = _mm_load_pd (v2); v2 += 2; + u1 = _mm_mul_pd (u1, u2); + u3 = _mm_add_pd (u3, u1); + } + _mm_storeu_pd (r, u3); + sum = r[0]+r[1]; + _mm_empty(); + } +#else + VEC_VAL a0, a1; + while ( v1 < vv ){ + a0 = *v1 * *v2; v1++; v2++; + a1 = *v1 * *v2; v1++; v2++; + sum += a0 + a1; + } +#endif + if ( v1 < v_end ){ sum += *v1 * *v2; } + return (sum); +} + +/* compute the l1-norm of two vectors */ +double VEC_l1dist (VEC *V1, VEC *V2){ + VEC_ID i, end=MIN(V1->end,V2->end); + double sum=0; + FLOOP (i, 0, end) sum += abs (((double)V1->v[i])- ((double)V2->v[i])); + return (sum); +} + +/* compute the l-infinity-norm of two vectors */ +double VEC_linfdist (VEC *V1, VEC *V2){ + VEC_ID i, end=MIN(V1->end,V2->end); + double m=0; + FLOOP (i, 0, end) ENMAX (m, abs (((double)V1->v[i])- ((double)V2->v[i]))); + return (m); +} + +double SETFAMILY_resemblance (QUEUE *Q1, QUEUE *Q2){ + int *x, *y=Q2->v, *yy = y+Q2->t, s=0; + MQUE_FLOOP (*Q1, x){ + while ( *y < *x ){ if ( ++y == yy ) goto END; } + if ( *y == *x ){ s++; if ( ++y == yy ) goto END; } + } + END:; + return ( ((double)s) / ((double)(Q1->t + Q2->t))); +} + + +#ifdef USE_MATH + +/****************************************************************/ +/** Norm computation and normalization ************************/ +/****************************************************************/ +double SVEC_norm (SVEC *V){ + SVEC_ELE *v; + double sum=0; + MQUE_FLOOP (*V, v) sum += ((double)(v->a)) * (v->a); + return (sqrt(sum)); +} +void SVEC_normalize (SVEC *V){ + SVEC_ELE *v; + double norm = SVEC_norm (V); + MQUE_FLOOP (*V, v) v->a /= norm; +} + +double VEC_norm (VEC *V){ + return (sqrt (VEC_inpro (V, V))); +} + +void VEC_normalize (VEC *V){ + double norm = VEC_norm (V); + VEC_VAL *v = V->v, *v_end = v + V->end; +#ifdef USE_SIMD + __m128d u1, u2; + while ( v < v_end ){ + u1 = _mm_load_pd (v); + u2 = _mm_load1_pd (&norm); + u1 = _mm_div_pd (u1, u2); + _mm_storeu_pd (v, u1); + } + _mm_empty(); + if ( v < v_end ) *v /= norm; +#else + while ( v < v_end ) *v /= norm; +#endif +} + +/****************************************************************/ +/** Euclidean distance routines *********************************/ +/****************************************************************/ + +/* compute the Euclidean distance of two vectors (VEC) */ +double VEC_eucdist_ (VEC *V1, VEC *V2){ + double sum=0, a0; + VEC_VAL *v1 = V1->v, *v2 = V2->v, *v_end = v1 + MIN (V1->end, V2->end), *vv=v_end-1; +#ifdef USE_SIMD + __m128d u1, u2, u3; + double r[2]; + if ( v1 < vv ){ + u3 = _mm_load_pd (v1); v1 += 2; + u2 = _mm_load_pd (v2); v2 += 2; + u3 = _mm_sub_pd (u3, u2); + u3 = _mm_mul_pd (u3, u3); + while ( v1 < vv ){ + u1 = _mm_load_pd (v1); v1 += 2; + u2 = _mm_load_pd (v2); v2 += 2; + u1 = _mm_sub_pd (u1, u2); + u1 = _mm_mul_pd (u1, u1); + u3 = _mm_add_pd (u3, u1); + } + _mm_storeu_pd (r, u3); + sum = r[0]+r[1]; + _mm_empty(); + } +#else + double a1; + while ( v1 < vv ){ + a0 = *v1 - *v2; v1++; v2++; + a1 = *v1 - *v2; v1++; v2++; + sum += a0*a0 + a1*a1; + } +#endif + if ( v1 < v_end ){ a0 = *v1 - *v2; sum += a0*a0; } + return (sum); +} + +double VEC_eucdist (VEC *V1, VEC *V2){ + double p = SQRT (VEC_eucdist_ (V1, V2)); +#ifdef USE_SIMD + _mm_empty (); +#endif + return (p); +} + +/* compute the Euclidean distance of two vectors (SVEC)*/ +double SVEC_eucdist_ (SVEC *V1, SVEC *V2){ + VEC_ID i1, i2; + double sum=0, a; + for ( i1=i2=0 ; i1t && i2t ; ){ + if (V2->v[i2].i > V1->v[i1].i) a = V1->v[i1].a; + else if (V2->v[i2].i < V1->v[i1].i) a = V2->v[i2].a; + else a = ((double)V2->v[i2].a) - ((double)V1->v[i1].a); + sum += a*a; + } + return (sum); +} + +double SVEC_eucdist (SVEC *V1, SVEC *V2){ + return (sqrt (SVEC_eucdist (V1, V2))); +} + +/* compute the Euclidean distance of two vectors (VEC * SVEC)*/ +double VEC_SVEC_eucdist (VEC *V1, SVEC *V2){ + VEC_ID i, i2=0; + double sum=0, a; + FLOOP (i, 0, V1->end){ + if ( i < V2->v[i2].i ) a = V1->v[i]; + else { a = ((double)V1->v[i]) - ((double)V2->v[i2].a); i2++; } + sum += a*a; + } + return (sqrt(sum)); +} + +/**********************************************************/ +/* Euclidean distance of vector and set */ +double VEC_QUEUE_eucdist (VEC *V, QUEUE *Q){ + VEC_ID i; + QUEUE_ID i2=0; + double sum=0, a; + FLOOP (i, 0, V->end){ + if ( i < Q->v[i2] ) a = V->v[i]; + else { a = ((double)V->v[i]) - 1.0; i2++; } + sum += a*a; + } + return (sqrt(sum)); +} + +/* compute Euclidean distance of two sets */ +double QUEUE_eucdist (QUEUE *Q1, QUEUE *Q2){ + double f; + MQUE_UNION(f, *Q1, *Q2); + return (sqrt(f)); +} + +double MVEC_norm (void *V){ + VEC *VV = (VEC *)V; + double p; + if (VV->type==TYPE_VEC){ ARY_NORM (p, VV->v, VV->t); return (p); } + if (VV->type==TYPE_SVEC) return (SVEC_norm ((SVEC *)V)); + if (VV->type==TYPE_QUEUE) return (sqrt(((QUEUE*)V)->t)); + return (0.0); +} + +double MMAT_norm_i (void *M, int i){ + MAT *MM = (MAT *)M; + double p; + if (MM->type==TYPE_MAT){ ARY_NORM (p, MM->v[i].v, MM->v[i].t); return (p); } + if (MM->type==TYPE_SMAT) return (SVEC_norm (&((SMAT *)M)->v[i])); + if (MM->type==TYPE_SETFAMILY) return (sqrt (((SETFAMILY *)M)->v[i].t)); + return (0.0); +} + +double MVEC_eucdist (void *V, void *U){ + VEC *VV = (VEC *)V; + double p; + if (VV->type==TYPE_VEC) return (VEC_eucdist ((VEC *)V, (VEC *)U)); + if (VV->type==TYPE_SVEC) return (SVEC_eucdist ((SVEC *)V, (SVEC *)U)); + if (VV->type==TYPE_QUEUE){ MQUE_DIF (p, *((QUEUE *)V), *((QUEUE *)U)); return (sqrt(p));} + return (0.0); +} + +double MMAT_eucdist_ij (void *M, int i, int j){ + MAT *MM=(MAT *)M; + double p; + if (MM->type==TYPE_MAT) return (VEC_eucdist ( &MM->v[i], &MM->v[j] )); + if (MM->type==TYPE_SMAT) return (SVEC_eucdist ( &((SMAT *)M)->v[i], &((SMAT *)M)->v[j])); + if (MM->type==TYPE_SETFAMILY){ MQUE_DIF (p, ((SETFAMILY *)M)->v[i], ((SETFAMILY *)M)->v[j]); return (sqrt(p)); } + return (0.0); +} + + +#endif + +/**********************************************************/ +/** multi-vector routines ******************************/ +/**********************************************************/ + +/* compute the inner product, Euclidean distance for multi vector */ +double MVEC_inpro (void *V, void *U){ + VEC *VV = (VEC *)V, *UU = (VEC *)U; + double p; + if (VV->type==TYPE_VEC){ + if (UU->type==TYPE_VEC){ ARY_INPRO (p, VV->v, UU->v, VV->t); return (p); } + if (UU->type==TYPE_SVEC){ ARY_SVEC_INPRO (p, *((SVEC *)U), VV->v); return (p); } + if (UU->type==TYPE_QUEUE){ ARY_QUEUE_INPRO (p, *((QUEUE *)U), VV->v); return (p); } + } + if (VV->type==TYPE_SVEC){ + if (UU->type==TYPE_VEC){ ARY_SVEC_INPRO (p, *((SVEC *)V), UU->v); return (p);} + if (UU->type==TYPE_SVEC) return (SVEC_inpro ((SVEC *)V, (SVEC *)U)); +// if (UU->type==TYPE_QUEUE) return (VEC_QUEUE_inpro (V, U)); + } + if (VV->type==TYPE_QUEUE){ + if (UU->type==TYPE_VEC){ ARY_QUEUE_INPRO (p, *((QUEUE *)V), UU->v); return (p); } +// else if (UU->type==TYPE_SVEC) return (SVEC_inpro (V, U)); + if (UU->type==TYPE_QUEUE){ MQUE_INTSEC (p, *((QUEUE *)V), *((QUEUE *)U)); return (p);} + } + return (0.0); +} + +double MVEC_double_inpro (void *V, double *w){ + VEC *VV = (VEC *)V; + double p; + if (VV->type==TYPE_VEC){ ARY_INPRO (p, VV->v, w, VV->t); return (p); } + if (VV->type==TYPE_SVEC){ ARY_SVEC_INPRO (p, *((SVEC *)V), w); return (p); } + if (VV->type==TYPE_QUEUE){ ARY_QUEUE_INPRO (p, *((QUEUE *)V), w); return (p); } + return (0.0); +} + +/* compute the inner product, euclidean distance for i,jth vector */ +double MMAT_inpro_ij (void *M, int i, int j){ + MAT *MM = (MAT *)M; + double p; + if (MM->type==TYPE_MAT){ ARY_INPRO (p, MM->v[i].v, MM->v[j].v, MM->v[j].t); return (p); } + if (MM->type==TYPE_SMAT) return (SVEC_inpro (&((SMAT *)M)->v[i], &((SMAT *)M)->v[j])); + if (MM->type==TYPE_SETFAMILY){ + p = QUEUE_intsec_ (&((SETFAMILY *)M)->v[i], &((SETFAMILY *)M)->v[j]); return (p); } + return (0.0); +} + +double MMAT_double_inpro_i (void *M, int i, double *w){ + MAT *MM = (MAT *)M; + double p; + if (MM->type==TYPE_MAT){ ARY_INPRO (p, MM->v[i].v, w, MM->v[i].t); return (p); } + if (MM->type==TYPE_SMAT){ ARY_SVEC_INPRO (p, ((SMAT *)M)->v[i], w); return (p); } + if (MM->type==TYPE_SETFAMILY){ ARY_QUEUE_INPRO (p, ((SETFAMILY *)M)->v[i], w); return (p); } + return (0.0); +} + +#ifdef _barray_h_ +void SETFAMILY_to_BARRAY (BARRAY *A, SETFAMILY *F){ + VEC_ID t; + size_t i=0; + BARRAY_init (A, F->clms, F->t); + FLOOP (t, 0, F->t){ + BARRAY_set_subset (&A->v[i], &F->v[t]); + i += A->xend; + } +} +#endif + +#endif + + diff --git a/rql-backend/shd31/vec.h b/rql-backend/shd31/vec.h new file mode 100644 index 0000000..7f8dab8 --- /dev/null +++ b/rql-backend/shd31/vec.h @@ -0,0 +1,171 @@ +/* library for sparse vector */ +/* Takeaki Uno 27/Dec/2008 */ + +#ifndef _vec_h_ +#define _vec_h_ + +//#define USE_MATH + +#include"math.h" +#include"queue.h" + +#ifndef SVEC_VAL + #ifdef SVEC_VAL_INT + #define SVEC_VAL int + #define SVEC_VAL2 LONG + #define SVEC_VAL_END INTHUGE + #define SVEC_VAL2_END LONGHUGE + #define SVEC_VALF "%d" + #else + #define SVEC_VAL double + #define SVEC_VAL2 double + #define SVEC_VAL_END DOUBLEHUGE + #define SVEC_VAL2_END DOUBLEHUGE + #define SVEC_VALF "%f" + #endif +#endif + +#define VEC_LOAD_BIN 16777216 // read binary file +#define VEC_LOAD_BIN2 33554432 // read binary file with 2byte for each number +#define VEC_LOAD_BIN4 67108864 // read binary file with 4byte for each number +#define VEC_LOAD_CENTERIZE 134217728 // read binary file, and minus the half(128) from each number +#define VEC_NORMALIZE 268435456 // read binary file, and minus the half(128) from each number + +/* matrix */ +typedef struct { + unsigned char type; // mark to identify type of the structure + char *fname; // input file name + int flag; // flag + + VEC *v; + VEC_ID end; + VEC_ID t; + VEC_VAL *buf, *buf2; + VEC_ID clms; + size_t eles; + VEC_VAL *buf_org, *buf2_org; +} MAT; + +/* sparse vector, element */ +typedef struct { + QUEUE_ID i; + SVEC_VAL a; +} SVEC_ELE; + +/* sparse vector, vector */ +typedef struct { + unsigned char type; // mark to identify type of the structure + SVEC_ELE *v; + VEC_ID end; + VEC_ID t; +} SVEC; + +/* sparse vector, matrix */ +typedef struct { + unsigned char type; // mark to identify type of the structure + char *fname; // input file name + int flag; // flag + + SVEC *v; + VEC_ID end; + VEC_ID t; + SVEC_ELE *buf, *buf2; + VEC_ID clms; + size_t eles, ele_end; +} SMAT; + +/* set family */ +typedef struct { + unsigned char type; // mark to identify type of the structure + char *fname; // input file name + int flag; // flag + + QUEUE *v; + VEC_ID end; + VEC_ID t; + QUEUE_INT *buf, *buf2; + VEC_ID clms; + size_t eles, ele_end; + WEIGHT *cw, *rw, **w, *wbuf; + int unit; + char *wfname, *cwfname, *rwfname; // weight file name +} SETFAMILY; + +#define INIT_SETFAMILY_ {TYPE_SETFAMILY,NULL,0,NULL,0,0,NULL,NULL,0,0,0,NULL,NULL,NULL,NULL,sizeof(QUEUE_INT),NULL,NULL,NULL} + +extern MAT INIT_MAT; +extern SVEC INIT_SVEC; +extern SMAT INIT_SMAT; +extern SETFAMILY INIT_SETFAMILY; + +QSORT_TYPE_HEADER (SVEC_VAL, SVEC_VAL) +QSORT_TYPE_HEADER (SVEC_VAL2, SVEC_VAL2) + +#define ARY_QUEUE_INPRO(f,U,V) do{(f)=0;FLOOP(common_QUEUE_ID, 0, (QUEUE_ID)(U).t)(f)+=(V)[(U).v[common_QUEUE_ID]];}while(0) +#define ARY_SVEC_INPRO(f,U,V) do{(f)=0;FLOOP(common_VEC_ID, 0, (VEC_ID)(U).t)(f)+=((double)(U).v[common_VEC_ID].a)*(V)[(U).v[common_VEC_ID].i];}while(0) + +/* terminate routine for VEC */ +void VEC_end (VEC *V); +void MAT_end (MAT *M); +void SVEC_end (SVEC *V); +void SMAT_end (SMAT *M); +void SETFAMILY_end (SETFAMILY *M); + +/* allocate memory according to rows and rowt */ +void VEC_alloc (VEC *V, VEC_ID clms); +void MAT_alloc (MAT *M, VEC_ID rows, VEC_ID clms); +void SVEC_alloc (SVEC *V, VEC_ID end); +void SMAT_alloc (SMAT *M, VEC_ID rows, VEC_ID *rowt, VEC_ID clms, size_t eles); +void SETFAMILY_alloc (SETFAMILY *M, VEC_ID rows, VEC_ID *rowt, VEC_ID clms, size_t eles); +void SETFAMILY_alloc_weight (SETFAMILY *M); + +/* count/read the number in file for MAT */ +/* if *rows>0, only read count the numbers in a row, for the first scan. */ +void MAT_load_bin (MAT *M, FILE2 *fp, int unit); +void MAT_file_load (MAT *M, FILE2 *fp); +void MAT_load (MAT *M); +void SMAT_load (SMAT *M); +void SETFAMILY_load (SETFAMILY *M); +void SETFAMILY_load_weight (SETFAMILY *M); +void SETFAMILY_load_row_weight (SETFAMILY *M); +void SETFAMILY_load_column_weight (SETFAMILY *M); + +void MAT_print (FILE *fp, MAT *M); +void SVEC_print (FILE *fp, SVEC *M); +void SMAT_print (FILE *fp, SMAT *M); +void SETFAMILY_print (FILE *fp, SETFAMILY *M); +void SETFAMILY_print_weight (FILE *fp, SETFAMILY *M); + + +/* norm, normalization **************************/ +double SVEC_norm (SVEC *V); +void SVEC_normalize (SVEC *V); + +/* inner product **************************/ +SVEC_VAL2 SVEC_inpro (SVEC *V1, SVEC *V2); + +/** Euclidean distance routines *********************************/ +double VEC_eucdist (VEC *V1, VEC *V2); +double SVEC_eucdist (SVEC *V1, SVEC *V2); +double VEC_SVEC_eucdist (VEC *V1, SVEC *V2); +double QUEUE_eucdist (QUEUE *Q1, QUEUE *Q2); +double VEC_QUEUE_eucdist (VEC *V, QUEUE *Q); + +void VEC_rand_gaussian (VEC *V); + +double VEC_linfdist (VEC *V1, VEC *V2); + +/* compute the inner product, Euclidean distance for multi vector */ +double MVEC_norm (void *V); +double MVEC_inpro (void *V, void *U); +double MVEC_double_inpro (void *V, double *p); +double MVEC_eucdist (void *V, void *U); + +/* compute the inner product, euclidean distance for i,jth vector */ +double MMAT_inpro_ij (void *M, int i, int j); +double MMAT_double_inpro_i (void *M, int i, double *p); +double MMAT_eucdist_ij (void *M, int i, int j); +double MMAT_norm_i (void *M, int i); + + +#endif diff --git a/rql-ui/.babelrc b/rql-ui/.babelrc new file mode 100644 index 0000000..9390d16 --- /dev/null +++ b/rql-ui/.babelrc @@ -0,0 +1,18 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"], + "env": { + "test": { + "presets": ["env", "stage-2"], + "plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"] + } + } +} diff --git a/rql-ui/.editorconfig b/rql-ui/.editorconfig new file mode 100644 index 0000000..9d08a1a --- /dev/null +++ b/rql-ui/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/rql-ui/.eslintignore b/rql-ui/.eslintignore new file mode 100644 index 0000000..e2192c5 --- /dev/null +++ b/rql-ui/.eslintignore @@ -0,0 +1,5 @@ +/build/ +/config/ +/dist/ +/*.js +/test/unit/coverage/ diff --git a/rql-ui/.eslintrc.js b/rql-ui/.eslintrc.js new file mode 100644 index 0000000..a7e6ac8 --- /dev/null +++ b/rql-ui/.eslintrc.js @@ -0,0 +1,33 @@ +// https://eslint.org/docs/user-guide/configuring + +module.exports = { + "globals": { + "$": true, + "jQuery": true, + "jquery": true, + "window": true, + "document": true + }, + root: true, + parser: 'babel-eslint', + parserOptions: { + sourceType: 'module' + }, + env: { + browser: true, + jquery: true, + }, + // https://github.com/standard/standard/blob/master/docs/RULES-en.md + extends: 'standard', + // required to lint *.vue files + plugins: [ + 'html' + ], + // add your custom rules here + rules: { + // allow async-await + 'generator-star-spacing': 'off', + // allow debugger during development + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' + } +} diff --git a/rql-ui/.gitignore b/rql-ui/.gitignore new file mode 100644 index 0000000..dfb4167 --- /dev/null +++ b/rql-ui/.gitignore @@ -0,0 +1,17 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +/test/unit/coverage/ +/test/e2e/reports/ +selenium-debug.log + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/rql-ui/.postcssrc.js b/rql-ui/.postcssrc.js new file mode 100644 index 0000000..eee3e92 --- /dev/null +++ b/rql-ui/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/rql-ui/Dockerfile b/rql-ui/Dockerfile new file mode 100644 index 0000000..25d8d75 --- /dev/null +++ b/rql-ui/Dockerfile @@ -0,0 +1,22 @@ +FROM node:20 AS build-node-stage + +WORKDIR /work +ADD package.json /work +ADD package-lock.json /work +RUN ["npm", "install"] + +ADD .eslintrc.js /work +ADD .postcssrc.js /work +ADD index.html /work +ADD static /work/static/ +ADD config /work/config/ +ADD build /work/build/ +ADD src /work/src/ +RUN ["npm", "run", "build"] + +FROM nginx:latest + +COPY --from=build-node-stage /work/dist/ /usr/share/nginx/html/ +ADD default.conf /etc/nginx/conf.d + +LABEL maintainer="Bilal REZKELLAH" \ No newline at end of file diff --git a/rql-ui/build/build.js b/rql-ui/build/build.js new file mode 100644 index 0000000..e3a20f9 --- /dev/null +++ b/rql-ui/build/build.js @@ -0,0 +1,49 @@ +"use strict"; +require("./check-versions")(); + +process.env.NODE_ENV = "production"; + +const ora = require("ora"); +const rm = require("rimraf"); +const path = require("path"); +const chalk = require("chalk"); +const webpack = require("webpack"); +const config = require("../config"); +const webpackConfig = require("./webpack.prod.conf"); + +const spinner = ora("building for production..."); +spinner.start(); + +rm( + path.join(config.build.assetsRoot, config.build.assetsSubDirectory), + (err) => { + if (err) throw err; + webpack(webpackConfig, (err, stats) => { + spinner.stop(); + if (err) throw err; + process.stdout.write( + stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false, + }) + "\n\n" + ); + + if (stats.hasErrors()) { + console.log(chalk.red(" Build failed with errors.\n")); + process.exit(1); + } + + console.log(chalk.cyan(" Build complete.\n")); + console.log( + chalk.yellow( + " Tip: built files are meant to be served over an HTTP server.\n" + + " Opening index.html over file:// won't work.\n" + ) + ); + process.exit(0); + }); + } +); diff --git a/rql-ui/build/check-versions.js b/rql-ui/build/check-versions.js new file mode 100644 index 0000000..3ef972a --- /dev/null +++ b/rql-ui/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/rql-ui/build/logo.png b/rql-ui/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/rql-ui/build/vue-loader.conf.js b/rql-ui/build/vue-loader.conf.js new file mode 100644 index 0000000..33ed58b --- /dev/null +++ b/rql-ui/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/rql-ui/build/webpack.base.conf.js b/rql-ui/build/webpack.base.conf.js new file mode 100644 index 0000000..1f4f47e --- /dev/null +++ b/rql-ui/build/webpack.base.conf.js @@ -0,0 +1,92 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +const createLintingRule = () => ({ + test: /\.(js|vue)$/, + loader: 'eslint-loader', + enforce: 'pre', + include: [resolve('src'), resolve('test')], + options: { + formatter: require('eslint-friendly-formatter'), + emitWarning: !config.dev.showEslintErrorsInOverlay + } +}) + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + ...(config.dev.useEslint ? [createLintingRule()] : []), + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/rql-ui/build/webpack.dev.conf.js b/rql-ui/build/webpack.dev.conf.js new file mode 100644 index 0000000..070ae22 --- /dev/null +++ b/rql-ui/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/rql-ui/build/webpack.prod.conf.js b/rql-ui/build/webpack.prod.conf.js new file mode 100644 index 0000000..2f17259 --- /dev/null +++ b/rql-ui/build/webpack.prod.conf.js @@ -0,0 +1,149 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = process.env.NODE_ENV === 'testing' + ? require('../config/test.env') + : require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: process.env.NODE_ENV === 'testing' + ? 'index.html' + : config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code splitted chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/rql-ui/config/dev.env.js b/rql-ui/config/dev.env.js new file mode 100644 index 0000000..a9b12b4 --- /dev/null +++ b/rql-ui/config/dev.env.js @@ -0,0 +1,8 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"', + ROOT_API: '"http://localhost:9992"' +}) diff --git a/rql-ui/config/index.js b/rql-ui/config/index.js new file mode 100644 index 0000000..9649abf --- /dev/null +++ b/rql-ui/config/index.js @@ -0,0 +1,76 @@ +'use strict' +// Template version: 1.2.8 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + // Use Eslint Loader? + // If true, your code will be linted during bundling and + // linting errors and warnings will be shown in the console. + useEslint: true, + // If true, eslint errors and warnings will also be shown in the error overlay + // in the browser. + showEslintErrorsInOverlay: false, + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true, + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/rql', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/rql-ui/config/prod.env.js b/rql-ui/config/prod.env.js new file mode 100644 index 0000000..cbfbc7a --- /dev/null +++ b/rql-ui/config/prod.env.js @@ -0,0 +1,5 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"', + ROOT_API: '"server"' +} diff --git a/rql-ui/default.conf b/rql-ui/default.conf new file mode 100644 index 0000000..37943d6 --- /dev/null +++ b/rql-ui/default.conf @@ -0,0 +1,25 @@ +server { + listen 80 default_server; + listen [::]:80 default_server; + + root /usr/share/nginx/html; + + index index.html; + + server_name localhost; + + location / { + try_files $uri $uri/ @rewrites; + } + + location @rewrites { + rewrite ^(.+)$ /index.html last; + } + + location ~* \.(?:ico|css|js|gif|jpe?g|png)$ { + # Some basic cache-control for static files to be sent to the browser + expires max; + add_header Pragma public; + add_header Cache-Control "public, must-revalidate, proxy-revalidate"; + } +} \ No newline at end of file diff --git a/rql-ui/index.html b/rql-ui/index.html new file mode 100644 index 0000000..8f107ee --- /dev/null +++ b/rql-ui/index.html @@ -0,0 +1,16 @@ + + + + + + + + + RQL Manager + + +
+ + + + diff --git a/rql-ui/package-lock.json b/rql-ui/package-lock.json new file mode 100644 index 0000000..3e006ac --- /dev/null +++ b/rql-ui/package-lock.json @@ -0,0 +1,18342 @@ +{ + "name": "rql-ui", + "version": "1.1.0-SNAPSHOT", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "rql-ui", + "version": "1.1.0-SNAPSHOT", + "dependencies": { + "axios": "^0.18.0", + "bootstrap": "^4.0.0-beta.3", + "bootstrap-vue": "^1.4.1", + "jquery-mobile": "^1.5.0-alpha.1", + "material-design-icons-iconfont": "^3.0.3", + "mockjs": "^1.0.1-beta3", + "moment": "^2.21.0", + "semantic-ui-css": "^2.2.12", + "sortable": "^2.0.0", + "vue": "^2.5.2", + "vue-carousel": "^0.6.5", + "vue-clip": "^1.0.0", + "vue-dual-list": "^1.0.0", + "vue-form-wizard": "^0.8.4", + "vue-good-table": "^1.20.2", + "vue-json-excel": "^0.1.7", + "vue-materialize-datatable": "^0.7.3", + "vue-mover": "^0.3.0", + "vue-multiselect": "^2.0.8", + "vue-resource": "^1.3.5", + "vue-resource-mock": "0.0.8", + "vue-router": "^3.0.1", + "vue-select": "^2.4.0", + "vue-strap": "^1.1.40", + "vue-xlsx-table": "^1.2.8", + "vue-xlsx-table-components": "^1.0.1", + "vue2-autocomplete-js": "^0.2.2", + "vue2-datatable-component": "^2.2.2", + "vuetable-2": "^1.7.2", + "vuetify": "^1.0.11" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-eslint": "^7.1.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-jest": "^21.0.2", + "babel-loader": "^7.1.1", + "babel-plugin-dynamic-import-node": "^1.2.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "babel-register": "^6.22.0", + "chalk": "^2.0.1", + "chromedriver": "^2.27.2", + "copy-webpack-plugin": "^4.0.1", + "cross-spawn": "^5.0.1", + "css-loader": "^0.28.0", + "eslint": "^3.19.0", + "eslint-config-standard": "^10.2.1", + "eslint-friendly-formatter": "^3.0.0", + "eslint-loader": "^1.7.1", + "eslint-plugin-html": "^3.0.0", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-node": "^5.2.0", + "eslint-plugin-promise": "^3.4.0", + "eslint-plugin-standard": "^3.0.1", + "extract-text-webpack-plugin": "^3.0.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^2.30.1", + "jest": "^21.2.0", + "jest-serializer-vue": "^0.3.0", + "jquery": "^1.12.4", + "nightwatch": "^0.9.12", + "node-notifier": "^5.1.2", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "selenium-server": "^3.0.1", + "semver": "^5.3.0", + "shelljs": "^0.7.6", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-jest": "^1.0.2", + "vue-loader": "^13.3.0", + "vue-style-loader": "^3.0.1", + "vue-template-compiler": "^2.5.2", + "webpack": "^3.6.0", + "webpack-bundle-analyzer": "^2.9.0", + "webpack-dev-server": "^2.9.1", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", + "dev": true + }, + "node_modules/@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", + "dev": true + }, + "node_modules/abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", + "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", + "dependencies": { + "mime-types": "~2.1.16", + "negotiator": "0.6.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "deprecated": "This is probably built in to whatever tool you're using. If you still need it... idk", + "dev": true, + "dependencies": { + "acorn": "^4.0.3" + } + }, + "node_modules/acorn-dynamic-import/node_modules/acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "dev": true, + "dependencies": { + "acorn": "^4.0.4" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "dependencies": { + "acorn": "^3.0.4" + } + }, + "node_modules/acorn-jsx/node_modules/acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adler-32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.0.0.tgz", + "integrity": "sha1-KHKKcXVvYpZm3RZTzYB5Op3xhlE=", + "dependencies": { + "concat-stream": "", + "exit-on-epipe": "", + "printj": "" + }, + "bin": { + "adler32": "bin/adler32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/adler-32/node_modules/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-gslSSJx03QKa59cIKqeJO9HQ/WZMotvYJCuaUULrLpjj8oG40kV2Z+gz82pVxlTkOADi4PJxQPPfhl1ELYrrXw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/adler-32/node_modules/exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/agent-base": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "dev": true, + "dependencies": { + "extend": "~3.0.0", + "semver": "~5.0.1" + } + }, + "node_modules/agent-base/node_modules/semver": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", + "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "node_modules/ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true, + "peerDependencies": { + "ajv": ">=4.10.0" + } + }, + "node_modules/align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "dependencies": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "node_modules/append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "dev": true, + "dependencies": { + "default-require-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "dependencies": { + "arr-flatten": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "node_modules/asn1.js": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", + "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "dependencies": { + "util": "0.10.3" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", + "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ast-types": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.10.1.tgz", + "integrity": "sha512-UY7+9DPzlJ9VM8eY0b2TUZcZvF+1pO0hzMtAyjBYKhOmnvRlqYNYnWdtsMj0V16CGaMlpL0G1jnLbLo4AyotuQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "dependencies": { + "lodash": "^4.14.0" + } + }, + "node_modules/async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "node_modules/async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/atob": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz", + "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/autoprefixer": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.4.tgz", + "integrity": "sha512-am8jJ7Rbh1sy7FvLvNxxQScWvhv2FwLAS3bIhvrZpx9HbX5PEcc/7v6ecgpWuiu0Dwlj+p/z/1boHd8x60JFwA==", + "dev": true, + "dependencies": { + "browserslist": "^2.10.2", + "caniuse-lite": "^1.0.30000784", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^6.0.15", + "postcss-value-parser": "^3.2.3" + }, + "bin": { + "autoprefixer-info": "bin/autoprefixer-info" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true + }, + "node_modules/axios": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz", + "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", + "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", + "dependencies": { + "follow-redirects": "^1.3.0", + "is-buffer": "^1.1.5" + } + }, + "node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/babel-core": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.0", + "debug": "^2.6.8", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.7", + "slash": "^1.0.0", + "source-map": "^0.5.6" + } + }, + "node_modules/babel-core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-eslint": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", + "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", + "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.22.0", + "babel-traverse": "^6.23.1", + "babel-types": "^6.23.0", + "babylon": "^6.17.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-generator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", + "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", + "dev": true, + "dependencies": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.6", + "trim-right": "^1.0.1" + } + }, + "node_modules/babel-generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-helper-bindify-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", + "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "dependencies": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-explode-class": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", + "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "dev": true, + "dependencies": { + "babel-helper-bindify-decorators": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "dependencies": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "dependencies": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-vue-jsx-merge-props": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz", + "integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg==", + "dev": true + }, + "node_modules/babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-jest": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-21.2.0.tgz", + "integrity": "sha512-O0W2qLoWu1QOoOGgxiR2JID4O6WSpxPiQanrkyi9SSlM0PJ60Ptzlck47lhtnr9YZO3zYOsxHwnyeWJ6AffoBQ==", + "dev": true, + "dependencies": { + "babel-plugin-istanbul": "^4.0.0", + "babel-preset-jest": "^21.2.0" + }, + "peerDependencies": { + "babel-core": "^6.0.0 || ^7.0.0-alpha || ^7.0.0-beta || ^7.0.0" + } + }, + "node_modules/babel-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz", + "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==", + "dev": true, + "dependencies": { + "find-cache-dir": "^1.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "babel-core": "6 || 7 || ^7.0.0-alpha || ^7.0.0-beta || ^7.0.0-rc", + "webpack": "2 || 3" + } + }, + "node_modules/babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-1.2.0.tgz", + "integrity": "sha512-yeDwKaLgGdTpXL7RgGt5r6T4LmnTza/hUn5Ul8uZSGGMtEjYo13Nxai7SQaGCTEzUtg9Zq9qJn0EjEr7SeSlTQ==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-dynamic-import": "^6.18.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz", + "integrity": "sha1-Z2DN2Xf0EdPhdbsGTyvDJ9mbK24=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0", + "istanbul-lib-instrument": "^1.7.5", + "test-exclude": "^4.1.1" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz", + "integrity": "sha512-yi5QuiVyyvhBUDLP4ButAnhYzkdrUwWDtvUJv71hjH3fclhnZg4HkDeqaitcR2dZZx/E67kGkRcPVjtVu+SJfQ==", + "dev": true + }, + "node_modules/babel-plugin-jsx-event-modifiers": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/babel-plugin-jsx-event-modifiers/-/babel-plugin-jsx-event-modifiers-2.0.5.tgz", + "integrity": "sha512-tWGnCk0whZ+nZcj9tYLw4+y08tPJXqaEjIxRJZS6DkUUae72Kz4BsoGpxt/Kow7mmgQJpvFCw8IPLSNh5rkZCg==", + "dev": true + }, + "node_modules/babel-plugin-jsx-v-model": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jsx-v-model/-/babel-plugin-jsx-v-model-2.0.3.tgz", + "integrity": "sha512-SIx3Y3XxwGEz56Q1atwr5GaZsxJ2IRYmn5dl38LFkaTAvjnbNQxsZHO+ylJPsd+Hmv+ixJBYYFEekPBTHwiGfQ==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-jsx": "^6.18.0", + "html-tags": "^2.0.0", + "svg-tags": "^1.0.0" + } + }, + "node_modules/babel-plugin-jsx-vue-functional": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jsx-vue-functional/-/babel-plugin-jsx-vue-functional-2.1.0.tgz", + "integrity": "sha1-VjCgyG/hkE0owwRl5r8c9xI1ojk=", + "dev": true + }, + "node_modules/babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "node_modules/babel-plugin-syntax-async-generators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", + "dev": true + }, + "node_modules/babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", + "dev": true + }, + "node_modules/babel-plugin-syntax-decorators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", + "dev": true + }, + "node_modules/babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", + "dev": true + }, + "node_modules/babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "node_modules/babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", + "dev": true + }, + "node_modules/babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "node_modules/babel-plugin-transform-async-generator-functions": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "dev": true, + "dependencies": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-generators": "^6.5.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "dependencies": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", + "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "dev": true, + "dependencies": { + "babel-helper-explode-class": "^6.24.1", + "babel-plugin-syntax-decorators": "^6.13.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "dependencies": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "dependencies": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", + "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", + "dev": true, + "dependencies": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "dependencies": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "dependencies": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "dependencies": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "node_modules/babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "dependencies": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, + "dependencies": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "node_modules/babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "dependencies": { + "regenerator-transform": "^0.10.0" + } + }, + "node_modules/babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-vue-jsx": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-3.5.0.tgz", + "integrity": "sha512-5vCg8K7aiiLwrFJ45ZF/b4cIiFpGAoYL5uNZpbgiZFptBc5LkueBCQXTVexrd1IFlpTV7XndqFjtWjcJ54JGUQ==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "peerDependencies": { + "babel-helper-vue-jsx-merge-props": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.8.0" + } + }, + "node_modules/babel-polyfill": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz", + "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=", + "dependencies": { + "babel-runtime": "^6.22.0", + "core-js": "^2.4.0", + "regenerator-runtime": "^0.10.0" + } + }, + "node_modules/babel-polyfill/node_modules/regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + }, + "node_modules/babel-preset-env": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", + "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", + "dev": true, + "dependencies": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^2.1.2", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-21.2.0.tgz", + "integrity": "sha512-hm9cBnr2h3J7yXoTtAVV0zg+3vg0Q/gT2GYuzlreTU0EPkJRtlNgKJJ3tBKEn0+VjAi3JykV6xCJkuUYttEEfA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^21.2.0", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" + } + }, + "node_modules/babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "dev": true, + "dependencies": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" + } + }, + "node_modules/babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "dev": true, + "dependencies": { + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" + } + }, + "node_modules/babel-preset-vue": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/babel-preset-vue/-/babel-preset-vue-1.2.1.tgz", + "integrity": "sha512-a/Z+6SJ4GXyAoCMfYidDH6OzXnccPNJ5nEaPMjALqCkP9SJkqxz9V0uUS//sGuWszcD8kibdwJRzU+brl8DdFQ==", + "dev": true, + "dependencies": { + "babel-helper-vue-jsx-merge-props": "^2.0.2", + "babel-plugin-jsx-event-modifiers": "^2.0.2", + "babel-plugin-jsx-v-model": "^2.0.1", + "babel-plugin-jsx-vue-functional": "^2.1.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-vue-jsx": "^3.5.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-preset-vue-app": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/babel-preset-vue-app/-/babel-preset-vue-app-1.3.2.tgz", + "integrity": "sha512-PLyyyVdrvgL4szMF7D5SuUhy85aBzy0+s5MO2QhpTwVqfW0qVaPFJi6K3d25CKz1nOV437JgpVvPj1W6tLGJ5g==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-object-rest-spread": "^6.26.0", + "babel-plugin-transform-runtime": "^6.15.0", + "babel-preset-env": "^1.6.0", + "babel-preset-vue": "^1.2.1", + "babel-runtime": "^6.20.0" + } + }, + "node_modules/babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "dependencies": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "node_modules/babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true, + "bin": { + "babylon": "bin/babylon.js" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base62": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base62/-/base62-1.2.1.tgz", + "integrity": "sha512-xVtfFHNPUzpCNHygpXFGMlDk3saxXLQcOOQzAAk6ibvlAHgT6WKXLv9rMFhcyEK1n9LuDmp/LxyGW/Fm9L8++g==", + "engines": { + "node": "*" + } + }, + "node_modules/base64-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "dev": true + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "node_modules/bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "dev": true, + "dependencies": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.1", + "http-errors": "~1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "~2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "~1.6.15" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "dependencies": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "node_modules/bonjour/node_modules/array-flatten": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", + "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", + "dev": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "node_modules/boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "dependencies": { + "hoek": "4.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/bootstrap": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.0.0-beta.3.tgz", + "integrity": "sha512-/Qe1Q2d1muLEZRX2iCteMQHZBBAm6ZIjJ9FcBYK/xLr05+HvDtBOVBN+Cz7mCNZuy0zr+y5artZHM05W7mIz6g==", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jquery": "1.9.1 - 3", + "popper.js": "^1.12.9" + } + }, + "node_modules/bootstrap-vue": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-1.4.1.tgz", + "integrity": "sha512-TXQ28trpKPkdJS/SlcvKOS5DTWxUPkyhGf19urUG1r6Cq6YrzNI+kMipzGpj46XFlYu0WUutzOa9KraYyPLDBQ==", + "hasInstallScript": true, + "dependencies": { + "lodash.startcase": "^4.4.0", + "opencollective": "^1.0.3", + "popper.js": "^1.12.9", + "vue-functional-data-merge": "^2.0.3" + }, + "peerDependencies": { + "vue": "^2.4.2" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "dependencies": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "node_modules/browser-resolve": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "dev": true, + "dependencies": { + "resolve": "1.1.7" + } + }, + "node_modules/browser-resolve/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "node_modules/browser-split": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/browser-split/-/browser-split-0.0.0.tgz", + "integrity": "sha1-QUGcrvdpdVkp3VGJZ9PuwKYmJ3E=" + }, + "node_modules/browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "dependencies": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.1.tgz", + "integrity": "sha512-Gp4oJOQOby5TpOJJuUtCrGE0KSJOUYVa/I+/3eD/TRWEK8jqZuJPAK1t+VuG6jp0keudrqtxlH4MbYbmylun9g==", + "deprecated": "Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30000789", + "electron-to-chromium": "^1.3.30" + }, + "bin": { + "browserslist": "cli.js" + } + }, + "node_modules/bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "deprecated": "This version of 'buffer' is out-of-date. You must update to v4.9.2 or newer", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.2.tgz", + "integrity": "sha512-dljb7dk1jqO5ogE+dRpoR9tpHYv5xz9vPSNunh1+0wRuNdYxmzp9WmsyokgW/DUF1FDRVA/TMsmxt027R8djbQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.0", + "chownr": "^1.0.1", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "lru-cache": "^4.1.1", + "mississippi": "^1.3.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.1", + "ssri": "^5.0.0", + "unique-filename": "^1.1.0", + "y18n": "^3.2.1" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cache-base/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "dependencies": { + "callsites": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "node_modules/camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caniuse-api": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", + "dev": true, + "dependencies": { + "browserslist": "^1.3.6", + "caniuse-db": "^1.0.30000529", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-api/node_modules/browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "deprecated": "Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.", + "dev": true, + "dependencies": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + }, + "bin": { + "browserslist": "cli.js" + } + }, + "node_modules/caniuse-db": { + "version": "1.0.30000791", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000791.tgz", + "integrity": "sha1-Bnh/VsrvQwChfjXRN0RxI731Nvk=", + "dev": true + }, + "node_modules/caniuse-lite": { + "version": "1.0.30000791", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000791.tgz", + "integrity": "sha1-jjV0Xv1IOj4ju301CZAybSMZ/BY=", + "dev": true + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "dependencies": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cfb": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-0.11.1.tgz", + "integrity": "sha1-qW248nKmw/uZ27sj70EiP0i+Hqc=", + "dependencies": { + "commander": "" + }, + "bin": { + "cfb": "bin/cfb.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/cfb/node_modules/commander": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.0.tgz", + "integrity": "sha512-7B1ilBwtYSbetCgTY1NJFg+gVpestg0fdA1MhC1Vs4ssyfSXnCAjFr+QcQM9/RedXC0EaUx1sG8Smgw2VfgKEg==" + }, + "node_modules/chai-nightwatch": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/chai-nightwatch/-/chai-nightwatch-0.1.1.tgz", + "integrity": "sha1-HKVt52jTwIaP5/wvTTLC/olOa+k=", + "dev": true, + "dependencies": { + "assertion-error": "1.0.0", + "deep-eql": "0.1.3" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.1.0", + "escape-string-regexp": "^1.0.5", + "supports-color": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "dependencies": { + "has-flag": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" + }, + "node_modules/chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dev": true, + "dependencies": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + }, + "optionalDependencies": { + "fsevents": "^1.0.0" + } + }, + "node_modules/chownr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "dev": true + }, + "node_modules/chromedriver": { + "version": "2.34.1", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.34.1.tgz", + "integrity": "sha512-ivXrPKKtnX442J8Lkbhb8hJ5+lelzAqrAI9VjVs3/iujm396JnJYXGGGjniPXvQeLVE3HDIWwsHu8goIUq3rMQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "del": "^3.0.0", + "extract-zip": "^1.6.5", + "kew": "^0.7.0", + "mkdirp": "^0.5.1", + "request": "^2.83.0" + }, + "bin": { + "chromedriver": "bin/chromedriver" + } + }, + "node_modules/ci-info": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz", + "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==", + "dev": true + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", + "dev": true + }, + "node_modules/clap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", + "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clap/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clap/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clap/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/class-list": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/class-list/-/class-list-0.1.1.tgz", + "integrity": "sha1-m5dFGSxBebXaCg12M2WOPHDXlss=", + "dependencies": { + "indexof": "0.0.1" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "deprecated": "Please upgrade to v0.1.7", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "deprecated": "Please upgrade to v0.1.5", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-css": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz", + "integrity": "sha1-Nc7ornaHpJuYA09w3gDE7dOCYwE=", + "dev": true, + "dependencies": { + "source-map": "0.5.x" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "dependencies": { + "restore-cursor": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-spinners": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.1.0.tgz", + "integrity": "sha1-8YR7FohE2RemceudFH499JfJDQY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "node_modules/cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "dependencies": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "node_modules/cliui/node_modules/wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/clone": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/coa": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", + "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", + "dev": true, + "dependencies": { + "q": "^1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/coalescy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/coalescy/-/coalescy-1.0.0.tgz", + "integrity": "sha1-SwZYRrg2NhrabEtKSr9LwcrDG/E=", + "dev": true + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/codepage": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.8.1.tgz", + "integrity": "sha1-8aAJ1SYdwnVGKLrLb7vw5uKr/6o=", + "dependencies": { + "commander": "", + "concat-stream": "", + "exit-on-epipe": "", + "voc": "" + }, + "bin": { + "codepage": "bin/codepage.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/codepage/node_modules/commander": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.0.tgz", + "integrity": "sha512-7B1ilBwtYSbetCgTY1NJFg+gVpestg0fdA1MhC1Vs4ssyfSXnCAjFr+QcQM9/RedXC0EaUx1sG8Smgw2VfgKEg==" + }, + "node_modules/codepage/node_modules/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-gslSSJx03QKa59cIKqeJO9HQ/WZMotvYJCuaUULrLpjj8oG40kV2Z+gz82pVxlTkOADi4PJxQPPfhl1ELYrrXw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/codepage/node_modules/exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "dev": true, + "dependencies": { + "clone": "^1.0.2", + "color-convert": "^1.3.0", + "color-string": "^0.3.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, + "dependencies": { + "color-name": "^1.1.1" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/color-string": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "dev": true, + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/colormin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", + "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "dev": true, + "dependencies": { + "color": "^0.11.0", + "css-color-names": "0.0.4", + "has": "^1.0.1" + } + }, + "node_modules/colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/commoner": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", + "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=", + "dependencies": { + "commander": "^2.5.0", + "detective": "^4.3.1", + "glob": "^5.0.15", + "graceful-fs": "^4.1.2", + "iconv-lite": "^0.4.5", + "mkdirp": "^0.5.0", + "private": "^0.1.6", + "q": "^1.1.2", + "recast": "^0.11.17" + }, + "bin": { + "commonize": "bin/commonize" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commoner/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.12.tgz", + "integrity": "sha1-xZpcmdt2dn6YdlAOJx72OzSTvWY=", + "dev": true, + "dependencies": { + "mime-db": ">= 1.30.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.1.tgz", + "integrity": "sha1-7/JgPvwuIs+G810uuTWJ+YdTc9s=", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "bytes": "3.0.0", + "compressible": "~2.0.11", + "debug": "2.6.9", + "on-headers": "~1.0.1", + "safe-buffer": "5.1.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/condense-newlines": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz", + "integrity": "sha1-PemFVTE5R10yUCyDsC9gaE0kxV8=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-whitespace": "^0.3.0", + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/config-chain": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz", + "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=", + "dev": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "dependencies": { + "date-now": "^0.1.4" + } + }, + "node_modules/consolidate": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.14.5.tgz", + "integrity": "sha1-WiUEe8dvcwcmZ8jLUsmJiI9JTGM=", + "deprecated": "Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog", + "dev": true, + "dependencies": { + "bluebird": "^3.1.1" + } + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", + "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==", + "deprecated": "Use whatwg-mimetype instead", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "node_modules/cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.3.1.tgz", + "integrity": "sha512-xlcFiW/U7KrpS6dFuWq3r8Wb7koJx7QVc7LDFCosqkikaVSxkaYOnwDLwilbjrszZ0LYZXThDAJKcQCSrvdShQ==", + "dev": true, + "dependencies": { + "cacache": "^10.0.1", + "find-cache-dir": "^1.0.0", + "globby": "^7.1.1", + "is-glob": "^4.0.0", + "loader-utils": "^0.2.15", + "lodash": "^4.3.0", + "minimatch": "^3.0.4", + "p-limit": "^1.0.0", + "pify": "^3.0.0", + "serialize-javascript": "^1.4.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "dependencies": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + }, + "node_modules/copy-webpack-plugin/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/core-js": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", + "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js." + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "node_modules/cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "dev": true, + "dependencies": { + "is-directory": "^0.3.1", + "js-yaml": "^3.4.3", + "minimist": "^1.2.0", + "object-assign": "^4.1.0", + "os-homedir": "^1.0.1", + "parse-json": "^2.2.0", + "require-from-string": "^1.1.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/cosmiconfig/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node_modules/crc-32": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.0.2.tgz", + "integrity": "sha1-CVB5hO6bzOO9G4hh8N6KsQroGH0=", + "dependencies": { + "exit-on-epipe": "", + "printj": "" + }, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc-32/node_modules/exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "node_modules/create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "dependencies": { + "boom": "5.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/cryptiles/node_modules/boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "dependencies": { + "hoek": "4.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/css-loader": { + "version": "0.28.8", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.8.tgz", + "integrity": "sha512-4jGj7Ag6WUZ5lQyE4te9sJLn0lgkz6HI3WDE4aw98AkW1IAKXPP4blTpPeorlLDpNsYvojo0SYgRJOdz2KbuAw==", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.26.0", + "css-selector-tokenizer": "^0.7.0", + "cssnano": "^3.10.0", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash.camelcase": "^4.3.0", + "object-assign": "^4.1.1", + "postcss": "^5.0.6", + "postcss-modules-extract-imports": "^1.1.0", + "postcss-modules-local-by-default": "^1.2.0", + "postcss-modules-scope": "^1.1.0", + "postcss-modules-values": "^1.3.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" + }, + "engines": { + "node": ">=0.12.0 || >= 4.3.0 < 5.0.0 || >=5.10" + } + }, + "node_modules/css-loader/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-loader/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-loader/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/css-loader/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-loader/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/css-loader/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-loader/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/css-select/node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/css-selector-tokenizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", + "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "dev": true, + "dependencies": { + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" + } + }, + "node_modules/css-selector-tokenizer/node_modules/regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, + "dependencies": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "node_modules/css-what": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", + "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + } + }, + "node_modules/cssnano": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "dev": true, + "dependencies": { + "autoprefixer": "^6.3.1", + "decamelize": "^1.1.2", + "defined": "^1.0.0", + "has": "^1.0.1", + "object-assign": "^4.0.1", + "postcss": "^5.0.14", + "postcss-calc": "^5.2.0", + "postcss-colormin": "^2.1.8", + "postcss-convert-values": "^2.3.4", + "postcss-discard-comments": "^2.0.4", + "postcss-discard-duplicates": "^2.0.1", + "postcss-discard-empty": "^2.0.1", + "postcss-discard-overridden": "^0.1.1", + "postcss-discard-unused": "^2.2.1", + "postcss-filter-plugins": "^2.0.0", + "postcss-merge-idents": "^2.1.5", + "postcss-merge-longhand": "^2.0.1", + "postcss-merge-rules": "^2.0.3", + "postcss-minify-font-values": "^1.0.2", + "postcss-minify-gradients": "^1.0.1", + "postcss-minify-params": "^1.0.4", + "postcss-minify-selectors": "^2.0.4", + "postcss-normalize-charset": "^1.1.0", + "postcss-normalize-url": "^3.0.7", + "postcss-ordered-values": "^2.1.0", + "postcss-reduce-idents": "^2.2.2", + "postcss-reduce-initial": "^1.0.0", + "postcss-reduce-transforms": "^1.0.3", + "postcss-svgo": "^2.1.1", + "postcss-unique-selectors": "^2.0.2", + "postcss-value-parser": "^3.2.3", + "postcss-zindex": "^2.0.1" + } + }, + "node_modules/cssnano/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssnano/node_modules/autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "dev": true, + "dependencies": { + "browserslist": "^1.7.6", + "caniuse-db": "^1.0.30000634", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^5.2.16", + "postcss-value-parser": "^3.2.3" + } + }, + "node_modules/cssnano/node_modules/browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "deprecated": "Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.", + "dev": true, + "dependencies": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + }, + "bin": { + "browserslist": "cli.js" + } + }, + "node_modules/cssnano/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssnano/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cssnano/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssnano/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/cssnano/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssnano/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "dev": true, + "dependencies": { + "clap": "^1.0.9", + "source-map": "^0.5.3" + }, + "bin": { + "csso": "bin/csso" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/csso/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", + "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", + "dev": true + }, + "node_modules/cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "dev": true, + "dependencies": { + "cssom": "0.3.x" + } + }, + "node_modules/cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=", + "dev": true + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "dev": true + }, + "node_modules/d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.9" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", + "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", + "dev": true + }, + "node_modules/date-fns": { + "version": "2.0.0-alpha.7", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.0.0-alpha.7.tgz", + "integrity": "sha1-JFrRb5V2Tqur+ywKQf1dAzwg5Xo=" + }, + "node_modules/date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", + "dev": true + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "dependencies": { + "type-detect": "0.1.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "node_modules/default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "dev": true, + "dependencies": { + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "dependencies": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, + "node_modules/degenerator": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", + "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", + "dev": true, + "dependencies": { + "ast-types": "0.x.x", + "escodegen": "1.x.x", + "esprima": "3.x.x" + } + }, + "node_modules/degenerator/node_modules/esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "dev": true, + "dependencies": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/del/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-node": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz", + "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=", + "dev": true + }, + "node_modules/detective": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", + "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", + "dependencies": { + "acorn": "^5.2.1", + "defined": "^1.0.0" + } + }, + "node_modules/diacriticless": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/diacriticless/-/diacriticless-1.0.1.tgz", + "integrity": "sha1-592peMKRlgm7SK7h78XeajN71MM=" + }, + "node_modules/diff": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", + "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dir-glob/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "node_modules/dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "dependencies": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/dns-packet/node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "node_modules/dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "dependencies": { + "buffer-indexof": "^1.0.0" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-converter": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz", + "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=", + "dev": true, + "dependencies": { + "utila": "~0.3" + } + }, + "node_modules/dom-converter/node_modules/utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", + "dev": true + }, + "node_modules/dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "dependencies": { + "domelementtype": "~1.1.1", + "entities": "~1.1.1" + } + }, + "node_modules/dom-serializer/node_modules/domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + }, + "node_modules/domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "deprecated": "update to domelementtype@1.3.1", + "dev": true + }, + "node_modules/domhandler": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", + "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.6.2.tgz", + "integrity": "sha1-GVjMC0yUJuntNn+xyOhUiRsPo/8=", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/downloadjs": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz", + "integrity": "sha1-9p+W+UDg0FU9rCkROYZaPNAQHjw=" + }, + "node_modules/dropzone": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/dropzone/-/dropzone-4.3.0.tgz", + "integrity": "sha1-SLC48q0JKHLktTW2cqfD8aHWfJE=" + }, + "node_modules/duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "node_modules/duplexify": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.3.tgz", + "integrity": "sha512-g8ID9OroF9hKt2POf8YLayy+9594PzmM3scI00/uBXocX3TWNgoB67hjzkFe9ITAbQOne/lLdBxHXvYUM4ZgGA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true, + "dependencies": { + "jsbn": "~0.1.0" + } + }, + "node_modules/editorconfig": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.13.3.tgz", + "integrity": "sha512-WkjsUNVCu+ITKDj73QDvi0trvpdDWdkDyHybDGSXPfekLCqwmpD7CP7iPbvBgosNuLcI96XTDwNa75JyFl7tEQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.0.5", + "commander": "^2.9.0", + "lru-cache": "^3.2.0", + "semver": "^5.1.0", + "sigmund": "^1.0.1" + }, + "bin": { + "editorconfig": "bin/editorconfig" + } + }, + "node_modules/editorconfig/node_modules/lru-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", + "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/ejs": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz", + "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-releases": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/electron-releases/-/electron-releases-2.1.0.tgz", + "integrity": "sha512-cyKFD1bTE/UgULXfaueIN1k5EPFzs+FRc/rvCY5tIynefAPqopQEgjr0EzY+U3Dqrk/G4m9tXSPuZ77v6dL/Rw==", + "deprecated": "this package is no longer updated, please fetch version information from https://releases.electronjs.org/releases.json instead", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.3.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz", + "integrity": "sha512-zx1Prv7kYLfc4OA60FhxGbSo4qrEjgSzpo1/37i7l9ltXPYOoQBtjQxY9KmsgfHnBxHlBGXwLlsbt/gub1w5lw==", + "dev": true, + "dependencies": { + "electron-releases": "^2.1.0" + } + }, + "node_modules/elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true, + "dependencies": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "dependencies": { + "iconv-lite": "~0.4.13" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "object-assign": "^4.0.1", + "tapable": "^0.2.7" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + }, + "node_modules/envify": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/envify/-/envify-3.4.1.tgz", + "integrity": "sha1-1xIjKejfFoi6dxsSUBkXyc5cvOg=", + "dependencies": { + "jstransform": "^11.0.3", + "through": "~2.3.4" + }, + "bin": { + "envify": "bin/envify" + } + }, + "node_modules/errno": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz", + "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.1.tgz", + "integrity": "sha1-oyArj7AxFKqbQKDjZp5IsrZaAQo=", + "dev": true, + "dependencies": { + "stackframe": "^1.0.3" + } + }, + "node_modules/es-abstract": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "dependencies": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es5-ext": { + "version": "0.10.37", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", + "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", + "dev": true, + "dependencies": { + "es6-iterator": "~2.0.1", + "es6-symbol": "~3.1.1" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "node_modules/es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", + "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", + "dev": true, + "dependencies": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.12.0" + }, + "optionalDependencies": { + "source-map": "~0.5.6" + } + }, + "node_modules/escodegen/node_modules/esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "dependencies": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-config-standard": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", + "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", + "dev": true, + "peerDependencies": { + "eslint": ">=3.19.0", + "eslint-plugin-import": ">=2.2.0", + "eslint-plugin-node": ">=4.2.2", + "eslint-plugin-promise": ">=3.5.0", + "eslint-plugin-standard": ">=3.0.0" + } + }, + "node_modules/eslint-friendly-formatter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-friendly-formatter/-/eslint-friendly-formatter-3.0.0.tgz", + "integrity": "sha1-J4h0Q1psRuwdlPoLH/SU4w7wQpA=", + "dev": true, + "dependencies": { + "chalk": "^1.0.0", + "coalescy": "1.0.0", + "extend": "^3.0.0", + "minimist": "^1.2.0", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-friendly-formatter/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-friendly-formatter/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-friendly-formatter/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node_modules/eslint-friendly-formatter/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "node_modules/eslint-loader": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-1.9.0.tgz", + "integrity": "sha512-40aN976qSNPyb9ejTqjEthZITpls1SVKtwguahmH1dzGCwQU/vySE+xX33VZmD8csU0ahVNCtFlsPgKqRBiqgg==", + "deprecated": "This loader has been deprecated. Please use eslint-webpack-plugin", + "dev": true, + "dependencies": { + "loader-fs-cache": "^1.0.0", + "loader-utils": "^1.0.2", + "object-assign": "^4.0.1", + "object-hash": "^1.1.4", + "rimraf": "^2.6.1" + }, + "peerDependencies": { + "eslint": ">=1.6.0 <5.0.0" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", + "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", + "dev": true, + "dependencies": { + "debug": "^2.6.8", + "pkg-dir": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-module-utils/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-module-utils/node_modules/pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-html": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-3.2.2.tgz", + "integrity": "sha512-sSuafathF6ImPrzF2vUKEJY6Llq06d/riMTMzlsruDRDhNsQMYp2viUKo+jx+JRr1QevskeUpQcuptp2gN1XVQ==", + "dev": true, + "dependencies": { + "htmlparser2": "^3.8.2", + "semver": "^5.4.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", + "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", + "dev": true, + "dependencies": { + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.6.8", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.1.1", + "has": "^1.0.1", + "lodash.cond": "^4.3.0", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "2.x - 4.x" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-node": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz", + "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==", + "dev": true, + "dependencies": { + "ignore": "^3.3.6", + "minimatch": "^3.0.4", + "resolve": "^1.3.3", + "semver": "5.3.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": ">=3.1.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.6.0.tgz", + "integrity": "sha512-YQzM6TLTlApAr7Li8vWKR+K3WghjwKcYzY0d2roWap4SLK+kzuagJX/leTetIDWsFcTFnKNJXWupDCD6aZkP2Q==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-standard": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", + "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", + "dev": true, + "peerDependencies": { + "eslint": ">=3.19.0" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/espree": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "dev": true, + "dependencies": { + "acorn": "^5.2.1", + "acorn-jsx": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "dependencies": { + "estraverse": "^4.0.0" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "dependencies": { + "estraverse": "^4.1.0", + "object-assign": "^4.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/eventemitter3": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", + "dev": true + }, + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/eventsource": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", + "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", + "dev": true, + "dependencies": { + "original": ">=0.0.5" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/exec-sh": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz", + "integrity": "sha512-aLt95pexaugVtQerpmE51+4QfWrNc304uez7jvj6fWnN8GeEHpttB8F36n8N7uVhUMbH/1enbxQ9HImZ4w/9qg==", + "dev": true, + "dependencies": { + "merge": "^1.1.3" + } + }, + "node_modules/execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "dependencies": { + "is-posix-bracket": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "dependencies": { + "fill-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-21.2.1.tgz", + "integrity": "sha512-orfQQqFRTX0jH7znRIGi8ZMR8kTNpXklTTz8+HGTpmTKZo3Occ6JNB5FXMb8cRuiiC/GyDqsr30zUa66ACYlYw==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "jest-diff": "^21.2.1", + "jest-get-type": "^21.2.0", + "jest-matcher-utils": "^21.2.1", + "jest-message-util": "^21.2.1", + "jest-regex-util": "^21.2.0" + } + }, + "node_modules/express": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", + "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.1", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.0", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.2", + "qs": "6.5.1", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.1", + "serve-static": "1.13.1", + "setprototypeof": "1.1.0", + "statuses": "~1.3.1", + "type-is": "~1.6.15", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/express/node_modules/statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", + "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "dependencies": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extract-text-webpack-plugin": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz", + "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", + "deprecated": "Deprecated. Please use https://github.com/webpack-contrib/mini-css-extract-plugin", + "dev": true, + "dependencies": { + "async": "^2.4.1", + "loader-utils": "^1.1.0", + "schema-utils": "^0.3.0", + "webpack-sources": "^1.0.1" + }, + "engines": { + "node": ">= 4.8 < 5.0.0 || >= 5.10" + }, + "peerDependencies": { + "webpack": "^3.1.0" + } + }, + "node_modules/extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "dependencies": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "bin": { + "extract-zip": "cli.js" + } + }, + "node_modules/extract-zip/node_modules/mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastparse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", + "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", + "dev": true + }, + "node_modules/faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "dev": true, + "dependencies": { + "bser": "^2.0.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "dependencies": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/file-loader": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.6.tgz", + "integrity": "sha512-873ztuL+/hfvXbLDJ262PGO6XjERnybJu2gW1/5j8HUfxSiFJI9Hj/DhZ50ZGRUxBvuNiazb/cM2rh9pqrxP6Q==", + "dev": true, + "dependencies": { + "loader-utils": "^1.0.2", + "schema-utils": "^0.3.0" + }, + "engines": { + "node": ">= 4.3 < 5.0.0 || >= 5.10" + }, + "peerDependencies": { + "webpack": "^2.0.0 || ^3.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true + }, + "node_modules/filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "dependencies": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "node_modules/filesize": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.5.11.tgz", + "integrity": "sha512-ZH7loueKBoDb7yG9esn1U+fgq7BzlzW6NRi5/rMdxIZ05dj7GFD/Xc5rq2CDt5Yq86CyfSYVyx4242QQNZbx1g==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "dependencies": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^1.1.3", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/find-babel-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.1.0.tgz", + "integrity": "sha1-rMAQQ6Z0n+w0Qpvmtk9ULrtdY1U=", + "dev": true, + "dependencies": { + "json5": "^0.5.1", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-cache-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", + "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "dependencies": { + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flat-cache/node_modules/del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "dependencies": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flat-cache/node_modules/globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", + "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash.", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/flush-write-stream": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.2.tgz", + "integrity": "sha1-yBuQ2HRnZvGmCaRoCZRsRd2K5Bc=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + } + }, + "node_modules/follow-redirects": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz", + "integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==", + "dependencies": { + "debug": "^3.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/follow-redirects/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/frac": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.0.6.tgz", + "integrity": "sha1-mg38I5VoUqizIGI7688b6eoEgik=", + "dependencies": { + "voc": "" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/friendly-errors-webpack-plugin": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.6.1.tgz", + "integrity": "sha1-4yeBxHIvVGoGqbXXp8+ihSA3XXA=", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "error-stack-parser": "^2.0.0", + "string-length": "^1.0.1" + } + }, + "node_modules/friendly-errors-webpack-plugin/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/friendly-errors-webpack-plugin/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/friendly-errors-webpack-plugin/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "bundleDependencies": [ + "node-pre-gyp" + ], + "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fsevents/node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/aproba": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/are-we-there-yet": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/fsevents/node_modules/balanced-match": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/fsevents/node_modules/chownr": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/code-point-at": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/fsevents/node_modules/deep-extend": { + "version": "0.5.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/detect-libc": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/fsevents/node_modules/fs-minipass": { + "version": "1.2.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "minipass": "^2.2.1" + } + }, + "node_modules/fsevents/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/gauge": { + "version": "2.7.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/fsevents/node_modules/glob": { + "version": "7.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fsevents/node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/iconv-lite": { + "version": "0.4.21", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/ignore-walk": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/fsevents/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/fsevents/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/ini": { + "version": "1.3.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/fsevents/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fsevents/node_modules/minimist": { + "version": "0.0.8", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/minipass": { + "version": "2.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "node_modules/fsevents/node_modules/minizlib": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minipass": "^2.2.1" + } + }, + "node_modules/fsevents/node_modules/mkdirp": { + "version": "0.5.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/fsevents/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/needle": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 0.10.x" + } + }, + "node_modules/fsevents/node_modules/node-pre-gyp": { + "version": "0.10.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/fsevents/node_modules/nopt": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/fsevents/node_modules/npm-bundled": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/npm-packlist": { + "version": "1.1.10", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "node_modules/fsevents/node_modules/npmlog": { + "version": "4.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/fsevents/node_modules/number-is-nan": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/fsevents/node_modules/os-homedir": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/os-tmpdir": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/osenv": { + "version": "0.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/fsevents/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/process-nextick-args": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/rc": { + "version": "1.2.7", + "dev": true, + "inBundle": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/fsevents/node_modules/rc/node_modules/minimist": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/readable-stream": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/fsevents/node_modules/rimraf": { + "version": "2.6.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "glob": "^7.0.5" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/fsevents/node_modules/safe-buffer": { + "version": "5.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/sax": { + "version": "1.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/semver": { + "version": "5.5.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/fsevents/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/signal-exit": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/fsevents/node_modules/string-width": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/strip-json-comments": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/tar": { + "version": "4.4.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/fsevents/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents/node_modules/wide-align": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^1.0.2" + } + }, + "node_modules/fsevents/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/fsevents/node_modules/yallist": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "dev": true, + "dependencies": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ftp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/ftp/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ftp/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/fuse.js": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-2.7.4.tgz", + "integrity": "sha1-luQg/efvARrEnCWKYhMU/ldlNvk=" + }, + "node_modules/generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "node_modules/generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "dependencies": { + "is-property": "^1.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "engines": { + "node": ">=4" + } + }, + "node_modules/get-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.1.tgz", + "integrity": "sha512-7aelVrYqCLuVjq2kEKRTH8fXPTC0xKTkM+G7UlFkEwCXY3sFbSxvY375JoFowOAYbkaU47SrBvOefUlLZZ+6QA==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "1", + "debug": "2", + "extend": "3", + "file-uri-to-path": "1", + "ftp": "~0.3.10", + "readable-stream": "2" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "dependencies": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "dependencies": { + "is-glob": "^2.0.0" + } + }, + "node_modules/globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "dependencies": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "node_modules/growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "node_modules/growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true + }, + "node_modules/gzip-size": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", + "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=", + "dev": true, + "dependencies": { + "duplexer": "^0.1.1" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/handle-thing": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", + "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "dev": true, + "dependencies": { + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^2.6" + } + }, + "node_modules/handlebars/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/handlebars/node_modules/uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "optional": true, + "dependencies": { + "source-map": "~0.5.1", + "yargs": "~3.10.0" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + }, + "optionalDependencies": { + "uglify-to-browserify": "~1.0.0" + } + }, + "node_modules/handlebars/node_modules/uglify-js/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/handlebars/node_modules/yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "optional": true, + "dependencies": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "dependencies": { + "function-bind": "^1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-symbol-support-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz", + "integrity": "sha512-JkaetveU7hFbqnAC1EV1sF4rlojU2D4Usc5CmS69l6NfmPDnpnFUegzFg33eDkkpNCxZ0mQp65HwUDrNFS/8MA==", + "engines": { + "node": "*" + } + }, + "node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-value/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + }, + "node_modules/hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "deprecated": "This module moved to @hapi/hawk. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.", + "dev": true, + "dependencies": { + "boom": "4.x.x", + "cryptiles": "3.x.x", + "hoek": "4.x.x", + "sntp": "2.x.x" + }, + "engines": { + "node": ">=4.5.0" + } + }, + "node_modules/he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hoek": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/html-comment-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", + "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=", + "dev": true + }, + "node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.1" + } + }, + "node_modules/html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "dev": true, + "engines": [ + "node >= 0.4.0" + ] + }, + "node_modules/html-minifier": { + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.8.tgz", + "integrity": "sha512-WX7D6PB9PFq05fZ1/CyxPUuyqXed6vh2fGOM80+zJT5wAO93D/cUjLs0CcbBFjQmlwmCgRvl97RurtArIpOnkw==", + "dev": true, + "dependencies": { + "camel-case": "3.0.x", + "clean-css": "4.1.x", + "commander": "2.12.x", + "he": "1.1.x", + "ncname": "1.0.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.3.x" + }, + "bin": { + "html-minifier": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/html-webpack-plugin": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz", + "integrity": "sha1-f5xCG36pHsRg9WUn1430hO51N9U=", + "deprecated": "out of support", + "dev": true, + "dependencies": { + "bluebird": "^3.4.7", + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "toposort": "^1.0.0" + }, + "peerDependencies": { + "webpack": "1 || ^2 || ^2.1.0-beta || ^2.2.0-rc || ^3" + } + }, + "node_modules/html-webpack-plugin/node_modules/loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "dependencies": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + }, + "node_modules/htmlparser2": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", + "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.0", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "node_modules/http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dependencies": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": ">= 1.3.1 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-parser-js": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz", + "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz", + "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=", + "dev": true, + "dependencies": { + "eventemitter3": "1.x.x", + "requires-port": "1.x.x" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-1.0.0.tgz", + "integrity": "sha1-zBzjjkU7+YSg93AtLdWcc9CBKEo=", + "dev": true, + "dependencies": { + "agent-base": "2", + "debug": "2", + "extend": "3" + } + }, + "node_modules/http-proxy-middleware": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz", + "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=", + "dev": true, + "dependencies": { + "http-proxy": "^1.16.2", + "is-glob": "^3.1.0", + "lodash": "^4.17.2", + "micromatch": "^2.3.11" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", + "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", + "dev": true, + "dependencies": { + "agent-base": "2", + "debug": "2", + "extend": "3" + } + }, + "node_modules/hyperscript": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/hyperscript/-/hyperscript-1.0.7.tgz", + "integrity": "sha1-2I7TxRk0xtb6NbKr/XwA8QCCD2U=", + "dependencies": { + "browser-split": "0.0.0", + "class-list": "~0.1.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "node_modules/icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "dev": true, + "dependencies": { + "postcss": "^6.0.1" + } + }, + "node_modules/ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, + "node_modules/iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "node_modules/ignore": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "dev": true + }, + "node_modules/import-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", + "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", + "dev": true, + "dependencies": { + "pkg-dir": "^2.0.0", + "resolve-cwd": "^2.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "node_modules/indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "deprecated": "Please update to ini >=1.3.6 to avoid a prototype pollution issue", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "dependencies": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/internal-ip": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz", + "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=", + "dev": true, + "dependencies": { + "meow": "^3.3.0" + }, + "bin": { + "internal-ip": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "node_modules/invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ip": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.0.1.tgz", + "integrity": "sha1-x+NWzeoiWucbNtcPLnGpK6TkJZA=", + "dev": true + }, + "node_modules/ipaddr.js": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", + "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "deprecated": "Please upgrade to v1.0.1", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "dependencies": { + "builtin-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-ci": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", + "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", + "dev": true, + "dependencies": { + "ci-info": "^1.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "deprecated": "Please upgrade to v1.0.1", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "dependencies": { + "is-primitive": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-my-json-valid": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz", + "integrity": "sha512-Q2khNw+oBlWuaYvEEHtKSw/pCxD2L5Rc1C+UQme9X6JdRDh7m5D7HkozA0qa3DUkQ6VzCnEm8mVIQPyIRkI5sQ==", + "deprecated": "catastrophic backtracking in regexes could potentially lead to REDOS attack, upgrade to 2.17.2 as soon as possible", + "dev": true, + "dependencies": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" + }, + "node_modules/is-odd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-1.0.0.tgz", + "integrity": "sha1-O4qTLrAos3dcObsJ6RdnrM22kIg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-odd/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "dependencies": { + "is-path-inside": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "dependencies": { + "path-is-inside": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "dependencies": { + "has": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", + "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", + "dev": true + }, + "node_modules/is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "dev": true, + "dependencies": { + "html-comment-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "node_modules/is-whitespace": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz", + "integrity": "sha1-Fjnssb4DauxppUy7QBz77XEUq38=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/istanbul-api": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.2.1.tgz", + "integrity": "sha512-oFCwXvd65amgaPCzqrR+a2XjanS1MvpXN6l/MlMUTv6uiA1NOgGX+I0uyq8Lg3GDxsxPsaP1049krz3hIJ5+KA==", + "dev": true, + "dependencies": { + "async": "^2.1.4", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.1.1", + "istanbul-lib-hook": "^1.1.0", + "istanbul-lib-instrument": "^1.9.1", + "istanbul-lib-report": "^1.1.2", + "istanbul-lib-source-maps": "^1.2.2", + "istanbul-reports": "^1.1.3", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", + "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==", + "dev": true + }, + "node_modules/istanbul-lib-hook": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz", + "integrity": "sha512-U3qEgwVDUerZ0bt8cfl3dSP3S6opBoOtk3ROO5f2EfBr/SRiD9FQqzwaZBqFORu8W7O0EXpai+k7kxHK13beRg==", + "dev": true, + "dependencies": { + "append-transform": "^0.4.0" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz", + "integrity": "sha512-RQmXeQ7sphar7k7O1wTNzVczF9igKpaeGQAG9qR2L+BS4DCJNTI9nytRmIVYevwO0bbq+2CXvJmYDuz0gMrywA==", + "dev": true, + "dependencies": { + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.1.1", + "semver": "^5.3.0" + } + }, + "node_modules/istanbul-lib-report": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz", + "integrity": "sha512-UTv4VGx+HZivJQwAo1wnRwe1KTvFpfi/NYwN7DcsrdzMXwpRT/Yb6r4SBPoHWj4VuQPakR32g4PUUeyKkdDkBA==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^1.1.1", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz", + "integrity": "sha512-8BfdqSfEdtip7/wo1RnrvLpHVEd8zMZEDmOFEnpC6dg0vXflHt9nvoAyQUzig2uMSXfF2OBEYBV3CVjIL9JvaQ==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.1.1", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.3.tgz", + "integrity": "sha512-ZEelkHh8hrZNI5xDaKwPMFwDsUf5wIEI2bXAFGp1e6deR2mnEKBPhLJEgr4ZBt8Gi6Mj38E/C8kcy9XLggVO2Q==", + "dev": true, + "dependencies": { + "handlebars": "^4.0.3" + } + }, + "node_modules/isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/jest": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-21.2.1.tgz", + "integrity": "sha512-mXN0ppPvWYoIcC+R+ctKxAJ28xkt/Z5Js875padm4GbgUn6baeR5N4Ng6LjatIRpUQDZVJABT7Y4gucFjPryfw==", + "dev": true, + "dependencies": { + "jest-cli": "^21.2.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/jest-changed-files": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-21.2.0.tgz", + "integrity": "sha512-+lCNP1IZLwN1NOIvBcV5zEL6GENK6TXrDj4UxWIeLvIsIDa+gf6J7hkqsW2qVVt/wvH65rVvcPwqXdps5eclTQ==", + "dev": true, + "dependencies": { + "throat": "^4.0.0" + } + }, + "node_modules/jest-config": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-21.2.1.tgz", + "integrity": "sha512-fJru5HtlD/5l2o25eY9xT0doK3t2dlglrqoGpbktduyoI0T5CwuB++2YfoNZCrgZipTwPuAGonYv0q7+8yDc/A==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^21.2.1", + "jest-environment-node": "^21.2.1", + "jest-get-type": "^21.2.0", + "jest-jasmine2": "^21.2.1", + "jest-regex-util": "^21.2.0", + "jest-resolve": "^21.2.0", + "jest-util": "^21.2.1", + "jest-validate": "^21.2.1", + "pretty-format": "^21.2.1" + } + }, + "node_modules/jest-diff": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-21.2.1.tgz", + "integrity": "sha512-E5fu6r7PvvPr5qAWE1RaUwIh/k6Zx/3OOkZ4rk5dBJkEWRrUuSgbMt2EO8IUTPTd6DOqU3LW6uTIwX5FRvXoFA==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1", + "diff": "^3.2.0", + "jest-get-type": "^21.2.0", + "pretty-format": "^21.2.1" + } + }, + "node_modules/jest-docblock": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", + "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", + "dev": true + }, + "node_modules/jest-environment-jsdom": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-21.2.1.tgz", + "integrity": "sha512-mecaeNh0eWmzNrUNMWARysc0E9R96UPBamNiOCYL28k7mksb1d0q6DD38WKP7ABffjnXyUWJPVaWRgUOivwXwg==", + "dev": true, + "dependencies": { + "jest-mock": "^21.2.0", + "jest-util": "^21.2.1", + "jsdom": "^9.12.0" + } + }, + "node_modules/jest-environment-node": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-21.2.1.tgz", + "integrity": "sha512-R211867wx9mVBVHzrjGRGTy5cd05K7eqzQl/WyZixR/VkJ4FayS8qkKXZyYnwZi6Rxo6WEV81cDbiUx/GfuLNw==", + "dev": true, + "dependencies": { + "jest-mock": "^21.2.0", + "jest-util": "^21.2.1" + } + }, + "node_modules/jest-get-type": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz", + "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==", + "dev": true + }, + "node_modules/jest-haste-map": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-21.2.0.tgz", + "integrity": "sha512-5LhsY/loPH7wwOFRMs+PT4aIAORJ2qwgbpMFlbWbxfN0bk3ZCwxJ530vrbSiTstMkYLao6JwBkLhCJ5XbY7ZHw==", + "dev": true, + "dependencies": { + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.1.11", + "jest-docblock": "^21.2.0", + "micromatch": "^2.3.11", + "sane": "^2.0.0", + "worker-farm": "^1.3.1" + } + }, + "node_modules/jest-jasmine2": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-21.2.1.tgz", + "integrity": "sha512-lw8FXXIEekD+jYNlStfgNsUHpfMWhWWCgHV7n0B7mA/vendH7vBFs8xybjQsDzJSduptBZJHqQX9SMssya9+3A==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1", + "expect": "^21.2.1", + "graceful-fs": "^4.1.11", + "jest-diff": "^21.2.1", + "jest-matcher-utils": "^21.2.1", + "jest-message-util": "^21.2.1", + "jest-snapshot": "^21.2.1", + "p-cancelable": "^0.3.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-21.2.1.tgz", + "integrity": "sha512-kn56My+sekD43dwQPrXBl9Zn9tAqwoy25xxe7/iY4u+mG8P3ALj5IK7MLHZ4Mi3xW7uWVCjGY8cm4PqgbsqMCg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1", + "jest-get-type": "^21.2.0", + "pretty-format": "^21.2.1" + } + }, + "node_modules/jest-message-util": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-21.2.1.tgz", + "integrity": "sha512-EbC1X2n0t9IdeMECJn2BOg7buOGivCvVNjqKMXTzQOu7uIfLml+keUfCALDh8o4rbtndIeyGU8/BKfoTr/LVDQ==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0" + } + }, + "node_modules/jest-mock": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-21.2.0.tgz", + "integrity": "sha512-aZDfyVf0LEoABWiY6N0d+O963dUQSyUa4qgzurHR3TBDPen0YxKCJ6l2i7lQGh1tVdsuvdrCZ4qPj+A7PievCw==", + "dev": true + }, + "node_modules/jest-regex-util": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-21.2.0.tgz", + "integrity": "sha512-BKQ1F83EQy0d9Jen/mcVX7D+lUt2tthhK/2gDWRgLDJRNOdRgSp1iVqFxP8EN1ARuypvDflRfPzYT8fQnoBQFQ==", + "dev": true + }, + "node_modules/jest-resolve": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-21.2.0.tgz", + "integrity": "sha512-vefQ/Lr+VdNvHUZFQXWtOqHX3HEdOc2MtSahBO89qXywEbUxGPB9ZLP9+BHinkxb60UT2Q/tTDOS6rYc6Mwigw==", + "dev": true, + "dependencies": { + "browser-resolve": "^1.11.2", + "chalk": "^2.0.1", + "is-builtin-module": "^1.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-21.2.0.tgz", + "integrity": "sha512-ok8ybRFU5ScaAcfufIQrCbdNJSRZ85mkxJ1EhUp8Bhav1W1/jv/rl1Q6QoVQHObNxmKnbHVKrfLZbCbOsXQ+bQ==", + "dev": true, + "dependencies": { + "jest-regex-util": "^21.2.0" + } + }, + "node_modules/jest-runner": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-21.2.1.tgz", + "integrity": "sha512-Anb72BOQlHqF/zETqZ2K20dbYsnqW/nZO7jV8BYENl+3c44JhMrA8zd1lt52+N7ErnsQMd2HHKiVwN9GYSXmrg==", + "dev": true, + "dependencies": { + "jest-config": "^21.2.1", + "jest-docblock": "^21.2.0", + "jest-haste-map": "^21.2.0", + "jest-jasmine2": "^21.2.1", + "jest-message-util": "^21.2.1", + "jest-runtime": "^21.2.1", + "jest-util": "^21.2.1", + "pify": "^3.0.0", + "throat": "^4.0.0", + "worker-farm": "^1.3.1" + } + }, + "node_modules/jest-runner/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-runtime": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-21.2.1.tgz", + "integrity": "sha512-6omlpA3+NSE+rHwD0PQjNEjZeb2z+oRmuehMfM1tWQVum+E0WV3pFt26Am0DUfQkkPyTABvxITRjCUclYgSOsA==", + "dev": true, + "dependencies": { + "babel-core": "^6.0.0", + "babel-jest": "^21.2.0", + "babel-plugin-istanbul": "^4.0.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "graceful-fs": "^4.1.11", + "jest-config": "^21.2.1", + "jest-haste-map": "^21.2.0", + "jest-regex-util": "^21.2.0", + "jest-resolve": "^21.2.0", + "jest-util": "^21.2.1", + "json-stable-stringify": "^1.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0", + "strip-bom": "3.0.0", + "write-file-atomic": "^2.1.0", + "yargs": "^9.0.0" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + } + }, + "node_modules/jest-runtime/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-serializer-vue": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/jest-serializer-vue/-/jest-serializer-vue-0.3.0.tgz", + "integrity": "sha512-Id1x3XabYu2r6BnmTfGk2tY172BEqR+vAzSvPk4VF8HyVqwebxZQbqiZ/giAtCnRSqi6lzxuyvzQbwQ6bo6Hbg==", + "dev": true, + "dependencies": { + "pretty": "2.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-21.2.1.tgz", + "integrity": "sha512-bpaeBnDpdqaRTzN8tWg0DqOTo2DvD3StOemxn67CUd1p1Po+BUpvePAp44jdJ7Pxcjfg+42o4NHw1SxdCA2rvg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1", + "jest-diff": "^21.2.1", + "jest-matcher-utils": "^21.2.1", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^21.2.1" + } + }, + "node_modules/jest-util": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-21.2.1.tgz", + "integrity": "sha512-r20W91rmHY3fnCoO7aOAlyfC51x2yeV3xF+prGsJAUsYhKeV670ZB8NO88Lwm7ASu8SdH0S+U+eFf498kjhA4g==", + "dev": true, + "dependencies": { + "callsites": "^2.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.11", + "jest-message-util": "^21.2.1", + "jest-mock": "^21.2.0", + "jest-validate": "^21.2.1", + "mkdirp": "^0.5.1" + } + }, + "node_modules/jest-util/node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-validate": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.2.1.tgz", + "integrity": "sha512-k4HLI1rZQjlU+EC682RlQ6oZvLrE5SCh3brseQc24vbZTxzT/k/3urar5QMCVgjadmSO7lECeGdc6YxnM3yEGg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1", + "jest-get-type": "^21.2.0", + "leven": "^2.1.0", + "pretty-format": "^21.2.1" + } + }, + "node_modules/jest/node_modules/ansi-escapes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest/node_modules/jest-cli": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-21.2.1.tgz", + "integrity": "sha512-T1BzrbFxDIW/LLYQqVfo94y/hhaj1NzVQkZgBumAC+sxbjMROI7VkihOdxNR758iYbQykL2ZOWUBurFgkQrzdg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "is-ci": "^1.0.10", + "istanbul-api": "^1.1.1", + "istanbul-lib-coverage": "^1.0.1", + "istanbul-lib-instrument": "^1.4.2", + "istanbul-lib-source-maps": "^1.1.0", + "jest-changed-files": "^21.2.0", + "jest-config": "^21.2.1", + "jest-environment-jsdom": "^21.2.1", + "jest-haste-map": "^21.2.0", + "jest-message-util": "^21.2.1", + "jest-regex-util": "^21.2.0", + "jest-resolve-dependencies": "^21.2.0", + "jest-runner": "^21.2.1", + "jest-runtime": "^21.2.1", + "jest-snapshot": "^21.2.1", + "jest-util": "^21.2.1", + "micromatch": "^2.3.11", + "node-notifier": "^5.0.2", + "pify": "^3.0.0", + "slash": "^1.0.0", + "string-length": "^2.0.0", + "strip-ansi": "^4.0.0", + "which": "^1.2.12", + "worker-farm": "^1.3.1", + "yargs": "^9.0.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/jest/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest/node_modules/string-length": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", + "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", + "dev": true, + "dependencies": { + "astral-regex": "^1.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jquery": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-1.12.4.tgz", + "integrity": "sha1-AeHfuikP5z3rp3zurLD5ui/sngw=" + }, + "node_modules/jquery-browserify": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/jquery-browserify/-/jquery-browserify-1.8.1.tgz", + "integrity": "sha1-DeqddBpPQRWuGYDEUxsiUCmRoBU=" + }, + "node_modules/jquery-mobile": { + "version": "1.5.0-alpha.1", + "resolved": "https://registry.npmjs.org/jquery-mobile/-/jquery-mobile-1.5.0-alpha.1.tgz", + "integrity": "sha1-KoQQ1X873re5ad4vTancOQb5kZ4=", + "dependencies": { + "jquery": ">=1.8.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/js-base64": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.0.tgz", + "integrity": "sha512-Wehd+7Pf9tFvGb+ydPm9TjYjV8X1YHOVyG8QyELZxEMqOhemVwGRmoG8iQ/soqI3n8v4xn59zaLxiCJiaaRzKA==", + "dev": true + }, + "node_modules/js-beautify": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.7.5.tgz", + "integrity": "sha512-9OhfAqGOrD7hoQBLJMTA+BKuKmoEtTJXzZ7WDF/9gvjtey1koVLuZqIY6c51aPDjbNdNtIXAkiWKVhziawE9Og==", + "dev": true, + "dependencies": { + "config-chain": "~1.1.5", + "editorconfig": "^0.13.2", + "mkdirp": "~0.5.0", + "nopt": "~3.0.1" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + } + }, + "node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^2.6.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "node_modules/jsdom": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", + "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", + "dev": true, + "dependencies": { + "abab": "^1.0.3", + "acorn": "^4.0.4", + "acorn-globals": "^3.1.0", + "array-equal": "^1.0.0", + "content-type-parser": "^1.0.1", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": ">= 0.2.37 < 0.3.0", + "escodegen": "^1.6.1", + "html-encoding-sniffer": "^1.0.1", + "nwmatcher": ">= 1.3.9 < 2.0.0", + "parse5": "^1.5.1", + "request": "^2.79.0", + "sax": "^1.2.1", + "symbol-tree": "^3.2.1", + "tough-cookie": "^2.3.2", + "webidl-conversions": "^4.0.0", + "whatwg-encoding": "^1.0.1", + "whatwg-url": "^4.3.0", + "xml-name-validator": "^2.0.1" + } + }, + "node_modules/jsdom/node_modules/acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "node_modules/json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "dependencies": { + "jsonify": "~0.0.0" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "deprecated": "Please use the native JSON object instead of JSON 3", + "dev": true + }, + "node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/jstransform": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/jstransform/-/jstransform-11.0.3.tgz", + "integrity": "sha1-CaeJk+CuTU70SH9hVakfYZDLQiM=", + "dependencies": { + "base62": "^1.1.0", + "commoner": "^0.10.1", + "esprima-fb": "^15001.1.0-dev-harmony-fb", + "object-assign": "^2.0.0", + "source-map": "^0.4.2" + }, + "bin": { + "jstransform": "bin/jstransform" + }, + "engines": { + "node": ">=0.8.8" + } + }, + "node_modules/jstransform/node_modules/esprima-fb": { + "version": "15001.1.0-dev-harmony-fb", + "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1.0-dev-harmony-fb.tgz", + "integrity": "sha1-MKlHMDxrjV6VW+4rmbHSMyBqaQE=", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jstransform/node_modules/object-assign": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jstransform/node_modules/source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/kew": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", + "dev": true + }, + "node_modules/killable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz", + "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms=", + "dev": true + }, + "node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/last-call-webpack-plugin": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-2.1.2.tgz", + "integrity": "sha512-CZc+m2xZm51J8qSwdODeiiNeqh8CYkKEq6Rw8IkE4i/4yqf2cJhjQPsA6BtAV970ePRNhwEOXhy2U5xc5Jwh9Q==", + "dev": true, + "dependencies": { + "lodash": "^4.17.4", + "webpack-sources": "^1.0.1" + } + }, + "node_modules/lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-fs-cache": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz", + "integrity": "sha1-VuC/CL2XCLJqdltoUJhAyN7J/bw=", + "dev": true, + "dependencies": { + "find-cache-dir": "^0.1.1", + "mkdirp": "0.5.1" + } + }, + "node_modules/loader-fs-cache/node_modules/find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "mkdirp": "^0.5.1", + "pkg-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-fs-cache/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-fs-cache/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-fs-cache/node_modules/pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "dev": true, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "dependencies": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "node_modules/lodash._arraycopy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", + "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=", + "dev": true + }, + "node_modules/lodash._arrayeach": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz", + "integrity": "sha1-urFWsqkNPxu9XGU0AzSeXlkz754=", + "dev": true + }, + "node_modules/lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "dependencies": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._baseclone": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz", + "integrity": "sha1-MDUZv2OT/n5C802LYw73eU41Qrc=", + "dev": true, + "dependencies": { + "lodash._arraycopy": "^3.0.0", + "lodash._arrayeach": "^3.0.0", + "lodash._baseassign": "^3.0.0", + "lodash._basefor": "^3.0.0", + "lodash.isarray": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "node_modules/lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "node_modules/lodash._basefor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz", + "integrity": "sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI=", + "dev": true + }, + "node_modules/lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=", + "dev": true + }, + "node_modules/lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "node_modules/lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "node_modules/lodash._stack": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lodash._stack/-/lodash._stack-4.1.3.tgz", + "integrity": "sha1-dRqnbBuWSwR+dtFPxyoJP8teLdA=", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "node_modules/lodash.clone": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-3.0.3.tgz", + "integrity": "sha1-hGiMc9MrWpDKJWFpY/GJJSqZcEM=", + "dev": true, + "dependencies": { + "lodash._baseclone": "^3.0.0", + "lodash._bindcallback": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "node_modules/lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", + "dev": true + }, + "node_modules/lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dev": true, + "dependencies": { + "lodash._baseassign": "^3.0.0", + "lodash._basecreate": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "node_modules/lodash.defaultsdeep": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.3.2.tgz", + "integrity": "sha1-bBpYbmxWR7DmTi15gUG4g2FYvoo=", + "dev": true, + "dependencies": { + "lodash._baseclone": "^4.0.0", + "lodash._stack": "^4.0.0", + "lodash.isplainobject": "^4.0.0", + "lodash.keysin": "^4.0.0", + "lodash.mergewith": "^4.0.0", + "lodash.rest": "^4.0.0" + } + }, + "node_modules/lodash.defaultsdeep/node_modules/lodash._baseclone": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-4.5.7.tgz", + "integrity": "sha1-zkKt4IOE711i+nfDD2GkbmhvhDQ=", + "dev": true + }, + "node_modules/lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "node_modules/lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "node_modules/lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "dependencies": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "node_modules/lodash.keysin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.keysin/-/lodash.keysin-4.2.0.tgz", + "integrity": "sha1-jMP7NcLZSsxEOhhj4C+kB5nqbyg=", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "node_modules/lodash.mergewith": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", + "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=", + "dev": true + }, + "node_modules/lodash.rest": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/lodash.rest/-/lodash.rest-4.0.5.tgz", + "integrity": "sha1-lU73UEkmIDjJbR/Jiyj9r58Hcqo=", + "dev": true + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha1-lDbjTtJgk+1/+uGTYUQ1CRXZrdg=" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "dependencies": { + "chalk": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/loglevel": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", + "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "node_modules/lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/macaddress": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz", + "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=", + "dev": true + }, + "node_modules/make-dir": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", + "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "dependencies": { + "tmpl": "1.0.x" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/material-design-icons-iconfont": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/material-design-icons-iconfont/-/material-design-icons-iconfont-3.0.3.tgz", + "integrity": "sha1-FUoQhAR9Ticjf6f1o34Qdc7qbfI=" + }, + "node_modules/math-expression-evaluator": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", + "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", + "dev": true + }, + "node_modules/md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/md5.js/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "dependencies": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node_modules/merge": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", + "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", + "dev": true + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "dependencies": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "dependencies": { + "mime-db": "~1.30.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "engines": { + "node": ">=4" + } + }, + "node_modules/mimic-response": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", + "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "node_modules/mississippi": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-1.3.0.tgz", + "integrity": "sha1-0gFYPrEjJ+PFwWQqQEqcrPlONPU=", + "dev": true, + "dependencies": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^1.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.0.tgz", + "integrity": "sha512-dgaCvoh6i1nosAUBKb0l0pfJ78K8+S9fluyIR2YvAeUD/QuMahnFnF3xYty5eYXMjhGSsB0DsW6A0uAZyetoAg==", + "deprecated": "Critical bug fixed in v2.0.1, please upgrade to the latest version.", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-1.0.0.tgz", + "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0=", + "dev": true + }, + "node_modules/mocha-nightwatch": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/mocha-nightwatch/-/mocha-nightwatch-3.2.2.tgz", + "integrity": "sha1-kby5s73gV912d8eBJeSR5Y1mZHw=", + "dev": true, + "dependencies": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.5", + "glob": "7.0.5", + "growl": "1.9.2", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "bin": { + "_mocha-nightwatch": "bin/_mocha", + "mocha-nightwatch": "bin/mocha" + }, + "engines": { + "node": ">= 0.10.x", + "npm": ">= 1.4.x" + } + }, + "node_modules/mocha-nightwatch/node_modules/commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "dependencies": { + "graceful-readlink": ">= 1.0.0" + }, + "engines": { + "node": ">= 0.6.x" + } + }, + "node_modules/mocha-nightwatch/node_modules/debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "dependencies": { + "ms": "0.7.1" + } + }, + "node_modules/mocha-nightwatch/node_modules/diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mocha-nightwatch/node_modules/glob": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz", + "integrity": "sha1-tCAqaQmbu00pKnwblbZoK2fr3JU=", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha-nightwatch/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mocha-nightwatch/node_modules/ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "node_modules/mocha-nightwatch/node_modules/supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/mockjs": { + "version": "1.0.1-beta3", + "resolved": "https://registry.npmjs.org/mockjs/-/mockjs-1.0.1-beta3.tgz", + "integrity": "sha1-0jTzwnJWOXVk8slVFC6JGQlTcgk=", + "dependencies": { + "commander": "*" + }, + "bin": { + "random": "bin/random" + } + }, + "node_modules/moment": { + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.21.0.tgz", + "integrity": "sha512-TCZ36BjURTeFTM/CwRcViQlfkMvL1/vFISuNLO5GkcVm1+QHfbSiNqZuWeMFjj1/3+uAjXswgRk30j1kkLYJBQ==", + "engines": { + "node": "*" + } + }, + "node_modules/move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/multicast-dns": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.1.tgz", + "integrity": "sha512-uV3/ckdsffHx9IrGQrx613mturMdMqQ06WTq+C09NsStJ9iNG6RcUWgPKs1Rfjy+idZT6tfQoXEusGNnEZhT3w==", + "dev": true, + "dependencies": { + "dns-packet": "^1.0.1", + "thunky": "^0.1.0" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "node_modules/nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "dev": true, + "optional": true + }, + "node_modules/nanomatch": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.7.tgz", + "integrity": "sha512-/5ldsnyurvEw7wNpxLFgjVvBLMta43niEYOy0CJ4ntcYSbx6bugRUTQeFb4BR/WanEL1o3aQgHuVLHQaB6tOqg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "is-odd": "^1.0.0", + "kind-of": "^5.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/ncname": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ncname/-/ncname-1.0.0.tgz", + "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=", + "dev": true, + "dependencies": { + "xml-char-classes": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/netmask": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", + "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/nightwatch": { + "version": "0.9.19", + "resolved": "https://registry.npmjs.org/nightwatch/-/nightwatch-0.9.19.tgz", + "integrity": "sha1-S9l1cnPTC4RfBIR6mLcb6bt8Szs=", + "dev": true, + "dependencies": { + "chai-nightwatch": "~0.1.x", + "ejs": "2.5.7", + "lodash.clone": "3.0.3", + "lodash.defaultsdeep": "4.3.2", + "minimatch": "3.0.3", + "mkpath": "1.0.0", + "mocha-nightwatch": "3.2.2", + "optimist": "0.6.1", + "proxy-agent": "2.0.0", + "q": "1.4.1" + }, + "bin": { + "nightwatch": "bin/nightwatch" + } + }, + "node_modules/nightwatch/node_modules/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "dev": true, + "dependencies": { + "brace-expansion": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nightwatch/node_modules/q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "dependencies": { + "lower-case": "^1.1.1" + } + }, + "node_modules/node-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.1.1.tgz", + "integrity": "sha1-CFJGRe5AOd7cPcwd18a5eeBhnkQ=", + "dev": true, + "dependencies": { + "clone": "2.x", + "lodash": "4.x" + }, + "engines": { + "node": ">= 0.4.6" + } + }, + "node_modules/node-cache/node_modules/clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/node-fetch": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz", + "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=", + "dependencies": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node_modules/node-forge": { + "version": "0.6.33", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.6.33.tgz", + "integrity": "sha1-RjgRh59XPUUVWtap9D3ClujoXrw=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-libs-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "dev": true, + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.0", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.10.3", + "vm-browserify": "0.0.4" + } + }, + "node_modules/node-notifier": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.1.2.tgz", + "integrity": "sha1-L6nhJgX6EACdRFSdb82KY93g5P8=", + "dev": true, + "dependencies": { + "growly": "^1.3.0", + "semver": "^5.3.0", + "shellwords": "^0.1.0", + "which": "^1.2.12" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nth-check": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", + "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nwmatcher": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", + "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==", + "dev": true + }, + "node_modules/oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "deprecated": "Please upgrade to v0.1.7", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "deprecated": "Please upgrade to v0.1.5", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.2.0.tgz", + "integrity": "sha512-smRWXzkvxw72VquyZ0wggySl7PFUtoDhvhpdwgESXxUrH7vVhhp9asfup1+rVLrhsl7L45Ee1Q/l5R2Ul4MwUg==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-visit/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "dependencies": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/observable": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/observable/-/observable-1.3.1.tgz", + "integrity": "sha1-PSogOxQw2vak1tNvI2zBPm7Vu04=" + }, + "node_modules/obuf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz", + "integrity": "sha1-EEEktsYCxnlogaBCVB0220OlJk4=", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/opencollective": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/opencollective/-/opencollective-1.0.3.tgz", + "integrity": "sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE=", + "dependencies": { + "babel-polyfill": "6.23.0", + "chalk": "1.1.3", + "inquirer": "3.0.6", + "minimist": "1.2.0", + "node-fetch": "1.6.3", + "opn": "4.0.2" + }, + "bin": { + "oc": "dist/bin/opencollective.js", + "opencollective": "dist/bin/opencollective.js" + } + }, + "node_modules/opencollective/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "engines": { + "node": ">=4" + } + }, + "node_modules/opencollective/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/opencollective/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/opencollective/node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opencollective/node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opencollective/node_modules/inquirer": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz", + "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=", + "dependencies": { + "ansi-escapes": "^1.1.0", + "chalk": "^1.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.1", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx": "^4.1.0", + "string-width": "^2.0.0", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + } + }, + "node_modules/opencollective/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "engines": { + "node": ">=4" + } + }, + "node_modules/opencollective/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "node_modules/opencollective/node_modules/mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "node_modules/opencollective/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opencollective/node_modules/opn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", + "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=", + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/opencollective/node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opencollective/node_modules/run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dependencies": { + "is-promise": "^2.1.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/opencollective/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opencollective/node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opencollective/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", + "dev": true, + "bin": { + "opener": "opener.js" + } + }, + "node_modules/opn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", + "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==", + "dev": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "dependencies": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "node_modules/optimist/node_modules/wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/optimize-css-assets-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-Fjn7wyyadPAriuH2DHamDQw5B8GohEWbroBkKoPeP+vSF2PIAPI7WDihi8WieMRb/At4q7Ea7zTKaMDuSoIAAg==", + "dev": true, + "dependencies": { + "cssnano": "^3.4.0", + "last-call-webpack-plugin": "^2.1.2" + } + }, + "node_modules/optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-1.3.0.tgz", + "integrity": "sha1-gAeN0rkqk0r2ajrXKluRBpTt5Ro=", + "dev": true, + "dependencies": { + "chalk": "^1.1.1", + "cli-cursor": "^2.1.0", + "cli-spinners": "^1.0.0", + "log-symbols": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/original": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz", + "integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=", + "dev": true, + "dependencies": { + "url-parse": "1.0.x" + } + }, + "node_modules/original/node_modules/url-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz", + "integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=", + "dev": true, + "dependencies": { + "querystringify": "0.0.x", + "requires-port": "1.0.x" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "dependencies": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pac-proxy-agent": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz", + "integrity": "sha512-QBELCWyLYPgE2Gj+4wUEiMscHrQ8nRPBzYItQNOHWavwBt25ohZHQC4qnd5IszdVVrFbLsQ+dPkm6eqdjJAmwQ==", + "dev": true, + "dependencies": { + "agent-base": "2", + "debug": "2", + "extend": "3", + "get-uri": "2", + "http-proxy-agent": "1", + "https-proxy-agent": "1", + "pac-resolver": "~2.0.0", + "raw-body": "2", + "socks-proxy-agent": "2" + } + }, + "node_modules/pac-resolver": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-2.0.0.tgz", + "integrity": "sha1-mbiNLxk/ve78HJpSnB8yYKtSd80=", + "dev": true, + "dependencies": { + "co": "~3.0.6", + "degenerator": "~1.0.2", + "ip": "1.0.1", + "netmask": "~1.0.4", + "thunkify": "~2.1.1" + } + }, + "node_modules/pac-resolver/node_modules/co": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/co/-/co-3.0.6.tgz", + "integrity": "sha1-FEXyJsXrlWE45oyawwFn6n0ua9o=", + "dev": true + }, + "node_modules/pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "node_modules/parallel-transform": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "dev": true, + "dependencies": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "node_modules/param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true, + "dependencies": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3" + } + }, + "node_modules/parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "dependencies": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", + "dev": true + }, + "node_modules/parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pbkdf2": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "node_modules/popper.js": { + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.12.9.tgz", + "integrity": "sha1-DfvC3/lsRRuzMu3Pz6r1ZtMx1bM=", + "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1" + }, + "node_modules/portfinder": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz", + "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=", + "dev": true, + "dependencies": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz", + "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==", + "dev": true, + "dependencies": { + "chalk": "^2.3.0", + "source-map": "^0.6.1", + "supports-color": "^5.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-calc": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "dev": true, + "dependencies": { + "postcss": "^5.0.2", + "postcss-message-helpers": "^2.0.0", + "reduce-css-calc": "^1.2.6" + } + }, + "node_modules/postcss-calc/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-calc/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-calc/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-calc/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-calc/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-calc/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-calc/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-colormin": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", + "dev": true, + "dependencies": { + "colormin": "^1.0.5", + "postcss": "^5.0.13", + "postcss-value-parser": "^3.2.3" + } + }, + "node_modules/postcss-colormin/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-colormin/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-colormin/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-colormin/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-colormin/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-colormin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-colormin/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-convert-values": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", + "dev": true, + "dependencies": { + "postcss": "^5.0.11", + "postcss-value-parser": "^3.1.2" + } + }, + "node_modules/postcss-convert-values/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-convert-values/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-convert-values/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-convert-values/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-convert-values/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-convert-values/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-convert-values/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-discard-comments": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", + "dev": true, + "dependencies": { + "postcss": "^5.0.14" + } + }, + "node_modules/postcss-discard-comments/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-comments/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-comments/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-discard-comments/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-comments/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-discard-comments/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-comments/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", + "dev": true, + "dependencies": { + "postcss": "^5.0.4" + } + }, + "node_modules/postcss-discard-duplicates/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-duplicates/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-duplicates/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-discard-duplicates/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-duplicates/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-discard-duplicates/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-duplicates/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-discard-empty": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", + "dev": true, + "dependencies": { + "postcss": "^5.0.14" + } + }, + "node_modules/postcss-discard-empty/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-empty/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-empty/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-discard-empty/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-empty/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-discard-empty/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-empty/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", + "dev": true, + "dependencies": { + "postcss": "^5.0.16" + } + }, + "node_modules/postcss-discard-overridden/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-overridden/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-overridden/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-discard-overridden/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-overridden/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-discard-overridden/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-overridden/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-discard-unused": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", + "dev": true, + "dependencies": { + "postcss": "^5.0.14", + "uniqs": "^2.0.0" + } + }, + "node_modules/postcss-discard-unused/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-unused/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-unused/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-discard-unused/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-unused/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-discard-unused/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-discard-unused/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-filter-plugins": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz", + "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", + "dev": true, + "dependencies": { + "postcss": "^5.0.4", + "uniqid": "^4.0.0" + } + }, + "node_modules/postcss-filter-plugins/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-filter-plugins/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-filter-plugins/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-filter-plugins/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-filter-plugins/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-filter-plugins/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-filter-plugins/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-import": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.0.0.tgz", + "integrity": "sha1-qWLi34LTvFptpqOGhBdHIE9B71s=", + "dev": true, + "dependencies": { + "postcss": "^6.0.1", + "postcss-value-parser": "^3.2.3", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "node_modules/postcss-load-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz", + "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=", + "dev": true, + "dependencies": { + "cosmiconfig": "^2.1.0", + "object-assign": "^4.1.0", + "postcss-load-options": "^1.2.0", + "postcss-load-plugins": "^2.3.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-load-options": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz", + "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=", + "dev": true, + "dependencies": { + "cosmiconfig": "^2.1.0", + "object-assign": "^4.1.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-load-plugins": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz", + "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=", + "dev": true, + "dependencies": { + "cosmiconfig": "^2.1.1", + "object-assign": "^4.1.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-loader": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.10.tgz", + "integrity": "sha512-xQaDcEgJ/2JqFY18zpFkik8vyYs7oS5ZRbrjvDqkP97k2wYWfPT4+qA0m4o3pTSCsz0u26PNqs8ZO9FRUWAqrA==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "postcss": "^6.0.0", + "postcss-load-config": "^1.2.0", + "schema-utils": "^0.3.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/postcss-merge-idents": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", + "dev": true, + "dependencies": { + "has": "^1.0.1", + "postcss": "^5.0.10", + "postcss-value-parser": "^3.1.1" + } + }, + "node_modules/postcss-merge-idents/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-idents/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-idents/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-merge-idents/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-idents/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-merge-idents/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-idents/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "dev": true, + "dependencies": { + "postcss": "^5.0.4" + } + }, + "node_modules/postcss-merge-longhand/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-longhand/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-longhand/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-merge-longhand/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-longhand/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-merge-longhand/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-longhand/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-merge-rules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", + "dev": true, + "dependencies": { + "browserslist": "^1.5.2", + "caniuse-api": "^1.5.2", + "postcss": "^5.0.4", + "postcss-selector-parser": "^2.2.2", + "vendors": "^1.0.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "deprecated": "Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.", + "dev": true, + "dependencies": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + }, + "bin": { + "browserslist": "cli.js" + } + }, + "node_modules/postcss-merge-rules/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-merge-rules/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=", + "dev": true + }, + "node_modules/postcss-minify-font-values": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.2" + } + }, + "node_modules/postcss-minify-font-values/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-font-values/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-font-values/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-minify-font-values/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-font-values/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-minify-font-values/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-font-values/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "dev": true, + "dependencies": { + "postcss": "^5.0.12", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-minify-gradients/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-minify-params": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.1", + "postcss": "^5.0.2", + "postcss-value-parser": "^3.0.2", + "uniqs": "^2.0.0" + } + }, + "node_modules/postcss-minify-params/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-params/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-params/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-minify-params/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-params/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-minify-params/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-params/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.2", + "has": "^1.0.1", + "postcss": "^5.0.14", + "postcss-selector-parser": "^2.0.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-minify-selectors/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", + "dev": true, + "dependencies": { + "postcss": "^6.0.1" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "dev": true, + "dependencies": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "node_modules/postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "dev": true, + "dependencies": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "node_modules/postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "dev": true, + "dependencies": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "dev": true, + "dependencies": { + "postcss": "^5.0.5" + } + }, + "node_modules/postcss-normalize-charset/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-normalize-charset/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-normalize-charset/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-normalize-charset/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-normalize-charset/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-normalize-charset/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-normalize-charset/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-normalize-url": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "dev": true, + "dependencies": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^1.4.0", + "postcss": "^5.0.14", + "postcss-value-parser": "^3.2.3" + } + }, + "node_modules/postcss-normalize-url/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-normalize-url/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-normalize-url/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-normalize-url/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-normalize-url/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-normalize-url/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-normalize-url/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-ordered-values": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "dev": true, + "dependencies": { + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.1" + } + }, + "node_modules/postcss-ordered-values/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-ordered-values/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-ordered-values/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-ordered-values/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-ordered-values/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-ordered-values/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-ordered-values/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", + "dev": true, + "dependencies": { + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.2" + } + }, + "node_modules/postcss-reduce-idents/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-idents/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-idents/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-reduce-idents/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-idents/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-reduce-idents/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-idents/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "dev": true, + "dependencies": { + "postcss": "^5.0.4" + } + }, + "node_modules/postcss-reduce-initial/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-initial/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-initial/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-reduce-initial/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-initial/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-reduce-initial/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-initial/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "dev": true, + "dependencies": { + "has": "^1.0.1", + "postcss": "^5.0.8", + "postcss-value-parser": "^3.0.1" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, + "dependencies": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "node_modules/postcss-svgo": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "dev": true, + "dependencies": { + "is-svg": "^2.0.0", + "postcss": "^5.0.14", + "postcss-value-parser": "^3.2.3", + "svgo": "^0.7.0" + } + }, + "node_modules/postcss-svgo/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-svgo/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-svgo/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-svgo/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-svgo/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-svgo/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-svgo/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.1", + "postcss": "^5.0.4", + "uniqs": "^2.0.0" + } + }, + "node_modules/postcss-unique-selectors/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-unique-selectors/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-unique-selectors/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-unique-selectors/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-unique-selectors/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-unique-selectors/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-unique-selectors/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-url": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.0.tgz", + "integrity": "sha512-VBP6uf6iL3AZra23nkPkOEkS/5azj1xf/toRrjfkolfFEgg9Gyzg9UhJZeIsz12EGKZTNVeGbPa2XtaZm/iZvg==", + "dev": true, + "dependencies": { + "mime": "^1.4.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.0", + "postcss": "^6.0.1", + "xxhashjs": "^0.2.1" + } + }, + "node_modules/postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "dev": true + }, + "node_modules/postcss-zindex": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", + "dev": true, + "dependencies": { + "has": "^1.0.1", + "postcss": "^5.0.4", + "uniqs": "^2.0.0" + } + }, + "node_modules/postcss-zindex/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-zindex/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-zindex/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-zindex/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-zindex/node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-zindex/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-zindex/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prettier": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.10.2.tgz", + "integrity": "sha512-TcdNoQIWFoHblurqqU6d1ysopjq7UX0oRcT/hJ8qvBAELiYWn+Ugf0AXdnzISEJ7vuhNnQ98N8jR8Sh53x4IZg==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pretty": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz", + "integrity": "sha1-rbx5YLe7/iiaVX3F9zdhmiINBqU=", + "dev": true, + "dependencies": { + "condense-newlines": "^0.2.1", + "extend-shallow": "^2.0.1", + "js-beautify": "^1.6.12" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "dev": true, + "dependencies": { + "renderkid": "^2.0.1", + "utila": "~0.4" + } + }, + "node_modules/pretty-format": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz", + "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/printj": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", + "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", + "bin": { + "printj": "bin/printj.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "node_modules/progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", + "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", + "dev": true, + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.5.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-agent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-2.0.0.tgz", + "integrity": "sha1-V+tTR6qAXXTsaByyVknbo5yTNJk=", + "dev": true, + "dependencies": { + "agent-base": "2", + "debug": "2", + "extend": "3", + "http-proxy-agent": "1", + "https-proxy-agent": "1", + "lru-cache": "~2.6.5", + "pac-proxy-agent": "1", + "socks-proxy-agent": "2" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz", + "integrity": "sha1-5W1jVBSO3o13B7WNFDIg/QjfD9U=", + "dev": true + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.3.6.tgz", + "integrity": "sha512-BurGAcvezsINL5US9T9wGHHcLNrG6MCp//ECtxron3vcR+Rfx5Anqq7HbZXNJvFQli8FGVsWCAvywEJFV5Hx/Q==", + "dev": true, + "dependencies": { + "duplexify": "^3.5.3", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.0.tgz", + "integrity": "sha512-6MYypjOvtiXhBSTOD0Zs5eNjCGfnqi5mPsCsW+dgKTxrZzQMZQNpBo3XRkLx7id753f3EeyHLBqzqqUymIolgw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "dependencies": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystringify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz", + "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=", + "dev": true + }, + "node_modules/randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/randomatic/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/randomatic/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/randomatic/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", + "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "dev": true, + "dependencies": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "mute-stream": "0.0.5" + } + }, + "node_modules/recast": { + "version": "0.11.23", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", + "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", + "dependencies": { + "ast-types": "0.9.6", + "esprima": "~3.1.0", + "private": "~0.1.5", + "source-map": "~0.5.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/recast/node_modules/ast-types": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", + "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/recast/node_modules/esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/recast/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "dependencies": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reduce-css-calc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "dev": true, + "dependencies": { + "balanced-match": "^0.4.2", + "math-expression-evaluator": "^1.2.14", + "reduce-function-call": "^1.0.1" + } + }, + "node_modules/reduce-css-calc/node_modules/balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "node_modules/reduce-function-call": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", + "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "dev": true, + "dependencies": { + "balanced-match": "^0.4.2" + } + }, + "node_modules/reduce-function-call/node_modules/balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "node_modules/regenerate": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", + "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==", + "dev": true + }, + "node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "node_modules/regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "node_modules/regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "dependencies": { + "is-equal-shallow": "^0.1.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.0.tgz", + "integrity": "sha1-Qvg+OXcWIt+CawKvF2Ul1qXxV/k=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "dependencies": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "node_modules/regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "node_modules/renderkid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", + "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=", + "dev": true, + "dependencies": { + "css-select": "^1.1.0", + "dom-converter": "~0.1", + "htmlparser2": "~3.3.0", + "strip-ansi": "^3.0.0", + "utila": "~0.3" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", + "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", + "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/renderkid/node_modules/htmlparser2": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", + "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", + "dev": true, + "dependencies": { + "domelementtype": "1", + "domhandler": "2.1", + "domutils": "1.1", + "readable-stream": "1.0" + } + }, + "node_modules/renderkid/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/renderkid/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/renderkid/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/renderkid/node_modules/utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/request": { + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "hawk": "~6.0.2", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "stringstream": "~0.0.5", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "node_modules/require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "dependencies": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.5" + } + }, + "node_modules/resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "dependencies": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "dependencies": { + "align-text": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "dependencies": { + "glob": "^7.0.5" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "dev": true, + "dependencies": { + "hash-base": "^2.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "dependencies": { + "once": "^1.3.0" + } + }, + "node_modules/run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "dependencies": { + "aproba": "^1.1.1" + } + }, + "node_modules/rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=" + }, + "node_modules/rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "node_modules/sane": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-2.2.0.tgz", + "integrity": "sha512-OSJxhHO0CgPUw3lUm3GhfREAfza45smvEI9ozuFrxKG10GHVo0ryW9FK5VYlLvxj0SV7HVKHW0voYJIRu27GWg==", + "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", + "dev": true, + "dependencies": { + "anymatch": "^1.3.0", + "exec-sh": "^0.2.0", + "fb-watchman": "^2.0.0", + "minimatch": "^3.0.2", + "minimist": "^1.1.1", + "walker": "~1.0.5", + "watch": "~0.18.0" + }, + "bin": { + "sane": "src/cli.js" + }, + "engines": { + "node": ">=0.6.0" + }, + "optionalDependencies": { + "fsevents": "^1.1.1" + } + }, + "node_modules/sane/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "dev": true, + "dependencies": { + "ajv": "^5.0.0" + }, + "engines": { + "node": ">= 4.3 < 5.0.0 || >= 5.10" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "node_modules/selenium-server": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/selenium-server/-/selenium-server-3.8.1.tgz", + "integrity": "sha512-Ym66mGUUFN0YUceazRQldtxm6mMmcvFY/XAX/FI+wxAPF3692W/lu1HKB7AMb1MK0s+qWYjtiXrT4eFjtNIekg==", + "dev": true, + "bin": { + "selenium": "bin/selenium" + } + }, + "node_modules/selfsigned": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.1.tgz", + "integrity": "sha1-v4y3uDJWxFUeMTR8YxF3jbme7FI=", + "dev": true, + "dependencies": { + "node-forge": "0.6.33" + } + }, + "node_modules/semantic-ui-css": { + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/semantic-ui-css/-/semantic-ui-css-2.2.12.tgz", + "integrity": "sha512-RrA3k6hya+kEMDmVLT38SBTDQD8FgdnFi16eMPuQ1N1xUOoBxKzr+HZASb7Zo3xlMvkYqEWvPIp58Wjl6Zcsfg==", + "dependencies": { + "jquery": "x.*" + } + }, + "node_modules/semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", + "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.1", + "destroy": "~1.0.4", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.3.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true, + "bin": { + "mime": "cli.js" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-javascript": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.4.0.tgz", + "integrity": "sha1-fJWFFNtqwkQ6irwGLcn3iGp/YAU=", + "dev": true + }, + "node_modules/serve-favicon": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.3.2.tgz", + "integrity": "sha1-3UGeJo3gEqtysxnTN/IQUBP5OB8=", + "dependencies": { + "etag": "~1.7.0", + "fresh": "0.3.0", + "ms": "0.7.2", + "parseurl": "~1.3.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-favicon/node_modules/etag": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz", + "integrity": "sha1-A9MLX2fdbmMtKUXTDWZScxo01dg=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-favicon/node_modules/fresh": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz", + "integrity": "sha1-ZR+DjiJCTnVm3hYdg1jKoZn4PU8=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-favicon/node_modules/ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", + "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/set-getter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", + "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", + "dev": true, + "dependencies": { + "to-object-path": "^0.3.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + }, + "node_modules/sha.js": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", + "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "iojs": "*", + "node": ">=0.11.0" + } + }, + "node_modules/shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true + }, + "node_modules/sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "node_modules/signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/smart-buffer": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", + "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=", + "dev": true, + "engines": { + "node": ">= 0.10.15", + "npm": ">= 1.3.5" + } + }, + "node_modules/snapdragon": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz", + "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "deprecated": "Please upgrade to v0.1.7", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "deprecated": "Please upgrade to v0.1.5", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "deprecated": "This module moved to @hapi/sntp. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.", + "dev": true, + "dependencies": { + "hoek": "4.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" + } + }, + "node_modules/sockjs-client": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz", + "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=", + "dev": true, + "dependencies": { + "debug": "^2.6.6", + "eventsource": "0.1.6", + "faye-websocket": "~0.11.0", + "inherits": "^2.0.1", + "json3": "^3.3.2", + "url-parse": "^1.1.8" + } + }, + "node_modules/sockjs-client/node_modules/faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/socks": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz", + "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=", + "deprecated": "If using 2.x branch, please upgrade to at least 2.1.6 to avoid a serious bug with socket data flow and an import issue introduced in 2.1.0", + "dev": true, + "dependencies": { + "ip": "^1.1.4", + "smart-buffer": "^1.0.13" + }, + "engines": { + "node": ">= 0.10.0", + "npm": ">= 1.3.5" + } + }, + "node_modules/socks-proxy-agent": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz", + "integrity": "sha512-sFtmYqdUK5dAMh85H0LEVFUCO7OhJJe1/z2x/Z6mxp3s7/QPf1RkZmpZy+BpuU0bEjcV9npqKjq9Y3kwFUjnxw==", + "dev": true, + "dependencies": { + "agent-base": "2", + "extend": "3", + "socks": "~1.1.5" + } + }, + "node_modules/socks/node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sortable": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sortable/-/sortable-2.0.0.tgz", + "integrity": "sha1-NLNUK0KQTFm4RU9VFIoPT2AYaUM=", + "dependencies": { + "hyperscript": "~1.0.1", + "jquery-browserify": "~1.8.1", + "observable": "~1.3.1" + } + }, + "node_modules/sortablejs": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.7.0.tgz", + "integrity": "sha1-gKKyNwq9Vo4c7IwnETHvMKkE+ig=" + }, + "node_modules/source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", + "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.0.0", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "dependencies": { + "source-map": "^0.5.6" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "dependencies": { + "spdx-license-ids": "^1.0.2" + } + }, + "node_modules/spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "node_modules/spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "node_modules/spdy": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", + "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=", + "dev": true, + "engines": [ + "node >= 0.7.0" + ], + "dependencies": { + "debug": "^2.6.8", + "handle-thing": "^1.2.5", + "http-deceiver": "^1.2.7", + "safe-buffer": "^5.0.1", + "select-hose": "^2.0.0", + "spdy-transport": "^2.0.18" + } + }, + "node_modules/spdy-transport": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.20.tgz", + "integrity": "sha1-c15yBUxIayNU/onnAiVgBKOazk0=", + "dev": true, + "dependencies": { + "debug": "^2.6.8", + "detect-node": "^2.0.3", + "hpack.js": "^2.1.6", + "obuf": "^1.1.1", + "readable-stream": "^2.2.9", + "safe-buffer": "^5.0.1", + "wbuf": "^1.7.2" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/ssf": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.9.4.tgz", + "integrity": "sha1-jlepjBnbvx7dU/D4yef9UksPbJw=", + "dependencies": { + "colors": "0.6.2", + "frac": "~1.0.6", + "voc": "" + }, + "bin": { + "ssf": "bin/ssf.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ssf/node_modules/colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "dashdash": "^1.12.0", + "getpass": "^0.1.1" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + }, + "optionalDependencies": { + "bcrypt-pbkdf": "^1.0.0", + "ecc-jsbn": "~0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" + } + }, + "node_modules/ssri": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.0.0.tgz", + "integrity": "sha512-728D4yoQcQm1ooZvSbywLkV1RjfITZXh0oWrhM/lnsx3nAHx7LsRGJWB/YyvoceAYRq98xqbstiN4JBv1/wNHg==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/stackframe": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.0.4.tgz", + "integrity": "sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw==", + "dev": true + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "deprecated": "Please upgrade to v0.1.7", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "deprecated": "Please upgrade to v0.1.5", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-each": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz", + "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/stream-http": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", + "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.2.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", + "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", + "dev": true, + "dependencies": { + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "dependencies": { + "get-stdin": "^4.0.1" + }, + "bin": { + "strip-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "dev": true, + "dependencies": { + "has-flag": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "node_modules/svgo": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dev": true, + "dependencies": { + "coa": "~1.0.1", + "colors": "~1.1.2", + "csso": "~2.3.1", + "js-yaml": "~3.7.0", + "mkdirp": "~0.5.1", + "sax": "~1.2.1", + "whet.extend": "~0.9.9" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, + "node_modules/table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "dependencies": { + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", + "slice-ansi": "0.0.4", + "string-width": "^2.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "dependencies": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/table/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tapable": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/test-exclude": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz", + "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "micromatch": "^2.3.11", + "object-assign": "^4.1.0", + "read-pkg-up": "^1.0.1", + "require-main-filename": "^1.0.1" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "node_modules/through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "dependencies": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + }, + "node_modules/thunkify": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", + "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=", + "dev": true + }, + "node_modules/thunky": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", + "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=", + "dev": true + }, + "node_modules/time-stamp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz", + "integrity": "sha1-lcakRTDhW6jW9KPsuMOj+sRto1c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/timers-browserify": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz", + "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==", + "dev": true, + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz", + "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "regex-not": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "deprecated": "Please upgrade to v0.1.7", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "deprecated": "Please upgrade to v0.1.5", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toposort": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.6.tgz", + "integrity": "sha1-wxdI5V0hDv/AD9zcfW5o19e7nOw=", + "dev": true + }, + "node_modules/tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "dev": true, + "dependencies": { + "punycode": "^1.4.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "node_modules/trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tsconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", + "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", + "dev": true, + "dependencies": { + "@types/strip-bom": "^3.0.0", + "@types/strip-json-comments": "0.0.30", + "strip-bom": "^3.0.0", + "strip-json-comments": "^2.0.0" + } + }, + "node_modules/tsconfig/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/type-is": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.15" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "node_modules/uglify-js": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.5.tgz", + "integrity": "sha512-ZebM2kgBL/UI9rKeAbsS2J0UPPv7SBy5hJNZml/YxB1zC6JK8IztcPs+cxilE4pu0li6vadVSFqiO7xFTKuSrg==", + "dev": true, + "dependencies": { + "commander": "~2.12.1", + "source-map": "~0.6.1" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "node_modules/uglifyjs-webpack-plugin": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.6.tgz", + "integrity": "sha512-VUja+7rYbznEvUaeb8IxOCTUrq4BCb1ml0vffa+mfwKtrAwlqnU0ENF14DtYltV1cxd/HSuK51CCA/D/8kMQVw==", + "dev": true, + "dependencies": { + "cacache": "^10.0.1", + "find-cache-dir": "^1.0.0", + "schema-utils": "^0.4.2", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "uglify-es": "^3.3.4", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" + }, + "engines": { + "node": ">= 4.8 < 5.0.0 || >= 5.10" + }, + "peerDependencies": { + "webpack": "^2.0.0 || ^3.0.0" + } + }, + "node_modules/uglifyjs-webpack-plugin/node_modules/ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true, + "peerDependencies": { + "ajv": "^5.0.0" + } + }, + "node_modules/uglifyjs-webpack-plugin/node_modules/schema-utils": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.3.tgz", + "integrity": "sha512-sgv/iF/T4/SewJkaVpldKC4WjSkz0JsOh2eKtxCPpCO1oR05+7MOF+H476HVRbLArkgA7j5TRJJ4p2jdFkUGQQ==", + "dev": true, + "dependencies": { + "ajv": "^5.0.0", + "ajv-keywords": "^2.1.0" + }, + "engines": { + "node": ">= 4.8 < 5.0.0 || >= 5.10" + }, + "peerDependencies": { + "webpack": "^2.0.0 || ^3.0.0" + } + }, + "node_modules/uglifyjs-webpack-plugin/node_modules/uglify-es": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.5.tgz", + "integrity": "sha512-7IvaFuYtfbcXm0fGb13mmRYVQdzQDXETAtvYHbCDPt2V88Y8l2HaULOyW6ueoYA0JhGIcLK7dtHkDcBWySqnBw==", + "deprecated": "support for ECMAScript is superseded by `uglify-js` as of v3.13.0", + "dev": true, + "dependencies": { + "commander": "~2.12.1", + "source-map": "~0.6.1" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "node_modules/union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value/node_modules/set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "node_modules/uniqid": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz", + "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=", + "dev": true, + "dependencies": { + "macaddress": "^0.2.8" + } + }, + "node_modules/uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "node_modules/unique-filename": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz", + "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", + "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-loader": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.5.9.tgz", + "integrity": "sha512-B7QYFyvv+fOBqBVeefsxv6koWWtjmHaMFT6KZWti4KRw8YUD/hOU+3AECvXuzyVawIBx3z7zQRejXCDSO5kk1Q==", + "dev": true, + "dependencies": { + "loader-utils": "^1.0.2", + "mime": "1.3.x" + }, + "peerDependencies": { + "file-loader": "*" + } + }, + "node_modules/url-loader/node_modules/mime": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.6.tgz", + "integrity": "sha1-WR2E02U6awtKO5343lqoEI5y5eA=", + "dev": true, + "bin": { + "mime": "cli.js" + } + }, + "node_modules/url-parse": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz", + "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==", + "dev": true, + "dependencies": { + "querystringify": "~1.0.0", + "requires-port": "~1.0.0" + } + }, + "node_modules/url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/url-parse/node_modules/querystringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", + "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=", + "dev": true + }, + "node_modules/url-pattern": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/url-pattern/-/url-pattern-1.0.3.tgz", + "integrity": "sha1-BAkpJHGyTyPFDWWkeTF5PStaz8E=", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "engines": { + "node": ">= 4" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "node_modules/use": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz", + "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "lazy-cache": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "deprecated": "Please upgrade to v0.1.7", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "deprecated": "Please upgrade to v0.1.5", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use/node_modules/lazy-cache": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", + "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", + "dev": true, + "dependencies": { + "set-getter": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "dependencies": { + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vendors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz", + "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=", + "dev": true, + "engines": { + "node": ">=0.11.0" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "dependencies": { + "indexof": "0.0.1" + } + }, + "node_modules/voc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/voc/-/voc-1.1.0.tgz", + "integrity": "sha512-fthgd8OJLqq8vPcLjElTk6Rcl2e3v5ekcXauImaqEnQqd5yUWKg1+ZOBgS2KTWuVKcuvZMQq4TDptiT1uYddUA==", + "bin": { + "voc": "voc.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/vue": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.13.tgz", + "integrity": "sha512-3D+lY7HTkKbtswDM4BBHgqyq+qo8IAEE8lz8va1dz3LLmttjgo0FxairO4r1iN2OBqk8o1FyL4hvzzTFEdQSEw==", + "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details." + }, + "node_modules/vue-carousel": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/vue-carousel/-/vue-carousel-0.6.5.tgz", + "integrity": "sha1-8E5Ehc5qwkBOr/GGkj960FeDkgU=" + }, + "node_modules/vue-clip": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vue-clip/-/vue-clip-1.0.0.tgz", + "integrity": "sha1-woOZ6kyklXo5EIZYTVBUinQ0CYA=", + "dependencies": { + "dropzone": "^4.3.0", + "lodash.clone": "^4.5.0" + } + }, + "node_modules/vue-clip/node_modules/lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" + }, + "node_modules/vue-dual-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vue-dual-list/-/vue-dual-list-1.0.0.tgz", + "integrity": "sha512-2X9E5iOzVw/edsYrmKvBlMeetusbM5nzNB+Pv3WlLVzGMC5A4OBwLW3SAS55kAGNsKEexWpeUdPaZz1IADEkew==", + "dependencies": { + "express": "4.15.2", + "serve-favicon": "2.3.2", + "vue": "^2.2.6", + "vue-material": "^0.7.1", + "vue-router": "^2.3.1" + }, + "engines": { + "node": ">= 4.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/vue-dual-list/node_modules/debug": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz", + "integrity": "sha1-eYVQkLosTjEVzH2HaUkdWPBJE1E=", + "dependencies": { + "ms": "0.7.2" + } + }, + "node_modules/vue-dual-list/node_modules/express": { + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.15.2.tgz", + "integrity": "sha1-rxB/wUhQRFfy3Kmm8lcdcSm5ezU=", + "dependencies": { + "accepts": "~1.3.3", + "array-flatten": "1.1.1", + "content-disposition": "0.5.2", + "content-type": "~1.0.2", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.1", + "depd": "~1.1.0", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "etag": "~1.8.0", + "finalhandler": "~1.0.0", + "fresh": "0.5.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.1", + "path-to-regexp": "0.1.7", + "proxy-addr": "~1.1.3", + "qs": "6.4.0", + "range-parser": "~1.2.0", + "send": "0.15.1", + "serve-static": "1.12.1", + "setprototypeof": "1.0.3", + "statuses": "~1.3.1", + "type-is": "~1.6.14", + "utils-merge": "1.0.0", + "vary": "~1.1.0" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/vue-dual-list/node_modules/finalhandler": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz", + "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vue-dual-list/node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/vue-dual-list/node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/vue-dual-list/node_modules/fresh": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", + "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/vue-dual-list/node_modules/ipaddr.js": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz", + "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vue-dual-list/node_modules/mime": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", + "bin": { + "mime": "cli.js" + } + }, + "node_modules/vue-dual-list/node_modules/ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" + }, + "node_modules/vue-dual-list/node_modules/proxy-addr": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz", + "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=", + "dependencies": { + "forwarded": "~0.1.0", + "ipaddr.js": "1.4.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/vue-dual-list/node_modules/qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/vue-dual-list/node_modules/send": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.15.1.tgz", + "integrity": "sha1-igI1TCbm9cynAAZfXwzeupDse18=", + "dependencies": { + "debug": "2.6.1", + "depd": "~1.1.0", + "destroy": "~1.0.4", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "etag": "~1.8.0", + "fresh": "0.5.0", + "http-errors": "~1.6.1", + "mime": "1.3.4", + "ms": "0.7.2", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.3.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/vue-dual-list/node_modules/serve-static": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.1.tgz", + "integrity": "sha1-dEOpZePO1kes61Y5+ga/TRu+ADk=", + "dependencies": { + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "parseurl": "~1.3.1", + "send": "0.15.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/vue-dual-list/node_modules/statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/vue-dual-list/node_modules/utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vue-dual-list/node_modules/vue-router": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-2.8.1.tgz", + "integrity": "sha512-MC4jacHBhTPKtmcfzvaj2N7g6jgJ/Z/eIjZdt+yUaUOM1iKC0OUIlO/xCtz6OZFFTNUJs/1YNro2GN/lE+nOXA==" + }, + "node_modules/vue-form-wizard": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/vue-form-wizard/-/vue-form-wizard-0.8.4.tgz", + "integrity": "sha512-/Zk1+B7bz7qHFJ16mwu021lpPXWf/9Tlr2mTNG3J7M0Hdy3rgA802lWsbKYySns0B0qtsD8BYGjQ2Wyxgg+4uw==", + "engines": { + "node": ">= 4.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/vue-functional-data-merge": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vue-functional-data-merge/-/vue-functional-data-merge-2.0.4.tgz", + "integrity": "sha512-Q7OBltO35UEYnRxLcweulhi37/kYVfToqSrsdsbwM5os2DjRB1+k9YKtYcZEdjTUTC+QIqCMjqxggRn1mMoC1w==" + }, + "node_modules/vue-good-table": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/vue-good-table/-/vue-good-table-1.20.2.tgz", + "integrity": "sha512-rSbO2BPAYE5sv2+lWhQdiEdAUVOuXIdEVt2PZJptWPwyUqpaFjUlnhslFtvXVMd0I9dRGI19JovPl8bHSYH71g==", + "dependencies": { + "babel-runtime": "^6.26.0", + "date-fns": "^2.0.0-alpha.7", + "diacriticless": "1.0.1", + "lodash.clone": "^4.5.0", + "lodash.foreach": "^4.5.0" + }, + "engines": { + "node": ">= 4.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/vue-good-table/node_modules/lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" + }, + "node_modules/vue-hot-reload-api": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.2.4.tgz", + "integrity": "sha512-e+ThJMYmZg4D9UnrLcr6LQxGu6YlcxkrmZGPCyIN4malcNhdeGGKxmFuM5y6ICMJJxQywLfT8MM1rYZr4LpeLw==", + "dev": true + }, + "node_modules/vue-jest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vue-jest/-/vue-jest-1.4.0.tgz", + "integrity": "sha512-X5YXTXcpklijK3wXG/CiW8Frkz+YPBjR+//FD5rcmlnmEelz+8AQpKA8vhbAHJx3gOhA2tkWt8XEjvxq1S0heg==", + "dev": true, + "dependencies": { + "babel-core": "^6.25.0", + "babel-preset-vue-app": "^1.3.1", + "chalk": "^2.1.0", + "find-babel-config": "^1.1.0", + "js-beautify": "^1.6.14", + "node-cache": "^4.1.1", + "object-assign": "^4.1.1", + "source-map": "^0.5.6", + "tsconfig": "^7.0.0", + "vue-template-es2015-compiler": "^1.5.3" + }, + "peerDependencies": { + "vue": "^2.x", + "vue-template-compiler": "^2.x" + } + }, + "node_modules/vue-jest/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue-json-excel": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/vue-json-excel/-/vue-json-excel-0.1.7.tgz", + "integrity": "sha1-yezD33O7dh9IEHaxfE9H+cj+iC8=", + "dependencies": { + "downloadjs": "^1.4.7" + } + }, + "node_modules/vue-loader": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-13.7.0.tgz", + "integrity": "sha512-kDXRgglOOltghngrDFS/YfFew7e0d8fkvPHLYAfLgur7GW0cBt+J0fpBReWY2pixA09dL13abfE4fECyRH4HGg==", + "dev": true, + "dependencies": { + "consolidate": "^0.14.0", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "lru-cache": "^4.1.1", + "postcss": "^6.0.8", + "postcss-load-config": "^1.1.0", + "postcss-selector-parser": "^2.0.0", + "prettier": "^1.7.0", + "resolve": "^1.4.0", + "source-map": "^0.6.1", + "vue-hot-reload-api": "^2.2.0", + "vue-style-loader": "^3.0.0", + "vue-template-es2015-compiler": "^1.6.0" + }, + "peerDependencies": { + "css-loader": "*", + "vue-template-compiler": "^2.0.0" + } + }, + "node_modules/vue-material": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/vue-material/-/vue-material-0.7.5.tgz", + "integrity": "sha512-MRtEeeOnMBVxaVoGoXcwupgdxqa3DyGDGXAA/7wzMRgQ4dWFNTlaS+p5434068dBJT7EofZe5La/ONKYivL2XQ==", + "peerDependencies": { + "vue": "^2.4.2" + } + }, + "node_modules/vue-materialize-datatable": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/vue-materialize-datatable/-/vue-materialize-datatable-0.7.3.tgz", + "integrity": "sha512-qOVaUPfNbmBFzZgHYsWl8n2XwsG4H1Y2yz9U0pdm/wcbNeN1lcfcAhCEq5A0a3AaxdefETnk01ndjw60iT9ixg==", + "dependencies": { + "babel-runtime": "^6.0.0", + "fuse.js": "^2.6.2", + "vue": "^1.0.21" + } + }, + "node_modules/vue-materialize-datatable/node_modules/vue": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/vue/-/vue-1.0.28.tgz", + "integrity": "sha1-7S/weyAL3hXIepDvhyfO6n04Vn0=", + "dependencies": { + "envify": "^3.4.0" + } + }, + "node_modules/vue-mover": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/vue-mover/-/vue-mover-0.3.0.tgz", + "integrity": "sha512-/gfhHVMKkCwB/0dkNh7f2ArC8lIaCyanJGNYOnvszZYSFdPsL+AyL/4iudjR07ciHYc7KWtlMl9z755KfxMZSA==", + "dependencies": { + "sortablejs": "^1.6.1", + "vue": "^2.4.4" + } + }, + "node_modules/vue-multiselect": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-2.0.8.tgz", + "integrity": "sha512-OKdWOwCLXiDGHVaYqWZXx4s2YNqOmfIqFMTd0Y3SzCcFIp19d7UeLB4UVZvIHammzMX4qrQ3yAzNHJmE0ApgHA==", + "engines": { + "node": ">= 4.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/vue-resource": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/vue-resource/-/vue-resource-1.3.5.tgz", + "integrity": "sha512-m9UC5q0Mcd6MphEVVPCeC609XrsWHatmT39UKhE3oQz1GojnjbyReU1ggX9uQqM6FB81XXFX/GU28yMHJ69O7w==", + "dependencies": { + "got": "^7.1.0" + } + }, + "node_modules/vue-resource-mock": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/vue-resource-mock/-/vue-resource-mock-0.0.8.tgz", + "integrity": "sha512-E8v11UZxX6SmVSdEKX9vAhxyCTs+w7wFK/qVIuLZkCBrAPJ7YOc2zOOF3gFPBlok9bUJ/1wjW/zj2XgXf9VhaA==", + "dependencies": { + "qs": "^6.3.0", + "url-pattern": "^1.0.3" + }, + "peerDependencies": { + "vue-resource": "^0.9.x || ^1.x" + } + }, + "node_modules/vue-router": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.1.tgz", + "integrity": "sha512-vLLoY452L+JBpALMP5UHum9+7nzR9PeIBCghU9ZtJ1eWm6ieUI8Zb/DI3MYxH32bxkjzYV1LRjNv4qr8d+uX/w==" + }, + "node_modules/vue-select": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/vue-select/-/vue-select-2.4.0.tgz", + "integrity": "sha512-WxQc7t65ht3YSwSgcSdHFU8cSOWKpvH6n1B/Z9ua44hMB2oVcy0Mieu4qjMPrYx3AQQ8Y8F+pfNIylRZ0t3IVA==", + "peerDependencies": { + "vue": "2.x" + } + }, + "node_modules/vue-strap": { + "version": "1.1.40", + "resolved": "https://registry.npmjs.org/vue-strap/-/vue-strap-1.1.40.tgz", + "integrity": "sha1-CRGDz66p5Fbop6CSudxpeowYQwI=", + "dependencies": { + "bootstrap": "^3.3.7", + "vue": "^1.0.26" + } + }, + "node_modules/vue-strap/node_modules/bootstrap": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.3.7.tgz", + "integrity": "sha1-WjiTlFSfIzMIdaOxUGVldPip63E=", + "engines": { + "node": ">=0.10.1" + } + }, + "node_modules/vue-strap/node_modules/vue": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/vue/-/vue-1.0.28.tgz", + "integrity": "sha1-7S/weyAL3hXIepDvhyfO6n04Vn0=", + "dependencies": { + "envify": "^3.4.0" + } + }, + "node_modules/vue-style-loader": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-3.0.3.tgz", + "integrity": "sha512-P/ihpaZKU23T1kq3E0y4c+F8sbm1HQO69EFYoLoGMSGVAHroHsGir/WQ9qUavP8dyFYHmXenzHaJ/nqd8vfaxw==", + "dev": true, + "dependencies": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + } + }, + "node_modules/vue-template-compiler": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.5.13.tgz", + "integrity": "sha512-15HWSgIxrGUcV0v7QRen2Y3fQsbgxXwMvjT/5XKMO0ANmaCcNh7y2OeIDTAuSGeosjb9+E1Pn2PHZ61VQWEgBQ==", + "dev": true, + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "node_modules/vue-template-es2015-compiler": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz", + "integrity": "sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==", + "dev": true + }, + "node_modules/vue-xlsx-table": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/vue-xlsx-table/-/vue-xlsx-table-1.2.8.tgz", + "integrity": "sha512-shvWAgdc6jozucmEoeCoBLBL3x9t9AYrTnJdP6lr56UTs6HEnt8bzzstWh31nGP3dKEXHZVzsy9bBAMPCLSvZQ==", + "dependencies": { + "xlsx": "^0.9.3" + } + }, + "node_modules/vue-xlsx-table-components": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vue-xlsx-table-components/-/vue-xlsx-table-components-1.0.1.tgz", + "integrity": "sha1-M77rME1C646FHLTeEZvI1NYpvWo=", + "dependencies": { + "vue": "^2.4.4", + "xlsx": "^0.9.3" + } + }, + "node_modules/vue2-autocomplete-js": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/vue2-autocomplete-js/-/vue2-autocomplete-js-0.2.2.tgz", + "integrity": "sha1-t6GILZeMsJJbuHjV6g3UdVomH5U=", + "dependencies": { + "vue": "^2.4.2" + } + }, + "node_modules/vue2-datatable-component": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/vue2-datatable-component/-/vue2-datatable-component-2.2.2.tgz", + "integrity": "sha1-Jlb71msAQzHlqbChsfDEWh5c8tU=", + "dependencies": { + "lodash": "^4.17.4" + } + }, + "node_modules/vuetable-2": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/vuetable-2/-/vuetable-2-1.7.2.tgz", + "integrity": "sha512-9DRNDGt4qNhVdYs+5Vcc9B/8TwUsoEeXq1W7rDgazbkX2BqdZoV3DaZ/H6QbO2xlHBXZiwJcjPQ1k4qMe48R4w==", + "dependencies": { + "axios": "^0.15.3" + }, + "engines": { + "node": ">= 4.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/vuetable-2/node_modules/axios": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz", + "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", + "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", + "dependencies": { + "follow-redirects": "1.0.0" + } + }, + "node_modules/vuetable-2/node_modules/follow-redirects": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", + "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", + "dependencies": { + "debug": "^2.2.0" + } + }, + "node_modules/vuetify": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-1.0.11.tgz", + "integrity": "sha512-R+wi3AnT1OCbHLhbZWlKUZmiamS+6jAy0gPTbtmRFXJOXWTV5DGMSyRWktjrpq6pxEEdEaJyGmOeurPYmnGxmg==", + "engines": { + "node": ">= 4.0.0", + "npm": ">= 3.0.0" + }, + "peerDependencies": { + "vue": "^2.5.0" + } + }, + "node_modules/walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "dependencies": { + "makeerror": "1.0.x" + } + }, + "node_modules/watch": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", + "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", + "dev": true, + "dependencies": { + "exec-sh": "^0.2.0", + "minimist": "^1.2.0" + }, + "bin": { + "watch": "cli.js" + }, + "engines": { + "node": ">=0.1.95" + } + }, + "node_modules/watch/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node_modules/watchpack": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", + "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", + "dev": true, + "dependencies": { + "async": "^2.1.2", + "chokidar": "^1.7.0", + "graceful-fs": "^4.1.2" + } + }, + "node_modules/wbuf": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz", + "integrity": "sha1-1pe5nx9ZUS3ydRvkJ2nBWAtYAf4=", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/webpack": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz", + "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==", + "dev": true, + "dependencies": { + "acorn": "^5.0.0", + "acorn-dynamic-import": "^2.0.0", + "ajv": "^5.1.5", + "ajv-keywords": "^2.0.0", + "async": "^2.1.2", + "enhanced-resolve": "^3.4.0", + "escope": "^3.6.0", + "interpret": "^1.0.0", + "json-loader": "^0.5.4", + "json5": "^0.5.1", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "mkdirp": "~0.5.0", + "node-libs-browser": "^2.0.0", + "source-map": "^0.5.3", + "supports-color": "^4.2.1", + "tapable": "^0.2.7", + "uglifyjs-webpack-plugin": "^0.4.6", + "watchpack": "^1.4.0", + "webpack-sources": "^1.0.1", + "yargs": "^8.0.2" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.9.2.tgz", + "integrity": "sha1-Y+2G63HMTNqG9o5oWoRTC6ASZEk=", + "dev": true, + "dependencies": { + "acorn": "^5.1.1", + "chalk": "^1.1.3", + "commander": "^2.9.0", + "ejs": "^2.5.6", + "express": "^4.15.2", + "filesize": "^3.5.9", + "gzip-size": "^3.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "opener": "^1.4.3", + "ws": "^4.0.0" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz", + "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==", + "dev": true, + "dependencies": { + "memory-fs": "~0.4.1", + "mime": "^1.5.0", + "path-is-absolute": "^1.0.0", + "range-parser": "^1.0.3", + "time-stamp": "^2.0.0" + }, + "engines": { + "node": ">=0.6" + }, + "peerDependencies": { + "webpack": "^1.0.0 || ^2.0.0 || ^3.0.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.10.1.tgz", + "integrity": "sha512-R9iZOrbIIsP2mw2j172HVjf479Zb9kcG0chjzHRrE/4M333NZ+3jOWRWJMGEQXwJzUtRNvVKzX2o27qM59TIhQ==", + "dev": true, + "dependencies": { + "ansi-html": "0.0.7", + "array-includes": "^3.0.3", + "bonjour": "^3.5.0", + "chokidar": "^2.0.0", + "compression": "^1.5.2", + "connect-history-api-fallback": "^1.3.0", + "debug": "^3.1.0", + "del": "^3.0.0", + "express": "^4.16.2", + "html-entities": "^1.2.0", + "http-proxy-middleware": "~0.17.4", + "import-local": "^1.0.0", + "internal-ip": "1.2.0", + "ip": "^1.1.5", + "killable": "^1.0.0", + "loglevel": "^1.4.1", + "opn": "^5.1.0", + "portfinder": "^1.0.9", + "selfsigned": "^1.9.1", + "serve-index": "^1.7.2", + "sockjs": "0.3.19", + "sockjs-client": "1.1.4", + "spdy": "^3.4.1", + "strip-ansi": "^4.0.0", + "supports-color": "^5.1.0", + "webpack-dev-middleware": "1.12.2", + "yargs": "6.6.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">=4.7" + }, + "peerDependencies": { + "webpack": "^2.2.0 || ^3.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-dev-server/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/webpack-dev-server/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/braces": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz", + "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.0.tgz", + "integrity": "sha512-OgXCNv2U6TnG04D3tth0gsvdbV4zdbxFG3sYUqcoQMoEFVd1j1pZR6TZ8iknC45o9IJ6PeQI/J6wT/+cHcniAw==", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + }, + "optionalDependencies": { + "fsevents": "^1.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/cliui/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/cliui/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/extglob": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.3.tgz", + "integrity": "sha512-AyptZexgu7qppEPq59DtN/XJGZDrLcVxSHai+4hdgMMS9EpF4GBvygcWWApno8lL9qSjVpYt7Raao28qzJX1ww==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "deprecated": "Please upgrade to v0.1.7", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "deprecated": "Please upgrade to v0.1.5", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/micromatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.5.tgz", + "integrity": "sha512-ykttrLPQrz1PUJcXjwsTUjGoPJ64StIGNE2lGVD1c9CuguJ+L7/navsE8IcDNndOoCMvYV0qc/exfVbMHkUhvA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.0", + "define-property": "^1.0.0", + "extend-shallow": "^2.0.1", + "extglob": "^2.0.2", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.0", + "nanomatch": "^1.2.5", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-dev-server/node_modules/which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^4.2.0" + } + }, + "node_modules/webpack-dev-server/node_modules/yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0" + } + }, + "node_modules/webpack-merge": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.1.tgz", + "integrity": "sha512-geQsZ86YkXOVOjvPC5yv3JSNnL6/X3Kzh935AQ/gJNEYXEfJDQFu/sdFuktS9OW2JcH/SJec8TGfRdrpHshH7A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.4" + } + }, + "node_modules/webpack-sources": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true, + "peerDependencies": { + "ajv": "^5.0.0" + } + }, + "node_modules/webpack/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/string-width/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "dependencies": { + "has-flag": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "dependencies": { + "source-map": "~0.5.1", + "yargs": "~3.10.0" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + }, + "optionalDependencies": { + "uglify-to-browserify": "~1.0.0" + } + }, + "node_modules/webpack/node_modules/uglify-js/node_modules/yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "dependencies": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + }, + "node_modules/webpack/node_modules/uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "source-map": "^0.5.6", + "uglify-js": "^2.8.29", + "webpack-sources": "^1.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + }, + "peerDependencies": { + "webpack": "^1.9 || ^2 || ^2.1.0-beta || ^2.2.0-rc || ^3.0.0" + } + }, + "node_modules/webpack/node_modules/yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + }, + "node_modules/webpack/node_modules/yargs/node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/yargs/node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/webpack/node_modules/yargs/node_modules/cliui/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", + "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.19" + } + }, + "node_modules/whatwg-url": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", + "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/whatwg-url/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "node_modules/whet.extend": { + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", + "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=", + "dev": true, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/worker-farm": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.2.tgz", + "integrity": "sha512-XxiQ9kZN5n6mmnW+mFJ+wXjNNI/Nx4DIdaAKLX1Bn6LYBWlN/zaBhu34DQYPZ1AJobQuu67S2OfDdNSVULvXkQ==", + "dev": true, + "dependencies": { + "errno": "^0.1.4", + "xtend": "^4.0.1" + } + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/write-file-atomic": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/ws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-4.0.0.tgz", + "integrity": "sha512-QYslsH44bH8O7/W2815u5DpnCpXWpEK44FmaHffNwgJI4JMaSZONgPBTOfrxJ29mXKbXak+LsJ2uAkDTYq2ptQ==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/xlsx": { + "version": "0.9.13", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.9.13.tgz", + "integrity": "sha1-WGHRHhCh+ZtvK0keLRGad3fQZuc=", + "deprecated": "this version is no longer supported. More info at https://cdn.sheetjs.com/xlsx/", + "dependencies": { + "adler-32": "~1.0.0", + "cfb": "~0.11.1", + "codepage": "~1.8.0", + "commander": "~2.9.0", + "crc-32": "~1.0.2", + "exit-on-epipe": "~1.0.0", + "ssf": "~0.9.1" + }, + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/xlsx/node_modules/commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dependencies": { + "graceful-readlink": ">= 1.0.0" + }, + "engines": { + "node": ">= 0.6.x" + } + }, + "node_modules/xml-char-classes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz", + "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", + "dev": true + }, + "node_modules/xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/xxhashjs": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.1.tgz", + "integrity": "sha1-m76b6JYUKXbfo0wGGy0GjEPTDeA=", + "dev": true, + "dependencies": { + "cuint": "latest" + } + }, + "node_modules/y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "node_modules/yargs": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", + "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + }, + "node_modules/yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0" + } + }, + "node_modules/yargs-parser/node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/yargs/node_modules/cliui/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/string-width/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "dependencies": { + "fd-slicer": "~1.0.1" + } + } + } +} diff --git a/rql-ui/package.json b/rql-ui/package.json new file mode 100644 index 0000000..58a35a0 --- /dev/null +++ b/rql-ui/package.json @@ -0,0 +1,116 @@ +{ + "name": "rql-ui", + "version": "1.1.0-SNAPSHOT", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "unit": "jest --config test/unit/jest.conf.js --coverage", + "e2e": "node test/e2e/runner.js", + "test": "npm run unit && npm run e2e", + "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs", + "build": "node build/build.js" + }, + "dependencies": { + "axios": "^0.18.0", + "bootstrap": "^4.0.0-beta.3", + "bootstrap-vue": "^1.4.1", + "jquery-mobile": "^1.5.0-alpha.1", + "material-design-icons-iconfont": "^3.0.3", + "mockjs": "^1.0.1-beta3", + "moment": "^2.21.0", + "semantic-ui-css": "^2.2.12", + "sortable": "^2.0.0", + "vue": "^2.5.2", + "vue-carousel": "^0.6.5", + "vue-clip": "^1.0.0", + "vue-dual-list": "^1.0.0", + "vue-form-wizard": "^0.8.4", + "vue-good-table": "^1.20.2", + "vue-json-excel": "^0.1.7", + "vue-materialize-datatable": "^0.7.3", + "vue-mover": "^0.3.0", + "vue-multiselect": "^2.0.8", + "vue-resource": "^1.3.5", + "vue-resource-mock": "0.0.8", + "vue-router": "^3.0.1", + "vue-select": "^2.4.0", + "vue-strap": "^1.1.40", + "vue-xlsx-table": "^1.2.8", + "vue-xlsx-table-components": "^1.0.1", + "vue2-autocomplete-js": "^0.2.2", + "vue2-datatable-component": "^2.2.2", + "vuetable-2": "^1.7.2", + "vuetify": "^1.0.11" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-eslint": "^7.1.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-jest": "^21.0.2", + "babel-loader": "^7.1.1", + "babel-plugin-dynamic-import-node": "^1.2.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "babel-register": "^6.22.0", + "chalk": "^2.0.1", + "chromedriver": "^2.27.2", + "copy-webpack-plugin": "^4.0.1", + "cross-spawn": "^5.0.1", + "css-loader": "^0.28.0", + "eslint": "^3.19.0", + "eslint-config-standard": "^10.2.1", + "eslint-friendly-formatter": "^3.0.0", + "eslint-loader": "^1.7.1", + "eslint-plugin-html": "^3.0.0", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-node": "^5.2.0", + "eslint-plugin-promise": "^3.4.0", + "eslint-plugin-standard": "^3.0.1", + "extract-text-webpack-plugin": "^3.0.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^2.30.1", + "jest": "^21.2.0", + "jest-serializer-vue": "^0.3.0", + "jquery": "^1.12.4", + "nightwatch": "^0.9.12", + "node-notifier": "^5.1.2", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "selenium-server": "^3.0.1", + "semver": "^5.3.0", + "shelljs": "^0.7.6", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-jest": "^1.0.2", + "vue-loader": "^13.3.0", + "vue-style-loader": "^3.0.1", + "vue-template-compiler": "^2.5.2", + "webpack": "^3.6.0", + "webpack-bundle-analyzer": "^2.9.0", + "webpack-dev-server": "^2.9.1", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/rql-ui/src/App.vue b/rql-ui/src/App.vue new file mode 100644 index 0000000..7a16f2a --- /dev/null +++ b/rql-ui/src/App.vue @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/rql-ui/src/assets/RQL.css b/rql-ui/src/assets/RQL.css new file mode 100644 index 0000000..622d426 --- /dev/null +++ b/rql-ui/src/assets/RQL.css @@ -0,0 +1,516 @@ +fieldset[disabled] .multiselect { + pointer-events: none + } + + .multiselect__spinner { + position: absolute; + right: 1px; + top: 1px; + width: 48px; + height: 35px; + background: #fff; + display: block + } + + .multiselect__spinner:after, + .multiselect__spinner:before { + position: absolute; + content: ""; + top: 50%; + left: 50%; + margin: -8px 0 0 -8px; + width: 16px; + height: 16px; + border-radius: 100%; + border-color: #08a4ff transparent transparent; + border-style: solid; + border-width: 2px; + box-shadow: 0 0 0 1px transparent + } + + .multiselect__spinner:before { + animation: a 2.4s cubic-bezier(.41, .26, .2, .62); + animation-iteration-count: infinite + } + + .multiselect__spinner:after { + animation: a 2.4s cubic-bezier(.51, .09, .21, .8); + animation-iteration-count: infinite + } + + .multiselect__loading-enter-active, + .multiselect__loading-leave-active { + transition: opacity .4s ease-in-out; + opacity: 1 + } + + .multiselect__loading-enter, + .multiselect__loading-leave-active { + opacity: 0 + } + + .multiselect, + .multiselect__input, + .multiselect__single { + font-family: inherit; + font-size: 8pt; + -ms-touch-action: manipulation; + touch-action: manipulation + } + + .multiselect { + box-sizing: content-box; + display: block; + position: relative; + width: 100%; + min-height: 40px; + text-align: left; + color: #35495e + } + + .multiselect * { + box-sizing: border-box + } + + .multiselect:focus { + outline: none + } + + .multiselect--disabled { + opacity: .6 + } + + .multiselect--active { + z-index: 1 + } + + .multiselect--active:not(.multiselect--above) .multiselect__current, + .multiselect--active:not(.multiselect--above) .multiselect__input, + .multiselect--active:not(.multiselect--above) .multiselect__tags { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0 + } + + .multiselect--active .multiselect__select { + transform: rotate(180deg) + } + + .multiselect--above.multiselect--active .multiselect__current, + .multiselect--above.multiselect--active .multiselect__input, + .multiselect--above.multiselect--active .multiselect__tags { + border-top-left-radius: 0; + border-top-right-radius: 0 + } + + .multiselect__input, + .multiselect__single { + position: relative; + display: inline-block; + min-height: 30px; + line-height: 20px; + border: none; + border-radius: 5px; + background: #fff; + padding: 0 0 0 5px; + width: 100%; + transition: border .1s ease; + box-sizing: border-box; + margin-bottom: 8px; + vertical-align: top + } + + .multiselect__tag~.multiselect__input, + .multiselect__tag~.multiselect__single { + width: auto + } + + .multiselect__input:hover, + .multiselect__single:hover { + border-color: #cfcfcf + } + + .multiselect__input:focus, + .multiselect__single:focus { + border-color: #a8a8a8; + outline: none + } + + .multiselect__single { + padding-left: 6px; + margin-bottom: 8px + } + + .multiselect__tags-wrap { + display: inline + } + + .multiselect__tags { + max-height: 80px; + display: block; + padding: 8px 40px 0 8px; + border-radius: 5px; + border: 1px solid #e8e8e8; + background: #fff; + overflow: auto; + } + + .multiselect__tag { + position: relative; + display: inline-block; + padding: 4px 26px 4px 10px; + border-radius: 5px; + margin-right: 10px; + color: #fff; + line-height: 1; + background: #009688; + margin-bottom: 5px; + white-space: nowrap; + overflow: hidden; + max-width: 100%; + text-overflow: ellipsis + } + + .multiselect__tag-icon { + cursor: pointer; + margin-left: 7px; + position: absolute; + right: 0; + top: 0; + bottom: 0; + font-weight: 700; + font-style: normal; + width: 22px; + text-align: center; + line-height: 22px; + transition: all .2s ease; + border-radius: 5px + } + + .multiselect__tag-icon:after { + content: "\D7"; + color: #fff; + font-size: 14px + } + + .multiselect__tag-icon:focus, + .multiselect__tag-icon:hover { + background: #009688 + } + + .multiselect__tag-icon:focus:after, + .multiselect__tag-icon:hover:after { + color: #fff + } + + .multiselect__current { + min-height: 40px; + overflow: hidden; + padding: 8px 12px 0; + padding-right: 30px; + white-space: nowrap; + border-radius: 5px; + border: 1px solid #e8e8e8 + } + + .multiselect__current, + .multiselect__select { + line-height: 16px; + box-sizing: border-box; + display: block; + margin: 0; + text-decoration: none; + cursor: pointer + } + + .multiselect__select { + position: absolute; + width: 40px; + height: 38px; + right: 1px; + top: 1px; + padding: 4px 8px; + text-align: center; + transition: transform .2s ease + } + + .multiselect__select:before { + position: relative; + right: 0; + top: 65%; + color: #999; + margin-top: 4px; + border-style: solid; + border-width: 5px 5px 0; + border-color: #999 transparent transparent; + content: "" + } + + .multiselect__placeholder { + color: #adadad; + display: inline-block; + margin-bottom: 10px; + padding-top: 2px + } + + .multiselect--active .multiselect__placeholder { + display: none + } + + .multiselect__content-wrapper { + position: absolute; + display: block; + background: #fff; + width: 100%; + max-height: 240px; + overflow: auto; + border: 1px solid #e8e8e8; + border-top: none; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + z-index: 1; + -webkit-overflow-scrolling: touch + } + + .multiselect__content { + list-style: none; + display: inline-block; + padding: 0; + margin: 0; + min-width: 100%; + vertical-align: top + } + + .multiselect--above .multiselect__content-wrapper { + bottom: 100%; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + border-bottom: none; + border-top: 1px solid #e8e8e8 + } + + .multiselect__content::webkit-scrollbar { + display: none + } + + .multiselect__element { + display: block + } + + .multiselect__option { + display: block; + padding: 12px; + min-height: 40px; + line-height: 16px; + text-decoration: none; + text-transform: none; + vertical-align: middle; + position: relative; + cursor: pointer; + white-space: nowrap + } + + .multiselect__option:after { + top: 0; + right: 0; + position: absolute; + line-height: 40px; + padding-right: 12px; + padding-left: 20px + } + + .multiselect__option--highlight { + background: #009688; + outline: none; + color: #fff + } + + .multiselect__option--highlight:after { + content: attr(data-select); + background: #009688; + color: #fff + } + + .multiselect__option--selected { + background: #f3f3f3; + color: #355e46; + font-weight: 700 + } + + .multiselect__option--selected:after { + content: attr(data-selected); + color: silver + } + + .multiselect__option--selected.multiselect__option--highlight { + background: #ff6a6a; + color: #fff + } + + .multiselect__option--selected.multiselect__option--highlight:after { + background: #ff6a6a; + content: attr(data-deselect); + color: #fff + } + + .multiselect--disabled { + background: #ededed; + pointer-events: none + } + + .multiselect--disabled .multiselect__current, + .multiselect--disabled .multiselect__select, + .multiselect__option--disabled { + background: #ededed; + color: #a6a6a6 + } + + .multiselect__option--disabled { + cursor: text; + pointer-events: none + } + + .multiselect__option--disabled.multiselect__option--highlight { + background: #dedede!important + } + + .multiselect-enter-active, + .multiselect-leave-active { + transition: all .15s ease + } + + .multiselect-enter, + .multiselect-leave-active { + opacity: 0 + } + + .multiselect__strong { + margin-bottom: 8px; + line-height: 20px; + display: inline-block; + vertical-align: top + } + + [dir=rtl] .multiselect { + text-align: right + } + + [dir=rtl] .multiselect__select { + right: auto; + left: 1px + } + + [dir=rtl] .multiselect__tags { + padding: 8px 8px 0 40px + } + + [dir=rtl] .multiselect__content { + text-align: right + } + + [dir=rtl] .multiselect__option:after { + right: auto; + left: 0 + } + + [dir=rtl] .multiselect__clear { + right: auto; + left: 12px + } + + [dir=rtl] .multiselect__spinner { + right: auto; + left: 1px + } + @keyframes a { + 0% { + transform: rotate(0) + } + to { + transform: rotate(2turn) + } + } + + .loader { + border: 16px solid #f3f3f3; + border-radius: 50%; + border-top: 16px solid #424242; + width: 120px; + height: 120px; + -webkit-animation: spin 2s linear infinite; + /* Safari */ + animation: spin 2s linear infinite; + margin: auto; + margin-top: 2%; + + } + + @-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + } + } + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + .select-style { + border: 1.2px solid #233; + border-radius: 2px; + overflow: hidden; + height: 30px; + font-size: 10pt; + font-weight: bold; + color: #fff; + background-color: #007aff; + } + + .select-style select { + padding: 5px 8px; + width: 130%; + border: none; + box-shadow: none; + background: transparent; + background-image: none; + -webkit-appearance: none; + } + + .select-style select:focus { + outline: none; + } + + option[disabled] { + color: #000001; + background-color: #fff; + font-size: 9pt; + font-weight: bold; + border: 5px; + border: #000001; + } + .rqlError{ + margin-left:5%; + margin-top: 20px; + background-color:#CD3645; + color:#fff + } + .sqlError { + margin-left: 5%; + margin-right: 5%; + background-color: #CD3645; + color: #fff; + } + b-list-group-item{ + font-size: 8pt; + } + .no-margin-top { + margin-top:0% + } diff --git a/rql-ui/src/assets/bg.jpg b/rql-ui/src/assets/bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..73d4f2340bfceac34604227cb3e6c84ca71b354a GIT binary patch literal 246648 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 z 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%0Dh^ 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%0DkSG5g{5!@P=}|98DfAm-?AI7xE#2wOGB63C=jz z?@r({h?mhL5X|FHy;J>Z{Ij^=_kVeNi+IP$!_3^Sen%qruX76D(P$7mL_iho1B166 zS8jNmrl{=`X~l}QJ-uINl_Fi=g3Va#kIV;}iIS=&{zPJq-31r*-xXqXse z^i(vO)c7Eei;g-nC7M+{E7Md~en#noi+VWsGDP!b_%LinSF#D|YS5IvNY1q}HeYsb zgnn0NhR=^8<1cobOpbBJvSmN~Qi{!|mr;rOb%P)$?hVr`e2`--Vt*@$I(jxpG9U3s ztaaXdS^4kzb{Lj6y{f>)+i>jSScaByt;XDc`alJ8zpwD=IKsJ^aF3;}jtx`$mpk39 z$tR^5-g?NH9%QO{p^Wn|ocP6Et$8P;C~i~3)N{;KBB zaeLD@rT$}2g2h=5>;ix{g3c&*hD%e?q#~l2pg$FkrpEZ|>s%MVuw{|4WM8u%`;EGA z%&>U9qUYij{Abs#Pv7+Wa>d8L44iy?n`CxmLNkdRq#b+ScE-h?cE53K+0vJ7yO+N! zk;~J_`awPt?JCRV%k}jy@cKP>P(?UujQTwSK#&4iK-W(IJL;Mes{s^{Bn1;m3qfTI zMHHw|D)7-1o0=g2$O;8TqX|n)1p#5n6w=;k7(=oGf;0%T6cEUYx${}pr-gf$;y8kN z1YA}kS2)o_*~1ud3aR4EBV9_k5vG*rm>`*Ms->EU$bfhb0TmIEC6vHBo2gYTG|1>m zFlm=MAZg{r1V>VW6Q~FX2n#ol1QC+ld{&@ucB+Dmk_T`UQi9+jhj>Be{{H~H+fHEr z0Mn59DO&5(;wA(I6g8WjgJ-rx0j7&KH_d#d`mvLD4)wffOSU%&GGnU8%he`xuL8Yvl50Y= z%H3ZX=8X)|U zVc@ze>8LT)dR`RWLGxLl6VqNRmrl_nS+!D8Fs{0-3GQC>_T0NNv}FsVdUpp2b?CWw z;KwN}{Fp@BnHQnLHv_kw3iH~yp)8nOCMF^P=m9PBQ&nFhJ0M0j;N6f62ZunVxF{U_ zf%xr$4JcdfS=C}@eseP8O5u%@LkO1p6_pZN+pJmwMj}!litOrsXt7h^8tcCiAif^2+ykh$tym<%2;;{8wyg5>XsLI!b%;+GGKkr!i-Khm6H zB7Y1(f0DW;HgS#EVox62tO>?O(1;NvR-i2Jk=fggtC*6N`+rIL4Y?1ZLzizQS5+=f zd9se*hdARx-IHq`H4%tzK~J*R6?b62u+Jh{Fpb#Si8gNm^jwkC=DKm_v4M^5UGM$6 z)sb>GWsPulWC8V<$3RJ;1Hp9qM@cc)$A8;1@~uYcJ7vt9Q8#@_30X1&>LOI_2a#NQ z{I9}T=;ePF%&p^J-En1Z^|!Nj5*H%?)b22FAA;e39r;*qYZ)D2EL>Hv|#~YL`Zm1H^eCcrB;FU_5*e0D?im!#1cT z9SRAeU0;zfB8Q5B!{@~VgFoDY&A$)5UxA}*gV3ln;9Xi2i;aBL5lFc}0Qj;A8l4a{ zhbE{PP(v;+@j(Hn4H14!I-ih5FW4Y(`xDT0Da`}p$D*AHJ`bwMk^ss=5e8E>-c{>CTZWMF9)qXmRD0(=6{{WjJ;{rSi zdR(m=cYVQjJ(%*s_O>*rZQw)mIYfV&{m>#0gi6h;ksLNHzttHzak;wXg8u-U+%6oM zgZ@!JqCfJ)DQ%{DR6Vy~V!d z=Yv^o_+R!o-UPs#vmP@G7ra@`z8#j?w(MIKqhn~>@%H$CJaO%a%3txweNz7bn66j# zZhm;Pb24@90t23>3Ci(Pec~c>r->6-`GGk$8b_**)45M@*)) zZ0y(WG_OmtKhvl2T_@#Py)|rYc(!ZX-!5nNb-Bch-nC|T@$th-QGnqH>+lO!$cnSf zxjI?1+Y_bBl=*70d;S*{G7YK#WC8}60ii&{a8*jbRcn{y5NlOEwLC>R%JtvF^n=HWgt}#{N%uU7Jy2-I z5rjZB=(UMylAHNx0<8Nn=#5Vi1g6|s8ZpGUxkR%|vBxA-GJ|PE5cd3dqaRZ3MUw!= zoY61vZ)zcuiRG#YyEvL4aBd|73JAL=HK>HPBP$MdG2qQN+d{hh%BATx= z{X`<((UwWCVQ+%VUEdFjGf(#36?E0Dlk*14Edz20w&`A;yNC@PD469;r zkQ_xBO&==$vF$Rs56#9eD+lU57Cv6SF7uC=Zcvw^tlwzI%^A{vBvg@eK~xd}TA;E6 zB%;0l03A?LAQD*_2LAvA1-S7*!^Hq2%>xe<3&&IhRsKj1LV*n{$BF>x7f*@-_h^9v z{7?=&`Jh!lax`#e@J35e$O;Doq6cuVk_EsM!2$h>2WeBU1P+d$Y8CYCb=RY>OU9G} zz;fcH4I#QW70ahscr3*6`xX^qH3Q_d4rFe|&!7nqm(@4Wk;pDR*kh5(wM1bo=V8FsmgPZ0%DQi z6B@hKITkUB5av_7BB$bL@qebe&G5 zv-}rce@{M5dH&_?oc*UO9~&scCe_3Jtea+rFsTe`D@v~1-?HwY&bf0MbAwypC(;7Q_vQ4;rEdb?rHuTgeq=?wB%Yee z)3G+o{D!S4Ll;c(xOKjn8Kj?i;f1BwU~LodW~I#bWha@P_5{FU2!1nh${c)=g8MM`$2usw?`J zZvOzM6EVc__~?S|ov$wYN`Kpd{kZ<+x%t}7>8)dC$FzH<_ar}UO;<_z#(wps{fu~@ z!DMmZPw!jt5mI^JxUp(iPxYUsKQ)`*@VKoxWL^INQul0l!reZ4tXpc~v9)dm;}HJ< z)M|bzV0wUn=mG?RYJd>v8bdiO0M;6|NyCc+pOmmE|_dTLV>f7=?YXJWM^@Ur!-6_ zZw_dpbSM~gKoAB!5JfF0f&yd~8?#W{ydf7Qf*7eBiQOby1jm{cZq6ws_WM6eigMs3qOcE??|i!#t1#0G^a67+b@t1XX|y zO4SoY{IpZxU9(a-sYlcwqcCiHk{oVTBQyU1YWivhgTZNPU_v3ns3ZcY2pS-C^gRL( zC->&f4aW-nOdq->%EPzk*O$Wkwj}U#vN5L~({5x3XsQt!^h*RX3{+D{{{R#XJdgltfCI13_#jSzKfwTh zGKe6b1T-9!2$Ta}omB<;C=1i=MF4&w2~K~C2X_PqyWmhc=*S%P9Qq(!iY=n#aegSC z-%!MVg7my;cvr}vY18csmrk&UKbq#L?UCZFqfSu#%t?^%nE(%h;re(S{^y11$G%1} zC!ZC`W0f{8T{0G+W+V8B;I1ntBHyPY-2)PMEZK_Ak&v8Z)D-RJm^3WZfW$tbYDLfC zqZ}w)jJrqIEeYVRCe{`Fdr`k0==WT*;7LocsKt>x;F&Z)`ueO5Xy1jX7(n*6fTp2h z-n({lw-HTysNf>B>_+V8D|4BIbPrS%Mm5X%v9oka7VW&8YFkeLgEv0i(|kt7xm}G2 zAbe2}TE1^y7R!!cbL6HDmmey23A zl;zyth`X+8==ST<1QQc7^eb{Br@I^enYagN4dMc=Oi|0kIas$R3=^4?7?F&BoJw3n z&@$iW*Oam0yXBkMle=d3c0J1iv7h2H(S>TgO}Qx%X4tiE;g!qnETS9_^1$=$)b(9> z=jD$2_*axk)abe}f^-BF2Lf$)bt@ElrpqcrmlcJ24mtkV<;@i>YJsOm)Pxl7h7GC= zyWDyrRYKhS(HU8l4nAtg)0xVNuSK}cRj_z)T1C$qA_(Bc1H-*EQ{_?v^3i2d2mQJ$ z1I2vQ630{$kMTh)cyV+S1EZGctPZ24f@}21r2mT;>EZ&-&)}5>S^rB;fV*}dQ z@(uq0Zy(KNk=E>*0RI5uS^F6$`9L;IJC_Ch!dJJPkX&ESxNoul04xhzkCarsR=&-+ zz(fEdBN+Y|3IWgsg!VdgT0TV9oY6y9e}V%}9|E9b`6?p4kz*Rszmt02HG!?$vJi;# zkqDTti*q}5{{Z?H&zHKu{{Z>Dzm~)uP5a%TkN81TV*MNTy`i|zwtMdX0B-^YO)a-( zkA1qhn~s7dvlV^==B7 zf(v+^2f=iol=(~3Vis&zk91)eHj_I1O6eqwZ9^>UBk8ma`H$$+;W)Iv!oWH7N%F3lN_@F(s(E&NPvm@WMwkLLUdW`Nj>>l z)wT2##X)UX7gw5op<|nPcss-c+}d)Xa%6wyO!nL#0=j;8E1z@c_-BbkfI<3X0f`)n z^rNKqR%hfr*M z-tIvHFUaYt29q9sNGRXPj6Rr$k!B)y2!bcKU24dHKu;cw#ksHHd01R zr1eu!djnRf=|F~85Z9xpl00AaQsZp-03B21dVG18Sr$BXN;6FsLu*#6pbx>g=z*lT z@j%IRRspHxub@JrXz=8NLdK$>6@m3%=+&e713&7yUxL>@*yr2m!Jt)61DXlqSp=a2 z---tIlc_t}4MFn0Qi3_hUMzySi+F`np`d?~N{FQ(4~l{b7bqh#Kpps^ zUqmH)4*-EzMnHv7I4GlCen>&kv-zMk(~kks0k0o0 zf#6a8Xr}>Mq44^nv3gz;#7>Q(DTX?g%co9JjahSPBwQD5dZ4;9Z{y=#jz45(e-!2( zoPb#Gomk~^PU(K+a<7=(w-N+c=pSCy$LiMNyrd#eU}G=D+*8sajy=4&waSPBR2Bv< zDYpolVkW_OH{P{@mn>K>DBA*D$IU$oWO_gtpA?j}o11Dfxfwz~UDgN1N*N8WDt6^N zWC_HvgYf3-I4S;8@svdF2oQd_mwGJXrN{L#GCfIXV?s1^9Y!8tyK3e8hqf{d0OEO- zaG`^H9_B7oPjv6dwbD&lL)$v+Y|8v2Xq$2|0iRB2A;;TnV_x-rXOM1wOIL{DxQ zSEW0K-}f#_%t#5XAHgo{o=h z&V}r|E+cBpOG4QDO4RVb4&v`^$Vvv}M6N~P{{XpKb3CB23ymFGI)J9e-Yfc%?fkvA z@ZK$1mHZvTWPWdjscY%5{5~t)_*v6ESCvLUxqrQSoQ&^0bSS89$>POkhT&55NYU14 z^(~rTOcqt>_}}S@Q57kDAH@*eP*uDf5HvxRc?Cn)!3K6%qdTo==5mI#*F~t!Qng8G zqS7sj{^SlFI3Rf8z^U@l@$r7EB0=D`9v|bPz?cFXmjbQ_f$`>`o;(i+K_~~2RtE~} z<`fSU`^pOtqkPa@fo?C+1-LVKYJzdc=ll>&0rNod`xF9C=6E2FuD)m^EJM`2lfak+Wnpsw-FR9Gt9m)2BbnxW&iE#IX!) zYca>ivKrlp28bRXdgi|Ur6+*!0aXw<{Lnl&*U1w4G?wrv$v-1bWg4bjoGn|G+p>+T zP^_-bLNOjBun04;w;678HnttRGu$@;V>~N=_VGXF$+_ETc@n0z^}jBP&$Io@k!#o8 zw;XS8;|A`<+u`}Vs?m+>fLo1!rUhp7NgW>9?O$%-UXD~Yd2SgnknY{LONS=ztV}&e zj7a4W7c2U=^{$^L0{z*_H}4A*jACp=n8o4<)bKojT>9?Sl0yKsX{Bxvgn(f%KBnXK z7d2VJ(QS{BG1L!W^A)tuU!7RK3P$P>-UhJMK(@_&jElEBjH$wD;k8VzByUQ0GFn6Pos<*H5 znWn(bE%|#9#th!1{;8iOkGJr+M#z`ddUCxd)<&NV6x~#@3@8{50YF(@35sZXpfz1Y z24_uD)F2&sYN$Gg=%8uWwYEC1$g{WGLVQSoMTaV#{0E|b$VZT8r)2LBc zd*%c;EweigVdIl#cKpbqONnO8c_zh?a`xGe8^!P9cVlEf_1ZnZa`w+IJo%nlcdy*V zHnVL10Ih>|88-ZF5hn8ikvo^JY<)q6mv1){8#2-EwUcTWZOf$M2>VxQd@;@0D$9j* z6+m?~4&^m)JDXJuGrLp-S40W8Aqzvn6qp``0YK1s1P=KiPC1|t)et~($R!rbYR;}2 zcWfi6R}j5RVuHQ_G{jdY88sWKl~9lm1r*kfr-CW7&9z`WzyNBdpHw!t%uDk0?Z$FE zz@oos%2OF#CPU~4K#S>8<|MnlK`MkIdwD|GYmhED@I|()#{4c1ra<&WImtlM5JZ1s zg1!6RluK|^Tl9+7N2n`KNfX%2xMQJJeJY!F-P_Gf5(3}3RXDLwMnHawv-K2cgqxBx zRq$E#5vVlcbh+yI07J zWIibp^uIgzCl`R=l+$sic*u80#ZP9mzz2m@H1>L_fs$rC+eJu*R0Rm|-_>b<`YQEU zzKb>;zC_CWay-?fXUMFoGVXdH6zYI+Zd_1CPf9A3Yp$HqDF^3Op*((LL>d_NkZwAx z53j#REq3iT<)?hiim{%3*S>Q5R)l~cj^zC|0;K3rIu{JXwumgmkj{aVzitiPF%i{S z1P1;-Krw{Gq%{thJj34}+_Adh-?1ozc2GTon$3>CpLt&m?|Wt4t8l-IaxK{+BK($J zJLQudMO_$NwhMB7RQXky0##MmMS*`LSc2;h+=!uadg_eoq^=Gs)Ilk^QA{=JfO(=5 zP<2Hv-abeJXoyUJw=M{{O~_FYm_2F=D7W|^O|J$(h+(1-o1c;{gMWf3wGS?c$oA-d z2xzzL=nxFZ4{LBh<|Dz7hs1C~oCokh^>GzvUZ;reeH0M(nV!f*&Syx*r{F5N_T1`E zZJbYP`-?CMW9<1IlBl_IK9qhlFpYqU2SQ6O zb*&6r7e-VfX-6!0AZ_XPU7R#xL#64jstI0kt2$bhTIImf9F){%-MG?(xl*Vt*vsMF ztw2Z_xX8*8y$}J7Bto_f3z>id4;9R6?Kv4H$hCUZzb_~4yai+Y6;lP{iJvQMV++EE zfk74AsM^TxC!ifv_Ew#XzPw~i%wh#(HB(V@62=Zp1-xdnkPReBVh28@O%;v}@#r-duAlt2tzGEP=pdcF^D<>7Yh;$;{BK|EVT z(i{c*$3q)$K@e(_nOb)HRt?EwT>Q(+9^`-0zXpvtMnbEs@Wrn%_c!S#$+==~S^nO) zcNcauo)>Y|PW$lNp5muz$Xohsr5nAuVk~GS{p{I!ml}Qmt zC^-2AZY!M0i<3&~3e-x^vhCeh@On`}*J+K4n zkt_poB+w{~yL-kyUE__k*va4XAXww=wvF)<{(H2w4>>Bci}KvF?Z0&8H1`aQA8F!{ z45EMUvjj~Xw{4hwWU+gZsm%WXmrEaDY@2-S-^j(e?p)x;IlHyPelU{irW65*BrmT?_lj&L(EO&Ny889Yix<$*% zRMltAG|AoVkp=t4y~W7$L0)+RrTmowHu7(fA#OqRBoXi${F5~;#ru0qfD_BT8&Qz} z2}`sRXaheJ)Gm|rXY93NIB}V?i;p~+L_F>g(0)go^$Su&ww;mcN)i{cY$I9EB89 zfMf+wkQ5742?Aru07?o3)zvTn839ZTkm8_f2DMRO#uJgGU0l@kvm8=?9GGzdYJO?< zGbYR-2$+T%NT+;B7n~Q9N zZJ+-DeqMn6R(NgNDfI7_Jb`-wIGwh zK?IJa2&;AiO+==-MDktT5q2Hj)e_Qn6)vMlB_gU*U&pF5 z;T-E*n}snlWHwU>6L@h{14MiuflYuAVK@p(B~$dzMl z+A?wON46IyB53tXkvzR87aJlr;p(2sRv~lit**0VYg)AuC|jD6t@3+z=|RO?brH%y zc=J^dnE>TgRl9fxuBs$?N5A%|?t6Ab06G&DhPvm&b_g(z0()Z_bM14Zw$^o@pcgxq#*x|#8G1ro; zFIm%*snbmhP&~W}tMIl&VhQKP7FJG0&>VBo8MTjc?Ny8*?vX65O%^^XDdH+9mK+cO z+Oh#e173&-{{R$0ZBawz(E)Fg2UFmIP`4xntM{Nx5C$Gd5A0ANfipMB4IT~VfQocL z@7R<4P{W3S1A{m3MUS@j{{Ule*@82_3wv#;H`RVmFhAgnpNjN(zMnhoZ>a6?eS@=O z2%Ov3_dBCl{{W|N;Trtb=jU&~3-rG=&>P<0_U*puO9N)KHI(HGa`>O9r_-3t>+|RS zT)yM_wd|}RD2>kU;W5J&(U3p$NrGFRmVVp+0Ix1`@9S>P3*zlpXC4y0ct!l787$ks zEl&RcOYq6w{pq}JcIT38;$vcD+aHz2xnxX-(p~atIsJn2ci*25{M%=jnPg?(zX1z` zcLP~OGqUsbTgDzm>DqZcIIeU{w{D%cqX`m0R#7fSU7ySwhCR=ucsgp-ccp4%2>$?P zM@W-JQJZ#V5|m{_!9`Oi*0~FDs3ZVYg6E?+-)O=@F`yjP#9X^+@#h)T9zA+35z7pJ z%jH{@=o^vLM2~@3s_CP8cUsN3n#Z~lABC1`G51^7EzRW-D1Z#3#1Y7=$j7}2WfC;# z@vn;IYjQmb&UK+`7Yw}-bb)RF4)R}s`)ImLg{^!|##uR6A!1XzD1JKqAP%O1IqS^`w*!jg{}9y%_wwqGLtsryd$$?goT!w(+e*|!<`wz7Vy!WU;*+mz)008_aY zUjG2gxzt+nYpqB4u8g3yATI{uRw_L!WRu1RjTTku*gxrx99bG)uK`pHJX=&nYq}Ix zP5%IoR7#`ff}Th|9MN3P7E|ov6Y+vY9=m zKxq1vsrlM{jm8^otG2D#jPeb~{^TM=LF7sLwbg1)f8^S?E18mrh>g9f$p^YpV{=M0 zScBDS+dsm8@~sBIj3F3{~2>ZR(_ zAx6|7UJ(HQ0AC-8s>-B5fOG|@hzO^4pap?IXlkfTe)SNWi+=*_h9Q)|(;x%rimP)fF?OpU&b#@nquUpRc&zH>PiJbjD{yxnWn5j6t7^@= zL8A~AO-M^37*F^h56|L(rOBmVk}SkCfrH$bXvU>YUlk>b(Z3$}mjjA2kp0St$Zy<& zDGosmR-GylcA`ESA@($v2(p^b!5ShP;ECv&{L!00hehAu$wUNHZ2S={SGz$&;EV1# zP1hoJ;Uf|cn$(!ZaW*kCbMj>~Z?@af%FLyXxinDomK7PS>9^|7qX~kz&Mg`rvaV!DwO)oxG zWrcD)HBYjAPXtZn2^!Tt=h2~$wOzVE5iV5w zuhr@v&-P8s%&P|MULrur*7=&})O~@m?Y8#(J67TtLLdM-E&66U8*>BUqKdL5M?lds zO-GuzEX0Jt;r{@vSew@Sg=1*iKo;*@63e(=k%oiJt$l5A{WjSjCvU#b-ga);<$*YG zkP2O%-8r`Vakh-1cH@?iNm_NAHe=b9o0A|$K*XunrudEQyAi*RSob)gTs7$B!(?KZ z5?jS;R(hC@&|*Gn)@5tjZrAuGDjbWVAl94$4tFB=aUdF%WMb7p^%ZZ1eWr{$cr3Jg zG6hZuphNUP(Gx@t>|{Xg;h;c3WK#W^0P2Br`%oTVGz1YuSr76=2@X6^(_75~(F3?s zPACw56`}y`T~LQ{=zzK?xgH#mPab5T`!jj{aoVxFp|fq*bEQx+GG*z&_3ag2%lhNx z%ldcfW6HO`)xUUdk(430jkg%n(Zi3YPO_|z#d5!^U;V!S0PSsgzEvnZI(-w)Fsm#krup8@8w23(*%1zofpRi7BZ2EZev*T6Tx>9t&Ej zp_XzaBN|&8%bJ>vB1d3}sBuNOF)|}_^H*=o17_G^2GvU!;Wey_S7Kvr;c_~*fO1%{ zlUdn!Y+j$`=WVBO_Qv4gdZf5k9zGmxUb$j-Om4)M{*tY_iQ{J^PBWZ+TTnH(_pIC< ze1tA-v6YvA5&($PU0qEPA}B~kz!HpwkBh5A_up)b0AQz)2Nm;vT`xuhdZ|KdZHhS;C2$0f%&Ye zruprBA9(v@?Rj}ImQARe*qITTjBQ>blDWXXg~x*Qf3NyylK6Z*xMIr>Gb<3>h4YPe zc8%L*;UfullM~3b7tv@uW7o=7g^?Ri(oXc&X3D#&W5 zxqZ8lV`~`$QcbddreBKL{{Y1mI^n)Amj2V39m8$I%mx1dF={fONi#@!6~eWAG(-OY z1y$eexi&XFfbH4#t=`4AA4eh=DkTtmfjTpDUQgE9U3vazwwcPaV$^Kg22rzaBF&-r zJ3t+v9W-2i(p-&o_RXoWuKr-w*^!J4g_mbM1BJeBx%sO`H{)_cy4|dP*qDfqspw=6 z4q zJP8hghgF3%8579^m~k$E5D+Tp-Ut)P_#mDDvIz(Xf!oy-2;zam<`D%H4~h&O z*tN`AJ2k=cR(nd+wRS==?LJFbVfQk`YdH6KDNwD>-QoC1eqm)x@^-=Q4iAbdQ4tyh zH&5;(gP;Sr=seZHMYG0K;+7_lr)UqV2>S;#A(9Q$ zA?VOPXu3o?FGguZWRTQXBqR8XBche;+jheO=aMsQWlsJ4nReTW1Bq5MZK`=&HOtY| zgtYp!HqE$W(qB>Fu-tANafp2ui*O`9#A1iYH^eC@7QE)Zhj z$kAfPrDV$rCH|J@MV-dvL;l+Xq(xSCnE>sP8bLO$40hfE4i2SXq#SLp2iwv9{WkaMG3Q za18n@hN{mp&9^2_R=%w2o$cljc90CO)h(`PbKfn9%3n#9YOkVe$UWDckGW&qgxHom z2L+z;x<}1>rZ1tBbjE<1crHBEv73jKY|K`Ku~zwBeZ3!V%JuE`67-_uW78^*ei-hN z?fQ5rtJkMDa?fOl92Vo3rI^j3<)$)W8{d8fEFle9Fa}01Pvb)DN)OCK;f?^;(|!A z^3el`dXuLVSZNgKiGXUzdM$i7lv-T)A`q=ybwIS&%?K#f8b8>HDbG+_$raUIg~Jmf z?kb;Wo9zv^YUS8gJ^-nu>1sQCr6>?PsHc{G)uoTI-Mb+!2cohbTiCwW2Bro?@cs$) zU#_>UY~yS`tdDJ|m%C_7@pM`1F{v2&nKm!ppQRCMI>y_(4;AIDFfR9-u;xHiI5Zsjf(==KCt{^BUHsx%Y_s$TU_s4jH4-oC{f5# zk~&LdS_a>yCT}%aqNmkyDYtqdyG5}oJW*Q^#>>ILxtQLht&Zz<=M$ zw{IQChk0+Y)^Rb`WN+}hwcfpY*P|f@vLPb<=8o;jYvG$7dw+Gzzc)UlzybpFoxGMQ zt&OfzGKEceu6{{gv$tpA%My4OU~UV53y~}%-Oqt=x^sMDQ*eQe=;PV9Gj3BYt4IT> zCXM2`^K!NABVzM^=-0G0aR_RBcu7ERDU+$f*X!Qc_Oke^Vgy!XUUz16RJ^O z?wX>qFEf+DZJMGRxt7^XNT3K4d2^5Upp-Dv%&Xu{5#-zx zz?Pr9tp~(;tcgEnS`Gkswu?Rlv5PSQFk7|*vnVvJmH;5P5-7GF{!1VeRRd|k1afa8 zsAzct0|?Ig09W_Nz94`a+^T?`wvB&A4Gk zKV8c*m5=`9KB)Y{RhKKny`_J$-r=`OpOn6C+K(%D$9Nt^!t!+;dUeiEMF!r@aLVQU zBNK8Na3I?nk~w)VKl>bgxpe%0OUF{rhi7L3{{UsUG;!_1EdYL^!=U}^&(9J!-|2e0 zepU&!f$7Q??&Vy+^t?=I5X8v20f)tDpKYrrwsvD~*gmbfk6gsdw&Y%Ip6MZ?<;R@tW81})zZLlbD~E^J0+*u=^hA$!>B{_$z2=_< zJ*vPAzy^rW0YncK=7>x=Dx!fXgsPGR-8|GyJAx*f0r)D=vHi#oYbcs)bX821+fZ>S zfglWwMP$QTD2V&-+%WX*c0ix5R|6IthZjXK;X-fg+@1F!qawh01_&)i0DUlv4iSj> zD?E!4u_DC%Ba+nNolP4y;iz-fZ|fpzUQI^PYv2MJui~Z%WqJ{M_a2H~v2j{=rf5E& z1&iGzS1x$hn!`wlcOWPS6j@1Tv}A^_q17ThGJf5?YutO@Egc3RDuOQH?ZE>`8lZyb6)SS< zFDU&6x+<El|9{{SdiTl_2#+M**hJdiNPsMMyKXb`u` z89E?#ld2{fV#r89GA<*P2T`IHE6Qch+K8ui-P^Ppx;2R7w@0`coj4+7i?Fo|VW2cc z)SN596HNpS01d?u2`5^h0J6RUkup~?5s|>F=@1Y!)sbp49l+5ATd^m@l9uAgtLc2! zT974gv^yh6U+ZVvfaMrJ+ExC#ziyolKj_`6eq%c1 zoBBWjU+PW2%YPU2n_#lW?|srW?vYxbnqT>Jc%I1i?jPaBwe;~J%G}~J;kj!MX~ZAe zw*cC9fEMIRmV1URnnVG~YDR5Py}sKTNHWxn>l-KBF^NCiWGe?F++YGt&<6nN;c~FD zJrkTSS_6kuGIz&Rlid7I_3lT8b=pK3%x!-CgXzV4Y?6u5P~$KQ`B;GWxX^ z;}@1y%bl<)vc#D;Bul>}Oj@;Ifu^Wp;DZW{IHKW_i=Ww%O%|%$v4xKp!1Gidgfgm6u5)LR3I& zNIB`;{-#reF6LsZ)4c?0hvCXxQd-0pjq#~sjfqLy)!$OVKF#I@CTytb!guPlD%P9JAyBl{uo;t8s5eeJ#Ex^VRc!>|G_yuue zQpvMo&Et62`N-fn0HKV`%zK`J$+15BBtL1@kY#PNo!fJWn1GCqrH_DDsExZq<+B;y z0yg9Rm<7Xgb(K#G(YbrP03s+G?L!vt+qHJwrP@6}DJ8r;ImpWWna)=37#UEug<-23 zc)#~n37G!nwiA#POw`18EEXr>!7~#TEz0IK?^4)zq@&G|r(KIHIS__K2oVHEcKF1U z!Mh7_xpp?o0$Z|N2=h>Oxfq_N&lz@o02oh>x+@^@%s=ejxoD5{=O~|w&s>h{E>g($ z?Bg3<{*}m{;4}iI)GIq^5S-&?@Ow8tnaB4oX=86A6aBjUVQ%1%VLNgfw^d|G8duH5rFX83Yjr?#-Y;V(;i+Kxr* zBhj~!8A>v?JDy&hOhGMD%YUC;b9@!?pSUdT_`BxgkF{K#-MYp_%XqggkEq5as`Xy~ z0FNnM9>pf@uO?afO?tM~FQzPLSSeOFC8a#P&_?Hq2yTjaqOtFBZV1aXnx2{>#1~Bm zg%Mb}6K>_G%PM!fW;&{vlw?1WrXDY7IHsz2&#Iawa7R8UB#gP1>aK}meAa~VBcccQ z4F?@o1dqW{D3?^B@!)uKNGAb7EF-7MU+^qKo+*OlWv4}N@rmo71z>!VRw$m+1RI6;YkVO6X#(qrM;v>Ub9Dy#8>X+#o%^AteY zNwh?-owKZskKXrekEX_Sr(!&sf8MkI0PzLq{U%pwe$myvUHsQITfxXUnV8uCpY6;N z++t`)z^r#R6Wh~li}AUYEBPYro6~$tV0QLEfkJg9*OEs|6Mj-Rp&N3>jP1fgQ1wLt z1;GH<0U|H)b*w6A!Z8g9h>k<=L_7vSmU3r;s#+e9F!3ab8oL{{R%6a^SITtA@9d$OJneYE>|XP)A4U$p}vB zSk$0fipeUUp>8*>-Vg%y*oe;O6By_bZFwiV@&5oL?p?b)2DQ4`o+b1D0I3hIA17V^ z04wn4)c*jt{GbPiO;=`j%h3M-Omoewz2|3{Xk6{h#s~c0O~&&9ZF|bU5&WJIV8~<$Cz&4sk?48P z!zvyn0gp5DK_L{O@j(HK2Db&TuxSO=Da=68)7oGd9z{yHhtruZ%s3~M!ZyGalN7SG zA{mPyeOCbUQ|nfERGwB1x=QRp9LQF1eWIlIjj{v%XwzORUq*H+OWa#z326e}3jI&A zw7u82LV$v`^*+cY?)(G56)?S154*75f+b(9O`-n)%yHwOhrwJ;s`owZXgf|JlOg3! z=e?p_dYbi523B?7dO`mH)$(-MW~kivoOoPkPqa_1W?%Q8DUy6r_ZD);z3&;C_g95h zf3>N@9{&KlFHPEiHd()_{{UMe@3`*C&!|iAbua4F{MlD`+p?jVI`LV*rnNXwxw_6m zvnwBFzN!~9AMA0?e@6fazqs`XUH7F(Fe6IHHj9Y-!`O6v10;@>td zMq`+CZ;Ovc!p;{h#;hAf#`t<7hUW5|X+x^lD_A$JNazW5SjvXhD{2uwwQ@FF??sTL zD%$fzFvL^rKo|}P7&rd?x?On>bZq2BJDGHKU0o1KI*G0Zzjk5~V-1TR6U8K}RQ-a~$ z(meM*J@NWzPK(b~l`BwT0S{75RaX@9A?ZkPi62~>Kot$`wK-eAjWaoh5;6PLM?oJ~ z^3OPSmMz8BwW*rHznkcGiHEl;Of@xGo>HuO_HJ1qH>O5{nyIEStoj&tr3lBm&GN!O zicV79M&3px`>?caw5`T8vJGS8tZsN_*456#^vjaAD^|_vcCn)lD^V;}xozZRKbd01 zYi*_i)a^HH-O16`x%8Xma^^YZs#vVc*!8EH&LwhNhV!4bXWWJz!xxC|gn%(4n-$ld zd?l^VYWt#d&HT3WbJVktf46jy1+(@5r(9}%o~N~Y%Wb!QcoMvFup~?;b`^vVKC3@m zUv4*WwQn1BzvyLJ$+db$?U`DblSJv<)d_i7b-80S-N2R~sp-y4B~}D=@m%jIV^e9h z2+lpyj9R_YEEfwdt&Qy4S2M1}pT$Fn! zCo!O2kI9SW<6o>k{{Y=K?A)(tZIHKzV&#Y(!!{D`zcFxkc14(59NMRtUqkcaW|zc| zm@ZaMb$2Cnth+6WbcoSs5XC8G48Qnef8kKCYP{fZ(Ru0cg)WCnf+GG;^Sih|>@ z;mjbx%ac149M${%vURCb431N`-kM^>GBo;`G{v}Nb>y02)N%uGbx|n4*If`z8|U~S znmGekMa07RaZ-q}8={6+B`!AsMF@9SA{M?u-#0EBc{@J7))XvlhK<3XlBEd3ul@aqbJB>pVLC zH{m^t@W`=eBH4R)?Z)H?{KAqWWd!bEy7n7;y z9UG0{ppNbPHY4AD>@3Heqyj3GHy>U904I+;f&T!TAY&g2*1R2)Olm5E1F9aRNGuu9 z57;WAE2;-K1rTTg8Ysxb5y8=MUU@cPOnbday=}wlDy|#<0CjN4Mk5{~O&Oo6L)Aer1RQOIZz)wqXY5Kkz8wIU^sJdI@09EPh?kL1+xvu-TG`jyk` zB5CbMR3;5wIiZMUdIF8ydMw_s#d%(woCDfAE_b_E6|Q&oOu>!7K7lPAWl-9NK#`sM zu`U=|fci&Q)znn#grXbIgXo4DifJ6n^g$V6!9W5v2=P*gWGV^xm71?V{XxN=M#Fn1 z)Je$OE<-NUf9aQy^9y`jtbUVYkH@_m_N`ut1{Y!`JPlW=kA7VzwQn3>c5JtVyJM3n z;$7-4MdSYf)eyJD+T;6Qte5z&q(REWznQ%bgPD4=YSOlVU?Mz)Uk5t1>1BzM+ zDVl-Y9Wh3lI%NPe_#zCXG#?b66vH^eFCyHOu~2rKrGRLti&pXB2BNUk8S#8u!Jp|X zT>DGuPi-Ju6=GKVjPlk6_|ajZam@osSW^kBEnsPGYbvFcn~jMRa{bubj74NiBFOU{ z{{ZzbZo}`hg&}_6p^*G5H>T$nyjyzrmTu{CM(yHly)C^Kb=RNHM;~`^jOJU9#T^fh zL|OhwhK!TkNP1|i7b`wl*L_KL&O)@R#kJOPF>2Q9lW4fRC*f7Dd$BL)7H)f!H@CE2 zEu$@eWpn(9c;vgv!v5zin`sqL~va z<*$9%KZ;Q!#Xhjw(6#SuDK~j%;0ROe7i#o9*|yAwmYb>9EiIP-kd#9jvpX^`hV_x^3T*)4^nD9^SwSTFXbKLn;{{XB{n$7(h{%~nGn}nTDf@w|fJWUea4DQuI8IV^5Q#7e} z)dprvLrJI)6}epca~GrAGu3vE9YlRqW!7x>gqhFb05a#)dN{4@t9|hV2O#JcU1yW6 zZN_o#F`{lS)mH8>i6NPl)Uls(lp3uvfQEM{&GuxzZB#@PFZZoT2Tn=w5z@aEQx)YS zrihgj{5T>S?ilgpfy}dLULO?$O+Ruey;-@04dTeKQAqKBiXkG1=kP$A{16g|R3}P= zA$-S*D6`Q6n7Reg&x!^6G9`D6`h|er-|#_m6tu?4x#c=PbeH{65moCOq13|@bSj)&QGC?D|h*fQ7T#i9K zv%TFDK?xe45XdcA#}>O|2(-18e$I-GkIcq4h{%_OnZnk!>5TTx=v%vO?cFADl)7_L zLflxj92~h_gd_Fa4=BX`&abqrlL3t}Gh%Wwks@=Y28^YKG_bGT7fwt_1-`Bz1tR-Z z&6V7n;~>G>jm#~|NEtas#iwZ*)4nhcwIZamn~ghS;lCKf52#49d{gT~r@2_h!yAx{ zuVR~~)GtSj#-aKxPtMjQ^M}~?p4)rrxeJ!S6maH8l@$g`G=M*uWio|vYKEGw_bB4Xw>{ET?swP1*gIHJoEAX3h_ZHjioKc^=3%}lRg@pNLmo5moL72j+vG%;Q9BmmQW` zM!a1a#aPXok3}`Fs%YLI)aaUCRw0meb#*C!8#AVr=oWYYMvDgQByK7yu&>Jdjof9B;fZzdNwzfe!1Kpk!MdUfpCo;_7wgFFq^E{i}bwZJrdQ^V=^^93TBZ#cclo z;Va2wz4qyY6dmWYGO3w_PK|os{{Xu$xp4hwooae^cVU$)_D!p?w~yH&cy{+sxxoZI z8jZzr^1ct2HHlm|XKYSHf;*}K0iBUGU=0A%fK)lUq8taw0d86& zQ36whDLKY6Ztl`*)vI|TA&u*o3t6)x7h`sRNM~Zf0{pb@cMOb!ax!o2#0bYwUz^dj zRdr(ByLQ3sgkbuR84{+JXcp(^BRZ4;5Wq0#wwfcCJ}9^n zlw#e)4xCi9h-G-O5s!f@7qvktN?MXz;IVqNFxG;LA*j@(s+vLp=7DqIfvhU%8g)gU zjFyWiVPmI~28|J@MP{jz4hn-mI>a)uuGp9c7wyUuiRu`k?crNIXOCw7-*T6Byo;F9 z=i3tS_<|R+o3X-w4cJ|siQ3Av;`S`#e%T+@YC=Qe%X7tN^yBT#kE(F;ZRX-*W!W!l zD%38(^q2&FtF?0c`ulS#$~H(74oDl@9!L>{PXr7$qEIl{|(V5yv7Vu_%`5#&JKr zF%6WN_}4^KLg5-|!4V{KCmM+{;E9Rjoq9S>UN1#{)h{bi-EWO%ek#t{`bC)U7qssy zUv&E7Pxrg={{X0HpL(BIn0tdNC56*X0V@6J{cAS;&6p@|$@we&l)sxw9_Pzy-9Hrm z+Mm`3-5IfVx_liz^!}tr-I;MUx=V0${>u;QSGn%|;wf~FuBZ0X`lBBH{g-*nuS&gn ztX}JLh|RgU-J89_UsXQUsTF0FGpxK8L`NcD)#QPu{F_t^^-n(p1Jyo705f)O2Sg3- zJlLQ;{{SQlyy$=lo_;71p9BNcJoG>f#^b|84fPAVpk3vU$pG)-fEklS0L|zSH@{XT z0`7h&8fD}H01p6J88Dq()eBW`0U&uT!x%Yssz{>i&2sKDyGhV3xnrZ)tlgE#j>A@A z)nlh_Ij={vwcMSU&QTze3gvpouZ|kg!u0ICqoDg1KHBN@a=U~;C4(L(qUps%o*7PgS3kM&z=Az=Ov{V0hAtKods! zEZV5aENkGQLAarz^CbvhHbwG0`JG)5n@^f9h;BSlMYVKI7Ct{}DIFhzC4hd^Q=YVQ zLKFvQzTjwRdkoX8WWU~WJS zd6K#Qjy+ATmvGMi0C2~5DCzVg?%!qJn|zz1<24855>QcdL(2+`(}bfH_MVPr1YnFc6OJ6A~V(F(F5(n z@;7~GiV)HRR#sNmu3p8>gT#qSA;fsPbwe#$xIvGn*&pcwo@w;cbj$#tF_???sv#}Zg(?1hg108mF$PjPlCfyl z{GKKN63HfaTj;hp`Eu%3`R3MYlEQgKHAZVQw!Y zS=`XdOU2)I*5hWx?sgk4Y5|CPE?3i1yZ-=g+`1av!^T_+=g)%rblCV(!n$t>7+jOe zGZX=D>YgKNJDx7_g_E^!J9UlH&<{LI?e%bYlcc(?{96+E^yhKENd1kwLU-+L`-a~O zy}|(G7J=s&n37wAmFSG|Mw=Db##^fc1e&v%JvFxAIA_sJM7T~*dRqd3K zFy3pON3LxW`eD?0rC92kfa(+sJbqL}M?E^82r{pYXswGFw<_meiYmO=1{^{REZ1pq zM!9i$)FqD{*dA`YmBi<0v|@p3_362eoLK$33w{#(l(Gz9DVMFK*PD zL<(?Z>iVqTgt$@6%k35|NQ3;uFkN!rMy+I6J5KxUyPJ@lakAxd#!T(jU6)9Krxtfu z{W-GA$6odC8)vp{V@d$P6A1y_Myyw=a~g9WrukU+^F7&wG7P;u`Q*cIAd7aTE0cu9 zuxU@F*>L=Pby?-z+PM+#oSZffcWAYINB;n~eo-WIq?cQN?r)bv8(@5Dx+-YIaS9i~ z`XQ+z=Yk^4OAS1b0zlJ5Tr|o4rhMS-`lWsFVR65%Zg%hI|301W=0wR8O^ zgP(6ZmL^B9m95p!7hE0XhN4K!UXLpcq;P{K@SRg+MIzItnNk zZdJkcOk)Q$g=EAAsnENjRxR0t1Y=qD5@RWz;vBiDMpMKSNQXTZr!-CI8g~}xDz`s0 z)S?#P%qz^*Zb+JaNm@b`sVoMm=#d=mLO+C=5x{=+i%gwmP@8Skt%E~xXz}7uTCBKB zi%W6W;vU?cQrw;5?k*u{DH>dhB)ChUxbuEF-X6%lt-#PC%fpwe}y-cn^?X(dUlR;MIgDH9~98V{5T;0?h57+k-AC$ zAhNmCH7Lh4S!9FFHt0XVoW57SWrM(hIH*1tu?0RpCtUb{h%RJFGFs!pf0A?LsB%YD z^S>}T37iyaq&dsc#g<>KVMq%K&zUAWnF8ZQ*r}Do{b(hp3l6wP-}29a?rc}EAixR;*ejryr2j(yayJ}#l>t^QTN$` zKvbnF4v}Peyu7Yeom=aj;;iem8uRuy2`rUG;^N-${QVS0y#g%}4fy!yW|@ed?uLe& zrMxrvub)fD15evJTBCI9;SshvEOqAC;|+Kr=`2EQ4hc{29^o2#1}n{XU_Dmu#f;B5 z)wFUlp*Hsl{Zl4*{f>oS9b;BUwib(g!}m!$V(i?QfM>xAxrac04}67*mHLKdQlPJf zo}eS-F@@tx_1i6vLq#kGk9fi3`dC89$!?+Jd1~>S`OdTbN;&~-TC+}H%`kMobV-rN z!w~N-ZRE2WTH}qk*c~oAm6BaKh=~rSe~*gNn~zDkF;OV?*hOoXZX4=-I7s_`YS%Wj z+~Xnd79Fc)vBo^-s!RHqT`;HIkk5sTI*jdjtDd88ZG z0%Oqh{wdxPaIIrd#Nk~!+5;<6uE(R?X-t6S8$_=1UA0#NBpo9ysWwp$LVb2ENmRqi&H_aR+K zk|Sa)->xJnO;gb3weTc!wuX?XgIMr!Z3&C#6%jXtPoJVo#v9)9niNWe5%}cWe)qYM z_S294uGNoIg1FLsw+JSvM7VikO|`Y-)#eziWs9vz0hwO2B+oLRK01UC<}Oq6__WuD7+1DUYv} zA+@n^)TRp~EQ44dZQ?&TH6SNht~hfU3Wx9h&-?H{I(0BRk@oIc zeG3Ym`s~5hf{5sS!afVyEScZjJG-DyWpsP6)xtL5a_V5bt!c6j)Ai-IJLG*R*cct1 z|A13tAv?TS6)(0X&)Ou8!B0JwY+P!)t(TzT^YArhqDSdv(%)}oTKT_+K`hdSOt~#S zWtUCM{tnR84G?RNiP*D0`tn(ZtoHIsvk;1qtwN!}K|!0YcCWvt|7{_EOZ&VzcT^gW zyxr{->)0l@U??YRyEd05qr|{7QnK6N} zUZU;af>%(cdxrH4Cwsg?jgME+F<@)tCLqI6?>ZhtLBftxm5lBBe%Q+5-C@v5AMUhs zUd`-zdi1E=0{%78h2ge?7$041Vswyz(-zeIdb$}f)?ImHc#vCVRL~i$5!eC`VE^Oe zUoO7W6)XK6p22iXwvif@6E12_YcF+ek}tu@9LyPYhtr+=T$>An&W%otgIU3(2l|Tc z9F_r!aE-;u{NOce;aaVwddJIB+vn~Dy;F=WoZ_sg1oNMjtA%5u+k09TCIAxkGK-4D zw`9JZq|^?4V9#Njc!m9fH{&IM;!M>PGM5V}B57jD_h?;S->_<2q;yI!Bfhss3jD(c z9O+)@z%;Rf%NaUl^9r?1Zv5Z6NLAfd6Y+2`28)K+!LFDPd^bs<0=I-K*v;(TVbH+tl(A--%e zDLJFf7_#3MKl?NstFX1hcbqqzq@z-SH-Cgy#q;_Pu#lTz9^0qGQAufE&~|7qGCzA5 zeR>dPjEN!C%kS(oWfc`0a2g};5X`3Ss{=9zU)XVGnHX+Ww~4gFF~Dx0F|r%_rQV|N zoT%_$ILS{*b*P-mN8>HP{eD!k{Q^f?=uhR%1~Xrm02#^jN)_NP{)qW`N$b+bp^lys zOoEuvt6aQ^{vbDhKrHl8P1>HCGD~dcB_Ja8=tYOZ6toiQ=Vt=vDi=vyTwXsNBnkQK z3F0uEI-*camLqg=_2R3>BW({jVQqqKX|qj8nm2^gGIOr<_PXDHBN8*_b`&?-$g-cG zHC~PbOZ39mIjvrQ z<0xu{O6B(pg!i`b@`_c>vop8>NqCBM&6_diYKU?Xa~_#b1O91q9O0 zN~m+icRO`?#|71aK8aT$-o;(l<8b3(*1hTL?96*J!%TL(0{a^tpxB4&9f?cmlnzef zELiWn9skwp$K9|g(|qg>we#Hn#k)lM7f;2gE2||_~0@?-aeUK03W|Vf++D>xj+k! z{*EIm_n^1qp=wxwhmSW74u}%OaDO>V|Em^z&*L!vG&N?s}n*$r_#?!&)1f%!Wht z$=ljmoh~Q3nLKWx@d4Ty%m$gh{7pkpovh(Cn(DRd9k!)BOH1TU2Z-6BCdlVbceC1V ziL(G!Y*59zOC7T#JTo{({Ae{Cqqii+XN5HxjwYC%>!1T)`PtE3tu^@AHKFB>d>$wZ=+UCgnLaxv(Gi)!^jVsL za+k_d;m~;eA(?sqjab$w^g!(-y#D~3+Sm*CA49y=(^0@#htC8YTT|ULc*l0Tp|@Ki z&4eND^kcQZ;9dpJid%7Kavk|G2JmTo=|9VGN&G^5rm5?bY23<9{dP0}@Qsu6aT{bvP3tWkpVnf(d!Q`%lv;^eVHPJ92c1r5_U=7t{y%aMS_lMz{R^Jn1TB+g_ zsv4rxP{uq#G>~uwg4s9{_PLJ!UEJhqm$!xJ?=Z}WZHVTlv&<9j=ROc^TxK~I?OTwigE(5~UXl;W*54%(n#TlZ)& z=}$aU#$B?>TiKiv%G`B=wyCNRzBZyM-5B|0jVzAYoRSj`(Ml|xWich-nM1Ee> zYoXx(`jzI3y?{1R7CTv>+hbWxv6Z}|621DP-EUR{8BtCZS+-$B`|xLhkT^@}khlAw z-nUndW1V;gOvMg@n~+v3CfRVO+s1Ucbr5~+S6HD5r%8=e{9VSn4Ul|Trci`|2#cJdEPF-+CLCITlD)PASz<$dK1?dWuyfZx8;uBlO4!S3wCX7un4iI z)XBah^HmUo8~mu1mQrIcY-oGlB(n)9q*v#SYB&b+ntd+&ch&A6IS-@%Lbtg8!kOVP z(6jUS^Bme0p|e=fG2kE=zS3pkggjx1X|YDDJf3)^9*AezVu3Kj;4`LGn^Y9=^;juB z;5^nY8n5gwNnHqklxsMhDwHEzW^rN*SN-7JjJ#)xE;wYsyIL}!A3Q`f5Ce<#lJ zx%n(2lS5Gl>_%P&`J|KWx?Nlvjy0o>mZitbgliCvD#hKwgkOlQKzG_$0sT4Nd<{2D zhm3`B;RPu^eH(FTdBXRAP1po|pq{9K4ko_q4HhwKIC>Uyw|WuiA0SMtjh>Dx)BYRe z#?!WN9<=r+vfX>a{iTVGa%3UI4d=ThB5se3KnfLuo9 zI;V_t@*=wHkx3&q9uFQA0>o2R1XzGjjz#bw(gV!Un*;wU6w0+ntJ@OWR1p`{IedCM z8K#EPYPCkRzYmDGe^;WR@$*SMy8g%MpGvgrW@COUE7M?TlNXDGUkt;Wc^8=a@lh;E7FUo)gk8Y6~@!k=ckeAI*`;6{N#>K{6MOI?Bfude$Wer zWT;HXa44K__wrr5I>@y>|Hd9S=8V{t|7V3!{=~_-*xwhSx)|%;iSnE&5oIKyklq*h z%^f)0lgt*|c%Hkp!qSCI9@}1%PZ^sWU&ED57+*P>EkA>-N~BGgn`CpO4`OYGa}&)W zr}=tH5h_kuZPEGD>V>+{S!(xf^P!=Q8i0^7L(Xun_>!$D9_ZO*iIWSt{W=%+7yf1G zNlbInJ^ek{&nSg7=DbNPsYW zg3&?@TYxPJDz0QAbqp=BG{GGgP!yo90Ko{;jw)@Qq2LaU+$WIx6l4E`I2c;g>7;+} zE#5bwpC);{Ao0#7ChuF;1-yh_w~=dd;N?VewQtUA+AcWkc7*(B0j@s+gte~?5}`9o zGkGLFgQ*db!0Qyy(By7-z88td>-M_tQ#Oh^%ef$W2KcVE~Z=qzQv=UPHHCLC~ zsnc_$RT_h`SZem(*Gfx$0j|b6>8U~^Cg_k`C*rk7ws!Y2;Ck~RC)1r?!z(s_gZAAt zE`%W#oW8nUwj`k1+|m7k87=Yc;M1o)6_*Nclj?QXg65xKrEcXHX&3eOzx+Ve05fDW zVnxr4DCm6eJG=$YyK?H~y1ISJTKXoLIaOr+ z%`4Boaitk!QKF)lk8Z@#3w80EAvL zc&={zY}27%T8o?UN)1EQ{t$Dn49V+qDF&5s;i1rYI0`AbFql_gt^>i7oVWT+xgSv^ zV5sdP=`6uGxL|#bxI2Uv5Nqq>y>_#Nc>lO7G~S92n8CY6py}_$d}+nY^RYs_5nfJ> zvnv+TU_2I5Z>_IHeuzs70@xku9ainUy5wI4EpwtRTvCS(9fztFifbO&kgx#V+>($n$mBTzBU-v4x%BZDtA z)kH!U!pzQI?iBq>gp1a}eE&C1%;G39 zJ4=F@+2sEL(m;ME1i!)Gn*w+n{83kOFz>`eTr|FC3@>ITvn1ON!=`uWLzo8JzMCtN z(i-FjRgR@CeCY5OV4%ug%Z=RT+-wRfYLZV9s%9d)#xS8}4^v|Q$rhKd z0#P6->fiK+gBZmTJr&m@t}qF{Y((p|)lO8fy+B=TGuln;q4tJgAAZd__J4q+wlt>! z3LUuOXQVQhWYQ&wbFOkwU{Il+V9>ui+zjU@2n?7>5$p$F-C)D5aq9wEFOPvfO3i28 zpelLGoDgq=JrVZmLs3l!k2d>#)RG|5AJM~w?$k>5I3rXC=BnN4(oMbOL2;X*uMgI6GfJ7!a+M9*HZL_@L!D4rf+p9XGb)XMR zc}cqeT^C9`qGAoORqVq>8}-k?G7`_b2uw5L_2syS>eW4y)f+nR+72cAhfFer#sabjay(k9 z=cJ^6OE2PL)r`vJK*5r}Ai|OBmkD6I7?_xB^7?)HdxAPWMVa0VxJ3(TEu(T}9e`a< zB$oCm3y|$OK4mPD88^Mp{5(9&_c*qe8+t6uVK2$pWRf`2KnBIQ8K?dLrL=l|U0H#l zO8Z7bQ=iElZmuU0FOs&qZuSbZjrNDQY@kT_yf>vY!m)PV>>siz^%y&TzrxNKr)qCf zaNv67?XM1UU|Ajf58&21o58l_LN*l;O_yhn;LG2Y6^m`PPQj1NWM4N}-A8Sw_=||$ zPWJ>Ul8MPODcD~T2eiQr@Ng9C>#4KscSX{oduz;~t(oH<;<+u2+(ji^ubKNo9}Yqf z1~(o7_Q4l~s*gc0$*`+qwOXuaU(Z;Mg@aQX$Dh53XOiu73$>z<1{m>uT0D9H}5` zuCG}2El6L38!{DT6I+`IkL;6j{`D~lj;w*juk_a$k(7V4mI7t+{i)>^Y_g4=&yex& z1FP+FRd7WAtWn27H79e4(xD%8R55s=y?PmUkNu{K{W%da>AjnCXQ0&d^<^)j)yOrg z0_N&CYjDt|?>r}8rRz95&@(UykM=Re+W%0`Q#Jd%({GFkcrO}WiO5bP)1m0NVzC1% z-yoIHy3eA1(1<6heisylROCqjkryL~5GgL9lU$N5WYgxo#H0ufcYvU3yq^&rK@~S4 zPfdJmU@Npv+Q58q?^8RZ=Y3Tow&YQEM7?S`Cd4%lAf6nut zp#1A6g3aVBUqhr{05_R5OtsTM(-psq@!`8Z_cO}wJ+|C1r~d#oPI z4O)<}T?yl)04!r|%uGp-@-jXNCYFc+BjDhV)z4AG4%j;T9qZ6lf}200YS0&V_0>@S z_edT@V9_Na>dIKWJ}?OCp55l?n61w)IssXF&Fd=-@ch_Jqtbb&x4wH@FZR;FFn2~; z_j`;9;)QK=^T~7aU?Kq2=LF(9qjX)oIRxKLiS-p6H65;x-GbVzqAf(crkmV9U11vZ zxN$`#zp4{Sr6&l#8ui)nILn-K&ebKdtWU2XR0NRKsP`lOnz_v@&0bJ!+4JkVMdo|Y zk(#EfATMeiaplvgjS3OQKgMOp*cA1oo~Qe#3u0m4D1Y}MYiYvG48fnB6d*H<`AUm+ z19-Q5C+6@}=Z-)kx=@sq#kjFs3CpKy#5B^3uEW+KGXYnm$p2|k)JYWdoY+&yM|3tq8xUDC+Ow2@x?E zd#bBbCY*Ve(3M9gz9Yc>O(4)sQsX9huH|yi8gjREu1303p)IAH2AB|Fl4A1Sf-t_T z@Qr9&V3*I>&hA^1(O(E^Fev}9+@sQ2&YW3uu}v5>a7-j)uSu%Z7dwlk)V07OX3#oq6>CRD`nqjA#*kut#eaUq?l@Tw4_I;2J&SI9wtfthmDvoZ8`mSH$I z-P#v}K{4NUsVFgEln^zwQ2KIlc(s|6i;F9Ik=;JX@6a`{_oe5832{pfE3nZY0Il+q zNe}vc7m$fHw!xPj7;H<#`~|>3%Q3c8NX{g{L<`X$&b>7;l4Km;u8liM8=sC-@a2Xj z1nQu{R{=px4K;bkT<6YTId6n$5DxQ(Clo)6~~@fJ34F6WNCdyc6%DTyksGgBB6{H z#M&Twtdd_7nN168Le!WA35Pl0G~OjJ=Bg zV5wMZV2`05rTH|Y!xI6h>-2iNStb#hNOmXNDh;w(@)qH$Aa^r<|NSh{=_XE*>92*`#K=B9Hb3$E$(+yQBg5UoJx#<{ z*bPU=!m8Y&;6b^B*u>@Gv&pk>OBOxYT|q{0%;XKr%%T*I1*#|9=DW>yzk>_t0}g-@yzfh zp#QXvRb{158RhrRqltE!(ZS?Rd5y^!(`z|3ORaM3Ciuf3ooBM!zXmjlWW~Lu`NY+- zp&^Z3FwQS3`p3$O5J3SGtilfDhP%Sm-?z6H;H+2OH`YXRyFbvMbV}Q%8|LI{pDeCB zWp_Ex3f5EaunnX+a$ijm#TD!M8_}`RZ3YoyHQzr2m*WLFr7yOoHfoB7Mo2BzEmj3l zt3)3R(>s2vq3gfpP-(rCd7?d^If54R-=E*$E!J}SJY`IL8y6&{*h_Zma$4)46G9e5 zVcLKBkRqHopLZpIv9?Usm2cdg^%UuxSEWdF#?|MTsJdXUC5<#waj=~z_hQn_=}+m( z-3|;gd5H~eOI%u2IMRmpDVTDv_N0n6ux+m8oz@0a#uCDPy;L|q{y<~{>`cTz{OYcU z>kD%C1-ro9x7dujxDXYqD{RDA#&BA%rfp1b!}@&co-;O>67-7~9&$bcp!_o_n4STx%I~)u z&_j>Q>20CNKQScW/A9x(Z&mh=u|GB-Bq+7-e!a+wZdBJgXFS83N?gPTD_@o}Zh zEJgmCQ6Q!0azAvlP00MV%-wZ!Tr*Q-4m=r5&8j!Oim~6nXN zDO{8+62TC$O~kq&Ej zTBR!zQo?4u2J7{OVuN-9b~1zZEdMA|Y9Gao)CXmpedzOAt)P>_negeu3M8eRK-uqd z_Y%E(?W=f3C=_yyC5TT)1PC6&U^t`kg;Q^UI8E*vQh0~k^d&S44G>Hz>-BRZ>=U^{7Msh>E~(Nx?t&!B+#WPJpYcSf z9DnQfBU`4D)9CmQUXwgC^G^dmR03bB~xw~1TJ^r%|Z{myBGq+ z${iEONA1GOl5XtAL^mi%by{oUjpN_-`7gQ3R=-P!7{uuv$-+e+mJ{S`<2#4B>U18@ z^@sCKwi#><+ELBynt_h|%&;`uf}#4&=%MYo8D2HroW7}&G>S&nobq;8Pd zTYN2dsZ-{|gNDh^%O;fv(gS9_mHWiRr)Hfr{n*l~ouNh_GNwotlheM?M!gdgR$&D} z1ABlQc4?vt8cQa=BWCe!Uje+7#Zw>#ov95nq_y`#SL$=JLk)_*y?`>-)ok%2tq5RE zR#$=pt2ffgCJ1qi>^I+8(0!^4G&)DbVqLizvqcWu81mph{8=DCIq^=LsoiMrD;-&O zUG4)D#d~RHgNuLqR>U{Qqm-t+NU%4vfGTlJVgxzLC<%Wh2_HX(Hy9QdgC>oI^pwQ- zruBhV*r#}u#mr%^pBQx^ga8kJKpJb-r9dU>D`psZa!De!Ei$9XgidYDU5R7Ym2rN6 ztkYa8kflbiOML6s2qlSIyTggniE2UrFsN`{hfoGd+e^haNyp`{5%YJ;Cgc`5-XCUxL zOTkXy(Z=tds`VM*_tUVf;B$V4m_SELZbaKo&YZh<;|#9K?ylNI!D#$(l7;en&tSvE~U}0_r9%@ z2VLoR(cKb&7XJg(RM0$j3$)}n$eMUX4IU$-L95A(Bk!1_Q3K{r&A$WQ&2(Zdgi^iu?_dHn>G?hO zdk7gW@^I&axs5Xk*H!x@qF@?Y+8{?2dW|r`y}v}gaw2gWihyNwXM{65%h@cxyDB&# zVX6&$vV+lqVnHAr)~s!5>hUED=Gf%tf9Q$*ZZE+p{=QzbIj^&cB2Z(n)frSpruO9S z2|;gl4E18W!TY*{*DYRs_ig$P;Yhx_aEu*rL6oQPSPvdvaFL4Ba;o-fJO+fuzaFrX zt3kOYv!RgqBY6@=%$LtV(WMNTcqPjAF`lyI4o7bbur!K@D?5rCd#zuYgK<9fNwCjd z#z>Nx`Oqx3UWQln9kw@yUGxtkH0jFIJ@bu^rZWB#0&Z(!J)x=Km1{Tl>}3$%01^AD zSQ8q=i%PfVQcisp@RX@0g#^J6JIfn0G#LO}t-zllphI&kd6~0yde|pla^Y!R=Ca;* zVh!e$-XQ*5+nrp)u<0Nb30JYqQq`*ZL?#L9;Nuhs1&C8*-dNXeT%hgay7N%+I@hgM z{N1XW{B-nGUxlX}oK*ucLyd3%He5j@vJd^GysujXla=G#^7cg61vy zw%nTe1Nx@nS^9Dpur?Ykx7?s?{3w$THS@~qVfOxh2Q8O~pRZMRmQz$HM>;s|Mg8I3 z{+X3?fCy#Q!KcYyXxQ4g<*gAHF+7M1H9|DzXgX_Z&nT@<@=l>^C9k^8G5S9MCR38? zW*I*?SZ#7L#z1xi(2@>M@53rN4s^8KrKR}ku$CvMoZa361)ry zHoE^K&S2`!SXReNTdEaj*%q2DswE*elaqaY8|VLpLsI5PKM9%aPwT2`H0VENq>#Z@BYhkL ztCWdP&fxakXr=bWhg^|^NT)~q@IhVEsb|su0H;2w4cmy_)I%UY?~_i>TP$?(qh6;c znG$#I=kNMEwmNSAVipdJ9$y#{LKDp$=`o&(aaa34rU#LCQArX;ks7?0x|Y||^Y#A$ zZhe4T9maj$o$vvAmGTHk~61b2H z2>0*WWG21AtNDjHapD=@ns$Girw`-3BU1z8;Xw1<)lm@L^%N}phtFVo6|Cmd_(&)< zlbyX#7U7LNL9G(QVBkw^tUEJ5?kJgYqQ~YYS$>d1umW80?0ji!TS$aGYb|Lovl52o z*SQ50D=^*4&THH^X#^5l6M*hR)Ah|?fAuZ>b#nFQzn9Nr(QCGlu=3rWB0Noq)v(}& z^4G8SU`fmq-=I0l)J=Od0T@bu{d76WsfT$|dC6`YMWt6!v}L-}PUd#8#<5a1n8+JO zO+bRGcPKoZqatjuB5J0t^CNOIn%HGIjb2Otc%%rS3V3Rgo;Fd9CcLB4dTdy}%6^Z? zkW?%WWbvU_RQG9~M(F>D=q5g%zNHn?5Egs)*m5fioH(vNYM>7r=0hygO8jVI&<3ik z6V(S^q^A=YUDrRu0fJE`hWFq6gkBye7L^9MtJ@pMlmI8P!VKHZe1oXPVtY@TVVs-=fThWydv9UoHwb_YK(C=V5mFM# zs6+ojJSnjk$Ww1c%AtoxspiV(Hv!rFf=819Is61P2$pDgyy=jRjT||S2 z>OS~oX{}2|G|my0zvV?2?l`ynA0XeaahCrpO)b6fF&;4s$Fz(?z(9Tkq10_57zZaB z1;RD;no%SBjdtNcTQ@ddB=4f#1}M8WiV?o8_hW*f6S8#;?xjK;H8uwuXE5%1E0v{L zthG#cxg@;?36mMaR0?03x09~DYrsVxBan#m??%l6V6Kl}#Fp1htlmtk1POa(@Xos&5p3}c$+lKoP4*Rt!fBMNp!tMtI4?S0+Ukc3skJ*yQku$W`cxIIr? zaxu=NL$EV;77`$M0mw&YCQ^@2ZAzD29Inyg`7+SJK|W4NrL8rhPE}FRz&@vR=pDzq z9tO*Vw^k^)<+GA!V@(vFsM+NY`P4-9Gby;S&_ejCJ0fFUqr8-j1v%aBRqg)K6VxzQj=W|B$_yupxe5R(PZe?|C$ns}AnS7z~hrpb54(%?X9HzML zE=j`(%eriD9s>WLZ?K=l2GY;slpdZ$t#INFjUZ!b71z?^T^$6HkCGKBLo_=6vbUa- zHT1r^KTo-`eVmAJjci8;9Z=Q4ELq$4qczTTTY>9QKB7nD*8PZke-ta z0r-gB?L^&w0H{eHWwyRshZ&I6irkMd(;-RuCsy&!6XNSsBlaheZUWdQtry|>Iu?L0 zw4;KBVtQKjFmI;EvVsq5=bKFa2nSq=h_pcI-BiqL~{VT!B1vQJQ3F|;5z=}76p%{rN}V49Y8r(S5W)6 zibnzBBd;jNd;=+x__dl2U`!?py&;wqRYem($p1=#Tn*=0{Bb)LeZsp)0%#!@QAiLT z-nmv2VBhLKVj+8u5Pe2oGn`Ek=BbQPdPzm59aUfcr=_Sfo1W~Y-|(eJUWc8TjV>id@( z=+N>Ov(GC9x+cL{yD|{^csic8qgOyrvNx7@b(;~)S=%l)Oj$n*0;5!U0UYr}nsSe>`{dG1^#Pg`2aLupA_^Nv>CYeS@>e$| zy606}<~C+P-zMtx1~?eVG+e{~VDq6f)pmMWY(&JTr46{(L>kqBLLECl`ETn{we5;L zf9KX~I?O7$bq(AGV>6}LEoAtxix*=$W%?t5A#`$GY$FVn?Wus?tLWY+%x zR-3ZY9LbOL>X2#FIsL#3B)tSgsCYsfDSnUMKBKS&8f4Y^xuU_9qnaC=og+M9IqB3T zG-04WX7_iSjJS|H#wrW^z_Av;YdTvEJ|>%*n(@3OZeR_oE#dD)3RyXfEA1R*S{K=G zT*83Ra_EDLjwUYu)DH+RzKWb=eL4Bjd$RH@S;+mrZ=c1m_@m1)N0KfO#0j|>+8A#8 zQJ-ex?6gH1h0gLUli0&wX4@N1yq@g%B-0e>NY~ShI9&Ef+FuEnsbmA|Kv$zwEyrcKJfh zQ!{L_;m|ehNiToA0oIhbvoDZm+JA2h6T00K^`Y&01|ecK`CV7z?oU1!-%%>s7dUqN z-YL1J`hNmsvg#f9ecuPFg#_L1wlN4)u%~t_s-RXufNluWkSPpld-qtA>RfpoY^{aS z??4QH$K(p@>=>$Kl3=W=EaQH!s-T{o7}M!5dv>#Ed2J_3fQlVYz}b=l2z`sx!Q&<+ ze;C5GSB+9xjk?CS88U~6DhWqOCY6m|NG5$as7C#0@=9gyT#zh-~78;g2wW*p7c&t``2Mv6^@0-8;rK{gmaH3wdw2e{o7alNGw- z`rgxz;;do$m1s@Py$GUyFDDbMh(VXr<=u@RUTpkeDS>NO3?HfJy6UB3_Uu#r^xeI9 zM3eRXlgxYZ#ccT4lZW{F&vEeI(?N2|`8WnbU2a;Wt8bS_(;bhR0`^VVscq>N^JI-; z$*&g6C>T51e}%gxZr%_zInz)`XFc9Ak-L;iE?jEVx^WGr1%jLz=g4&{2swh1P~a)Q z0-Blp#Opd@6n|ZBgKtRR*DpAZGp`+KkcfB9Z_@Jxlj^0^EcX<-s5-&Q%qM_2BJOe0 zQu5HVC4+gH`Ru*-Hf^*Fo!i5U_hh@Oy^F8vh!GF?<%XIykVAN5LBhe(zh+gx!^`mw zD5##G!wYzpMa^gsOhH~ca67o%I1ugq&;>GX5i$Uy0QXv;B5t^}GMKarAD0fS?C+%> zKB`~uHr;&tyoJZ%%S<7W5i*0cC|+8gBdLa=D~j&rPs$NoIO0tB``1CU4W2kFySyD10_h*x1H#iLmG@5!H1zP% zfh(@T6?mxNZj9n4mDOPSe#g2P=z0l8_TYWDR`P*G4jbmhB$lzbz8t*)a+vLLbW5w0 z6uz%}4YYFad!fei69my&ybM1yMcctgs5iC+=>3^o6Mku%KbaWg5#GJ;eYzLAgsjxA zo}JSpyEW1qMUB-1Y}6ZAUcm7k2Gc{3fr+8XCdwJo3*Z|4>^Ux>i~V2{m8(9D?&jJg zD7s_cXt*UdImc^g3uKVi)nx8;n>9vcjjrOc=qG_M#bP$1 zm#&R1C^zG+bc=xg+0(jKbUbwbuc$;Rq>QWLGL-CD^Tp|;W>NTJO5{*k@#P61G!hS1 zz5&A|@6k^3ob~qdiR5KjZOgnF4ZT?y5FYDRd(5CHa<;8M@{|wBoCghz_@vN>ZZ+Q^ z580(Ns6Z&ZDNjf*nS$>>Ks^ms7-{6q0qfes+SZbgk)bj4is?sAbOx^L*|5!Tio~!H zce80wuk2SzMZUO557p21qG!sH+Q8Bivmp(=8%hafGr-g=OI>y-#!ZXyn=KQ zX=CF1M7iMe*8t<~z|L3a{{REUZ9ozy!xpDOcImHpMvXY1dSF+KqYuV+{>RX>QeASi zuN0kWZ$oE4g^KxB(lNE__ey!HMI=&uYR#DWIy6XJUd>h*W42jc@;)F570VLc>Z=+% z0Z##hgsMb-w2s6P=R@S%cR*ZI2u93PALXU^!O&QggJHW+o6El&_CWOq;q&_qvOUBt z74%#gO|W5pme2t0t9%H8{TW}jN~HWVlOem3${;^%wTD8@ra)f<5>vjsym`10?late zaD!%cU*7pno#`mokERYMQ-#d)}G?TpO^Udq!G9Ie(kV-6f@ zV+dgfUIvZ3x_I4Pmk3~YYNP|nK6rGkG6AXUM&6gBS;%1F_egxU+|hg3-}BO(`a5j; zLqY<)j&;7J^8^syy3G1KeZNBiBxl{%ldS#8949g6+WkTB=8@kOKVU$E&LbCWg6IJS zUxz5oeqKs^t+HCa=DKLsTj^p>O<;|`J>psP`OD9L&`y}#1Vq+}4`%m1`6=W|^R8+( znDxRyKe$rl*)@S`y9WxqPOM7wn%Se(ev;j*ZoH%Z za4j!hmYz3wneuvK4eu+>pyO1#-oJ9cfa^AnURuQ(#MzzA@`5ZAwDjBR28k!eyD3Pf z6 z8rREU+(~j?Xb`n6X|W;)L93jWAs&h8beJ98Yjj0KWtK@agCdKSz?{?98rnzcnKwnd zJt*TUQCZZXb-drcTw^&`^pkw!9ETw0@hHt6tY8IovyIG50x1`nfe0Zd-oscrO75jL zlt6ku{N0d8n@7d`uO#KR^on!aH+h{mljf4bpY$vIl;>>9Krp9tRA zh6awlGaW)~!zfbmtHnx#WBU`8ZS`c0{i>z5OER1o2idw?b?O>F8wab*() z069(0#Z%i!c3?BgL&~*=?&D-(pl?Z$_Q>aGg~)SRdLbVM4Kjcyh217G$06Y+sq@r5 z!k;IyHR;^$&n?|Xv?!qv3zZ-xW#D+Jbu{FGjCLAK#;Wn8CDIXK86EJApEw*&&ri>- zP2;-^t&7b&zqJ3QD)OgsWTd>aW~IJ$1>njrdc1Z!=ewSCy?%r_!@#ll<%ExCgo^IR zitzsd?m!X0i}rk>`jaya!qyC{EI1!hLa!@@$y~aa=^S=cw+wx&8s1gAwz03+?%VxW z5HT|Pjj^RprDl3q=5Ac>oFpEM2a=6hj^ARGFT*OsOVyS<&vVd#9h-)W9;**#{VSEY z%W=PY^e#stGO;X8WM~MNlPhnQv%}SJ_Ujhz+`Su};fX$&0zzaoOY#M7%|6*)x3+E; zZVPtqUKcLL*p1t=`VBY`Ky|6dhHp-1-9E$GciT|Ow}E2rL|o3?;6JzxX*v)>>(5?) z?A-5Xmy~W_qx)6cLU^B<+irk;OGNjF@SFXr*w5O$>v;Vv-!LLBV$K=SF*B936K-*f zuy=UZ#b@g&I{sd5m$zl%TsE@tuH#(c8<8=81EKO#@M@f_9zIJr)}c0A_azaVbn!Z@ z)}kqZD9+0&gv)@9cpz&|N0$arI9oJ2sfHvLzzQmBSobeng_{=TdiBBuyHF1zPb9>> zN$u?()cqmN&K9#bz--!+NMOfOICr19Z=cTB8~R?oJ;P@9j^D9d6UMO^Py^r>qn>1Q zuDa#N07NhYMWj_TCQK@#CZBT!d@V8nKZ=?gas|uii^{1H1;F!DT1O+?)NYE1hz?m3 z4D2%DPN=2njXo@adO-dlBn>4KP)877nhycl0QN7xH$A5Dy9{m4=c|csa%f%0x=*HH z^d<-CW#;Sto$tjl^bj#%L2yIF^9M!fmqRXFjr&(D+^jCd!fmTaF=cZ{#GdZjFm{dS zF9&kFcNpVcF^(jDr|vE;4hBDThEU5aCb0#r8u_4S$ zhX^7)vSF84;%r5YQt5(c&4yM7nTpHZ>v$blmbX{ROa*Do#~-+R2UwprP? zINQCKA>9I4%G5~p0BV;9g5&%5oRR07t=n5}#kTA_M&WaL8^`_ErQI&kGcL$m5tTr; z@20H0H?J8T`QvNaHjErkZtWPmeD1_U3elckM2iVb{a0rqd6n+`xtwz6-P)<`OUH1> z+_$^Y^v3a)ZsNh;{@&C@yF?zKEdDp`dg(fz9US9i{{S$m^n5WHIW{q7CEY5jVw`dC zpbn&s5Xg*-Ztl?n{3wZ1jC*9#2E0N6`AN!=i42R58{Yd~L~!iqLM?LH?TO_$A6DPY z5WL^NFGu?QXNHy@RC93ga_yg^Ce&^Z`GdESUPpY-3qrKz!9{y#wlhCFvfbFon*M}Al0Bj^Z7ztklBsi#y( zulZ}&+F278<~ySyZT|oZyhg3Yv{x3cTF0|we`?r`L48Ys+7C)CNSc{YkOT|C0_D{L zKnVk?l7QsVG(A0th*_wOZAAb;<;@9SVTJf8&=pkH`JhpVtJMNLKtR)}bpTKV34>`= zQkVFs(VP^i5t!7~MOL~vp!09kJV{;IW1j%`w!6^Di*g6*9|gb8=S+T+!-}_ZHzOIu z{WAhlJqUH`Vb5>SHsy<%62cSo?jQ2bi(H+5E-NEGI8(W9a&id(4l7o(C!Ap1&&azTN{C;ii>0ZGi#|<^slx5YU`y&%HC|X#XE5+gKFs@=(j>GWqL^wg$laEZE#RkfSG126JgP57RUM?0!Bb1}@+0v1pnv7$%mooHkL6{ncp{zoNgf1_NS0`RPF%c^ zJRC5lf0fefM@IzEGMP<3@&xc!Kt|rfMNB?84^G!AXOy)s`&?qun+M>v^*+FGW27SO z#Y+?He0I|#_*KQz#@kRk2|U?MPqF_1?PiCw~Y%|{uex!zpan# z7;Q#J{W2S(eGjs6v=Gk^8Yj^E9(I{gq4HPy*X+3{rhA7$u!Zc-J8$!7A` zwEqD7WryLZPpet{AeXkJ9i!pVCn>1Mwyu9e@>a-gOCM^^MT|UDv8-t0`%*FfO7mH* z$lbH;>u>;e3Ts7+U1u#jJ7udi?F_Q%IcR#Y$AbbWHCeH?4sPQZg7W#RIcD_YcP-nu zzv|OYi=>WSbmDUNNzPL3I_kPkTzc(~JLX5YmplUAIoqnzxK60XqB7U)K*K-ah=|FU zsiGq{elDh|guOXxp`la@?LeNafdmN9pdN04RRKVq0zeNG1p+`v-iNS2xay0e*W!gF zL1YVx1In&}1JIyv&!Q}cPy|BejS>U}5FUsR?nHy3)w-gHsn(t-J$qgY4~TDR(fqig zC1wYQ6jLN9fvx+H24_Gt;Y2i^t~EeO(awmn8bGfP@kO->6@3w7XKVsjOh7LxM04Z= zYPx=2-Twe9<>`BW=`LRWY-R74{{Y!`!S$Fh{KUqrB54QfUW>OGLm4Hd#~i|`Z?BSZ(4aq>9^Y{LRv~z!}dpjGCwuH zt2ViP*WCXAmbZ3sfVFlJm!)pt0C)Dd`c%SK$-Bg}w{61d$egcbUzwHa7c!Bris93w zt#5wcgtotIVTndVYsCD$xWs-M2}#cr+>+m_^YZg3Tkn1^!D4%K_UiUga?W*_T@$zJ zL$tX5S;c|*tJHFIdv(m6uH~DMx-Ci>4fy+efuV85)x%!Vv+lFED_0HEFabWJ_Kwq2 z6VY^>>o()O$Gwd^ma+y>^sWc=ra_QBC8-Of@XfC42i-8VV{b0xFIkxa+}-8}P}N$z zYJJ^co*w6AtzQ$524deDg`B*#F0k{q44HQvTkIsy!koCPI*aAW?_STnxx|aRZJUsA z0Du#T;aI(VRsR65^0GX4+#jVk?8@!Ux)a4QucL4oLR9`=<{vdIYaTnFwPxU5HZttW z&A?~~p&ST06`WRFvB=iELdGtjIOCU^&E;iAarsx8nAVW8QxN|EN}QC%*J17d0Az1F z{NXEBPCh9ta;^hW{#fx=b8n|E{{U~{^xw39O*Vak)Ngt|wpjzeD(z?BIe9LVi9NYx z>&<#E_N>R#v;ZQSEyDO$Hq5@G$3;&zDNZEIw?t%NXahtN%+Z_08opJXh~SCvZ0AH*hv`?1L~GF*+;pE z)3n#YWAx{FBb)YL>K;ztX9E*=h3xH%D4Tn3;|oOIu_&6t=_l#{7kyhr!;Y^j?eCcR zczL+i^6;{)W#Zm{PbSoap(ZtAID)-0%8#9YTDF@CxFjrq$LamA~!v_PCEXzE88 zks(#j^_gPxUKwj6HaA;t+oOUeduNj%NfA1^E0>6>d62eWGy#`t#lvo3I0TZ>J`T0l zl#>$Jo+ZxXdlUV-^sLLbE4opDAhW~(?nN2aJ{5Cp%i8g;+x(^t?7Ya9v2x=|J;t5J z*mrGIA5wmw&maE)k7MI)d(G|V9yvE7pN)Rhp&0tM$v%vvDcLxKMZeDFOBVLM)BVqN z->{$n#@gj(5W8Qh;S%qzl;piU_5T3#<1!wZ+_0zXj zPF*j(cN>}6cwW=mTK-mb*d5|5;uz+lCR{t2&qd$%?|i$43AQf1|B=`&qeR-F70kr#FAqFs^n>cVobnzo4} z7K}kX#0txrVjR?}U=Gw!0s9mKpjLz0QL8|J4_;~z(Zy8<0o7HWLngi6CV*(V*8I5%Ep}XP01JU0Frr%6t%8=wD7j+ z%z$FEX143GHt0YO;F2qH)FEsL#CfX2Qy&`T=>Q`|zJEJX^^T(hWSrUI-0QzTi-%vU zu*BJ+Xag;IF7upl>$dHj866_PYF3l%(~cx90Wb+G6<4fI*$)`kij`$(TVexHaVs^x zSAYTzxz^*4-}e6i&q7_t=mYSr^AgvO=k0c}?iPp@pjhkjYoF21PmVd6s z{`$wc?fDMqz%dIqi>*$P+S&54rX>kT0a_Kx{%(`JYKs{&i0_e;a4SF7-`$&+wp_g6 zMuBc}=hcim+g#x$FeLDz-}SNg2<+D;!?#tb`4_e8djz5@2U`BNe(As2;Tm=a<3)an z_Ef*L_X0b50;T0=M%ecJHI#MLC+DT z>|xl*VnV;xpK<>HWh7EQY@gRt?n7joxCf;bpPBbf9hO0!D*pgk{f7Slv6p()KdCVbaFfoSM^E}t|CgHuzY0M+}Eeg}i17lH!+06h=~I{XkS z@%SJhG6aEBnhhy@TI*r7oI=Trw&3&Y}sgBH+bOWhYbFQ58ucW=H>?~htT83V1 zVU@kk25`)~7qw`SNLhhDi~PlR=b0X!c*kBh+*~Oc?!;OedY7XjWcB(Y9Fx?rT|Soj zZdi6^`(oXUjNGdR<&192mMmk=H%DmvHw=4#?gqb8wrFdupvYRW+x1FrSOEW6u{cM{iSeBdAGVU~#qzwrwGUV|6k-g$t z$K7*%3sy5Ge<>^XV`@Y-Coc98k0&)*oJ-}a*TaJME7DNv33zQ z9(M^1GcTq+03W?{)^Q=s^s=BX-<6XQ+b#k?>rb(6beQOI{l+%?(KwkGCuFd$-e^sP}dN1c>Ce%$V2hnH{5-1w1dc zIos`*X*GQnWh}vrMIWj+>76>rlT>Ei7}L!S@_A+i=%%$QrN$_(cZS|E36g(_age)-uh#K=ab z1n7K<^7GfjtDDTdGiGB1h+yNjp)h-WM`B4FY8`GQGZO5sTEA}n+2z<^ZbAj+0`!o5 zMJkpJ+w+ikd*%H8V`@4n+l5iT5RvxDfb)BKrV+p@67mAuSoVjj~u zMr{kXEtyH25@yU&dmer5J?i!?t=`9b`9Um#NPq(fgbxC2S|h|M zYWXhtkEDkPYsTYj?LO?kh<=+nv7MNX9oEmOZ{rCNydS4IUhZ$(oppT5=F?|j%orQS z4oNL*)E4fa@=xhM2VDOENwIi)z+hPUt^ypGI0Td1p#Yvf3R9MCqYPWOEwGF-3`}Uv zDAV^NSJP(PgoQlSVx)2YD$9r!eO97~1yG3t#Q=Ut1MAHIWsL0)Qv24WIo=4|%N8!Q6{^iI205<{VrdpcwobPe_qud5o?2)nHOZhDx>(U?Q znbXN%`p;{5>i+QKbqh>@lz2VQw_k zo{LkROVgvl+9e|n=+yCL+mFf1uhrh|yDVY>lv~AmdEz|x^tIL6#ExnlM(oemXT;%0yOw6>vCc#%0PWm zVaaB;!OOXF?4@o3pVY54E1kKr+PO1w=rfrv<#mo&WVVY>+Z$!{S0T1CuKRXTl%zvF zLZ4WDtY=->$fGCHHTNyUwbJQz2#J!jM zFoAy2){9ur*va6C4LlPG(?0GrMNC)~F|V?X%y`Fxa#^uuKN`n<0AbBp3)5QOBw#dm z)U8Oz*vptxlaU=&`k!TKV21jl+*WaZ%JRV<(a}Zw8Tlxecrzv+WOBfXpc-mZ7wl|s zhJZbEOg_aOxEe@1tMzB>c-!GY+QB}n_DdbU2l+uysi#K*F2)VjlMM-N;r{>)2CCuq zGx9M4k@8QfeT(uTzY2X<>}2t!7@pX?xJ5BE;e~o}iEhKhaaRwr&8!%Z<~}a2GpWW1 zIuDY+Q%mwU9+3^rF%FIs>k;6Xx{zQJe+xwPR}<~!G;o@NJxNcgx|HJp$Fce>-wj0! ztC6)5{{TxaT|03cc6RS-(U9*B7Y^&!`SQb-_ufg2wcxos_*1*R&N421QbfH(QTGRK zvLReP(yYVWQ6J1da*N>U`;1rnf{HH1Tb|~-}i$% zDIgW$uM`Trd=NIg(W8L#2+gI(n*<1+e-t5p?=%RpL(w->144(u_0f1E=pmn~`J%jZiIg^F@@Z=$ZwEcpyTB`RaiEsA+tZXD5x?#4Z)f|HHW-*u?2K!Zl_B(6j}m#7(0$8Oopj@mv*@jlY1;k2g+04zfH@*V z^Lc0LyLMmkcDEiLOuKW=J#(4Ms2-((DP~)qUEFW(UB)zpsG6BfxB{H@Taj=1U|;th z9!bkF+O3#ewqa`h%U-qnhd?4p5Vs!yx=CltKY8gc*S13T*$X?C9qX9pFFm%=jhIRf z?{;MO_KsBXS-oXg<^9LK;bU9O+w5SSv+0Cmg&S-pBK@bkx{>1gq)S{){qp{IdPEZUywmS)yo*~l<~;5&(kJRh_q zt6W#TEZy7f%HC!b%XwKK3|UMFdO|1aBetdVPW?B_&;I}+J067PI9wOnLLxxQwQ>P0 zJXZ~FIxWi%SlAd-?tqwcAWz{2pbo2F4E(0KY-D~;@r^QZjk;9#!N!X`qgUBk(zBnD zjvyi@Ze6Y%cS51x!ERqE)Y$1SXXJinU`x@FB4vR95L~qbE|hI#?pJd#v7{ptJ90ju zBD54&SkEroWZX7<-M;n_?*9OBjko;mi%^_|Km^8O;bUG*wa-|VE9PNk?IzYnG_H#m zL)x9d2h>Gr+`7)0v9;~p>o?TL^>+a)QJ42Ecf>qKrX-qt6Rx%rWp=kc%{v*>yJtQb zxZSbz?b~M^0RUC?b%~ZW>DX<)=)=j6ZTrI2(BeX4wxXxSaqFD)>n^Ns7Iw||ZM}xOCzaC#h_8Qe z;0an|{F!q$aG-~Gf-cp6%*JQBZ4xvbRmN&aWJW}}1}GaNW^O|!3bBh!zu-TIieaZ* ziKqu%6BSUznlll_OhaW7JQc;X$xsHOh+zfXgcP?N3tOfnu`b-bW}1$o*ALtB z-!t2<=hMtRyOn2iw=IWuy=NaR-j&UU{NQKXD8#_nBBC&t3TnKro+CDSc{?svPDRPc z=E~T@#KVzdG!qhxOEacpUc)ad@>$WAC>Y}+!2H%6CF%=Tqy%P3eI(z_!E^36%OiN& zKQkC*U|P2fI}kUs@a-4$yNygha$;M_Yo5-za~Kh~Z@zMSR_8d2StOp<*Ro)LDO;>M z9Ahj=%J9aqwnik0WPhtO($GBC2djH0D8lxCtzzG!a~AZjT$k06+F*OGkTfNPdsH03 zKa#|=J+{PiZ_LWvtVM*oE!;4a;tLREO17!Z_G4$;8*U~&>zUKr_bd^M7~jaVlXugx zF%m(Gf()JbXsuYQxo_G2IHR_8nBHgLaJ zaklJiEw={{OA8(`vyW!v1f>WHL`qysab0=p^2O&}ZQs=mvlbRke&1$syjnA~NIxag ze%&*FINsYmZ4K?4(D|T$ZNb$8#O}vKuLUu5-sx!}uB8#?KK`*R zd)QmWq4n4?xgt5(E=QasSDW{rFJJoiW;P)>U4$+`_d?`Ep)O#D2jIM}zu_SGaw;D$ zd)ae8KegcH5(&F#3!m}B>6gqeHSpbNW=O*mChTGA%FU_Wji&&}!X{myng?XfW;`!& z_m{Z0JdbZ=Z5WW9th>VR`%W8PyFW(YjNx|o@`4C70CinIubD3US#7U$u@6oW4oTwW z*CeYWim?dLjw=0>oRT@6_N)?DP z1UPz^boM8)W>(`NE3&&OOS)5%dMah41P)m6grGPz3@&r6CYWAOTY%SPvB~X~XXR``NH=oJ=15>v4Y3i;49_OZ@jg z2u!s%Kg*2Way{F-!ZOdzx3%D1J)>{IkrF*8b5rD-Atk=m@IAkek00$>4r?izl6ku2 z*XZxh5;|;cv_**?3yfE=90T%7iHF4(t{{Y1p{{ZbwD{X4Wj0=+-$ zb^ictdH(=;l3(GALN%w{y{|h1E(X@=i*_UF$%(OZ$5^XBh1{-(7j3z4iB2@)7jAzm zS-s=1+ct9|2WGmKUXFh^pRdu^t;wW|wPCH$r%f@)b>FtPN9qMFt; zEd2wUELy3%<#4=@)4&CtX*_Mok7(?5HFAV)O4;ug%C*uhf@<$eqMlaD7ts$gEMQYCYo&skOXSA ziS|5NH8Y^(t|JcCkgQBV&=s!?`7&5z@c~t@2a}^MvpdoTai(l4;H>0RVc>M{+bk7F=95I$&P}Enl|y}B6$ju%36_EEXLTBiJ;Ne z9eIx?_fGo^XwT~baPGaopAR0E^LIAv{_DG~6bS$?Z8jYD$NhY%agz$ynWFC|czXHgCxl<_-kwFT_L5>^dn112 zM2t@>aju-%)|kC4@7vt(VcXjArRu~;T+F)&m_k>`(nOx=o+QeTr52}#t+ck^X=ckm z6E^PcI2>rka?CAxFLFf6QXJia&a)mzk#8d=!NyY`Cp`&KPnn(MX;cRjOq)+M~lqd&L4a)gXrN-oj>fIwQ43vG^5-WeA+2<42} z7so!JHmx4xb3-flq)BEh1FZGs)0ZK$TiAwVZSFX?ClLus618>2=HEzT+BM?jc&>BX zS6xQqvO@mPZzN`8o2FF4w=;5a5&omvA{SiP=WbR;9z2dN7?J+~Ln*yLU+9?q;c?$9 ziuUZ?+xM$;H{l3E=X_ub1}47{t-cBA)7;C$85dx0+_w=ogEYH=Sz++G@~q46J7Rdc-}ifqBdac*>N2Cpk>cVj>@lxKIxTn^&8R z$wPG7?OU^xX69Bk$(W3sU}fk++aFMn9KM7WSnKnb)2}^k@V9R+S%Tg0(aOQS-xv@F zeYt%zi5drud_w0Z)OA&0MFy>++Z7-rj}#GHEk&r60f`zG=&6wb5_tfor`1kYq)v`j zwVE;_APGlLf-WJQ*9;`V6AZU}i3pYhnAKAgO5lr=BhYGzh8xlhM{jZ9uY~fC)}L?^ zV;(H7Lu^Mpn|`piL0}%5d{o2i5xZ(~k@YA!CNJ2-k|2JcsyaW4my=ZY&EnS0w%^aW zrLgbfn75~hZadevJegm7?qcsakjRCYM(5^j zeK(9`eyE#z8AqcnbNlr@vDf7{!_q8!&t}fr?rwW-Z{|HO{{RGz%fxX#vfvk6`^?zq zKRYYuuXSbNZkvuq_q5rD-;s#`Z(~~lyMZKK9Em!wH(hOZocMM4LO-ZGOtLoXHpjiT zJb1$==!b4in6q4f)XE}-Ult_s;pI00vwm12%&z51;r#wg!HlCJ{I9H7yRLmthWTyn z)4gUw<-C5`7rx8WZqDGk8V{>EJ@(vzORPJ5N0!HL<yqnULq-5X=CgkbFicqaz1c-0o`kPFn9^4$vn`8aJ*^glpwq+SW#1j??iv|2Lm_|T_=-A!s)8&t&QcIBwt zw;4iFpqSK;B@5!cH(~c>`xCR3x8_dW*s(pbF`Q2qWoKB;=3j59J*U0lexTu;T+lK1 zyfNK#HUI;1-ks7K5)Z|9=k>BY-%mMIGjT8N*>~{r7+uGajEKv zbtmGf>{=3UsD$)*GIpX}fhD*VG{-OQOc9r~Wj(n)kM6Op2h%bC0ECr~(r+%GmCl@( zwsH;Ks@;o{d$<#xEyKtAXX!q1W#O+~_TPO6GNQdp*m=G9xwsN8aqbJ&zu>t--UKcm zq{_bIzm-7-poSxuD+-~9w(a|Mvugtm#ud418xV{i#f4NC;&=f3kt`WVLNc7>(1BsvkNh| zY!2aV+ES@H3SdSe&soOnaO5YnX#& z<6uil+-m;-$_iyobK`6Gcf2HJyk{IOzqpU~+-J5asF2kE0L)Xz$Cdi;wytlr@V&Q( zitwZ5VsL4WPT*n#O60336`Z@Ol4(v-ErC5)M~X8HJgwQHKQO*t{=ky9J<%p zoMvLrGUVhlU<420Ze3N0l{Dhrzy^;3tV~k5Vp0ukIW&}t)}|@k#ErT$$m)0mF+%P% zS%`DV4L~u-htU_GBsE^9^==vu89O$MLcgUcOY4z{90Cg-m@xo`QpU7|J7~c23n?i|GzF@oT5ZS< z8uMkYQn533%h}zd^H(wLf((QxWzp8{m5VJ~jgg6N)u_T#4BW|CZ_`EsA^?anDT;7` zF7zA%mH=Z`XXc`Olx>khC>E6OPE=t0l~MG`V#psGMZ?f&07fshh*~^#Iw?t3t=l6| z8rf$p9Kx$p9nG(V?%BG9R;}LfSCZ85f{nfps28 z5dQ!a3z7lAphkfj5y2TMF{Ka}(Eww|P=N9KPyx%}fS^=BkT1Cb=z$NC1P{+Zfc^AE z(&YN07b@$;0O#>VlzjY9v~}?2iXX5*OY!(1N5{znhxnlm1CFh#4`T!DSbR7nioc)u zA*2BvUs8kv!0Xi%7>4nBAVhHex}a|cI_g3Y!tO{ONY;6Kx3)dKEvIRX!)@}i4YRlz zQ|q7Lv^)l*#dhLkdj9}EWRBe0y_YL^P?5U}AdH*RZrED`PZu<0(Q2-Bt)ttv@nvr1 z!?@(aUzd%-(`kn9ly!)$DCfahPpaO{vrZ;Cx1;%jew=$o67?=dBT)j(ABkbas+h;K zb0$0XRPwBUy5;9U*tu@gOu`YbY+LDQXza;XS8(=yx>$L6H*&7uzl-1KmW{k?S7iOL zh^(&2J1`odUPZrN${Ba9X5YJd^`g_A>c}7IsVvJqGi#d9+ww)-ve%|3YbIjl;APtZ zY!K#h;44*}Z;JIxn@%mu9&<6XJ* z_1H&iwYTm#I7jmWcE!6l@~s1QMC&L-OSTWxlD!eEoNSX@v&@1EJMF>C62XISLK23y|;JVcQ0DjOl~x7*^WG7THHYHAeSY{IxTO4 zJ6*2!RxU0sH+{I>vkt)y^WI{A8SNyN>ZQ8Oj>i_{uj5^W%YkdOwzc3F9`Bc4TnR}lw%)IMo}MxMn{iO>vzm2w{epum@)hpM|6I|rw3C}+a!iMy0)Q85^_OyNkkGd zEx|k`nvBVbe-Kua>|u~DLeKbFbqu2^5*C@0P|qKa;zG<)xn^L~g%VUy$;igS7EX3` zj2Pry7Hwb1pJl${38_5-txk8-#Qn*UzFxn$`0m{YN^6g-H*tX1U$X<|)A!y1( zNI7!is~z7t9*#NB4{pWvt=h93i5s^gZX)dX%1j*6i*e;iF4=bzQORpeRD|PLb_V1e zC)qD6QMYa*>yK|PD*d%F%X{A3GCi}n$NFu!9tw4QQy(xj!T3!L0qf#dk6xyp&#>-( z;oWeyoxUIUIkWAI<@jM3j_FMF0;#Ou4^8)Xw7s9OY;)S78LgXPJdx0^7OdSt*l9nv%8CN$5?Ai7=jf*;X_wjGOEFgPlVqm<5$muAP zN>Hm49mlwi-|uav=ef3QLAU#Z97^Z9w#zV|rFhVcjA9*&Ig}5GRB>2YaldZXM0*Y4 zSWb3L!X+9KOf~Zh7BxJ^_8xe~j3s~7#NAG2;%)jdSaiY|0|#D-r~?=*yp1%W`CPyRF&n z{@U9wM%fvb@+2WSiO7N>_`sfyHD!;^{{Y&x+|FYs3$om9PjIzz7xAb0y_-7Zk8R7Q zQ6>@+4Iq4YF13jjA~W-Gvg129{d}9<;t`DHF49b;DC)qh@0VQg&yLe}Her)itIJ)3#l#92852W#ny{@e;}=*|HkU zB7TA&f~@?VhqYVAncOX82xCGd%o6nRRWs^g~(-rwQ3>vDC{CzO5L zxGgMm7veMt_;08BCpMmL`mH@}=Eo_8jMC^h_>4DNw0m?T;|pME3pra@%fw zKbeQA5NZ9(2eMxnn3dq}Wqak`b=OIl)w--JruL3!AWY)5Q$GQIiKjDA*fLy;x z<5!opf^=pjaZ_d62u|eYAs7QG&P9L%q?5=gX(hKITDflZxLvg&J9lCy363!#!Sf2j z%(#%AD9QtO9>Ye0S^*H}k}7L+GKi6ZwoCmdUY`_9NNeO3K+>rKObJMA&EA zBv=&%Oq{H2I}^#vzi$&B*m>W(AqbB$ny)w9e^IR6xN!Zkw_M(`WP4+mF(_k$%m(hC zl{%@H{u6(Q#JTOCa(j+5%l9_pIop6UhS_iEwi={%3TgdLQ)KkNU*+lBC$)B+w#~WX z*?yrGvtLE*SW9e?{_jejlt{;C6pI<;Yw z>vkm={{U!{^_c;}I+s|SUY7Sc^7C81@85SjexBQkFf0-O0Kdu=Zg97$^IndB)t@Zi z-rr1^ZPw>>WanMEx#nx@WET734eINv^NO1f|ef^_lG6&2VEke##mWfCRe zQDfLYPj?w-dw(AuU+ZntIQLKdGzZKtf9KZn@L86}p~B32yQ5dui&nKE@{o(f4)Qn+ z6g4O^5s8oxk1i^Fsj{4ANRQLVs3P>HWC1kdRBHm}Of3QcGmz1ib*UA9Ig@w*B49Ya zr@?1csf}tOrP@dJcNa~?X~0{L(lt;CcS@0y1YATQp%?nX>9`i~es4^`|K*lm? z{{T{%fw8}D8Y8+?ZB(^s-xMGtcdqE?MD$b=gh!u-;K+$Z!cLInLwHU<7tHoUv#34CK5v-yd#Y+_t$C3U~ z9;;HJo{3_`Gzi+Rj@qU!5w!LAsfdik3Tk*nD7s{9&HlCzpd1#k)X}%xTS3W{LiDRm z0t4xiYKEWahAbR&Mx`rOr6)3vYiJPnRZeVwIxtQ((=OLHfcgOOQhQIcLNF!t?Foo6 zZ{-fjf0zi-?1EU~M)c|%sY64Ap4k#DzK#`$FNdiFH z0bU3fh9+FP=p9oxSk@?aWzde7+B<*e_nR`6v2xxY_snJZOo93V@HO&RndRH_pD%FUZC^zW;CoU{YF>rK*U5xgh~331-a$9BT`sc_T`57nQ+9ti#wQ@_ap_= zJ!Lk8Tt|R&;LAx~HM#9uos4bgbIi5=*^BB%8)d6^0W*=(A}&c_Jh+v|t2NquV+(7u z>s-K|Rs?NNBJh+m36Xe$0To>9qtY#UhC((Y8B8Ch++$iU@yD-ED#-^Ee!59DyiDLf z%y|4)AJQy(#PFe??WpHM)fhyWf)5QBE_(BejeVlQ*>c{!xAmsIY`E*qVLU1=l=i?O2XVTZ|wg7m&CyrY+Ji;*2_QJjj>Op9ZaQKlSSGy z;n3q*$;iQ#$bn`tJ=bkV`;G>Y4nD34@|hJz(T$u%ySXu)+?R$%J2OW@3_}V8)9To@ zvEl95`0@3O;fWsGa-5h(CxAQ_V%W2bi)Pi!x9z~%mFYahht*m+92^CzlKE;|$Hq49 zOxhm2sT+*a^E$BPvA0`Qh0}@OBXGh$^+vAMqP9wmJn4(M@|D=UWF4hfEvjZj`E|CX z8`xNPBNmTwfb$RcE`0lL&jBd*zXBH7L}w>3Ta| zgA?jnw;#uQx!8C3EqCHCH_wlU8SL%0-sA31Z0%UtxmU4n<{aGo83HVS+r-F8#F|Ep zqUSui{jOboc`GDH(QW6=kID<0-G_;=g5 z8c{r5Re6Tt`g6ABT#>auO5MUwryvYL^L5VtQnxz5_UGwl!E1Gp-iAcROkZx675kX? zJzGP*KpS!uFa?=U>cqERA?}QA!))I7J-qLivtfAL^sVGhM9H0{DM*lHLwK%Vrx%w_ zafPz)89v#|wRioq5_j(&%!p=N?ub2OBgAoB@0R@}-uEqwI^IS`C+4v)nA;bv!WQkv z)gh%8j-r%2R;6ag4=DDDTDJ&WgzGNj-7~~F;J1k?#y)@KF>gxD@^QBb&M~)>V(El^ zCOy%R2Cu;}Y*pK{y%|n4k93?!N>Cy7V;w4`i7RRu#uN3d5oU7_JgbuR?v@%rvx257 zJGo+DV*dcAYw;XlUPOwUmroPXJtJEVHm>#)FQ(XF1+g~M=>@?tI)+@Vbah_oxs7XO z+3{m);WslSJJ#YQYq%R-trIsShvF7LDdyI?yOGP-FO_E8%;g+;n^@SnFC%VpjY)~o z$nsq}*u2Qs$lr1?W7%Rx6PzN~;!DS}k+w;r5FM5{=UqDK$KA-5Rz&inemEvlKiG^+ ziSeT@@<`!rp>FOxV{$TtrXU2KL^Hih5yz4VGQTa62tv)4y>v&u++s&;gM-@|nz$;@ zDQ0GWpw^)a#Xae^nbTX0RPZg_o!xNh$C)_tDdp^gfAVsVz5SV(2fJqJJyYcDD z@7aUhnHB;OF(1sY%A^-AyGeohA_$wB_PO#=pt*1g_OL}7-m+u=0B2?4e4qN0(7<#YehZ%cu6#OY(r?XOjAIyx#v&1b z0uTTI0MG%#i=&;pP6tQT5MvmL83?qc_>UA0JR6EKa6pQ&LA?4Us30CH*rv*M?YDe{ zJBSf}B=8*2Nyot`B(j$38TYFc$-~rvfg}RXM?$RzHsfv}LLwuNH6{X{=qgkSr-d}0 zUTCJGgR+8-e&d0)GM{vr4 zj67jzeMEJU3g_~QxIW0-y~TDp{^;E=XWfM4BZT9&*@!&gGPpz_159ylr}r(%o@)RWLFv9e(BR*( zZw!NSFt?34S~DesMAKf0$5KMetZSQv&(3<*C+fm6lw&ypBE;|-mBRj+T|TZ?+&=2s zwwN2czI;u?{+1{&DIQU`8kEkvOVs7%n~%D^!@f+7w$J+}1n4rd2X*<5aks=*{H@y)#X)Koz+&_$1;&TrE)N7;5g4#8SrJ<8`*42R z&yp-<`u8#qrEXLN_sf7;zE&a_Q;g*~To5CIc8*E% zjQL236DYg!;I%6#v>*Z8O?!BGtEM2yxpTap;6pHscrD7sid+myC;X#dHLXlmy>2s; zN~45EiK$|h%W;X(&VUXIrX#Tu38NhrrDn#hxPSxGiI4A9F)6na=5&VF2RSyq8FhHag-qdB`?Q6-c{9CIPVuU0*<09n_p8k5JNj;Xb0|E)x;f_ zC-laV(3Oxyn7}#LkU)JSF{K8G872gX>NP89QMEZ2qm5MDUv%>cMv?%_ikiMs!XN?N z5(fmdl=$|O^p;r!LF7RolCJntj6SZ=%zg^%F(J1e)`(_PR|C@iQVfp(qJ;b59^x1d zJy38y=g&4Q+%l6esQIk*WRCv;pD&d6{Hbo6l;hm+gqeAIzFz4(V?zTBLNNe-70%Y9 zPT&@x=TWK-H*(51Wg!90eN)CyV}>L`5B z0zv>!B7pD+5I}mMNCzLe0MWxgGzpv_9!Sy8L}Uecw?rw$v_KzDXb;)R0yLrkYv6=0 z3LrdwT)z4H{vY&>p`<5RN0qNpUCOR?Jp#!x0kPZkKLvVJYH9Z*I z{82rY@(chM< zyl)T8xn}--n^_;<$F)CBHb{wa5+&Oxny{g*6*XHwZpHrqe#hK#G9YbQiTvh7$d!oC z@e4M9q@)1QJ$NUjg{*DrSlfxo$2a3+8rX<=z*1LB z03r((5%Wvn&o4Rl?aTM~9?Ld+?p_~7*;_XZL)3_Z9JY&;^Gfs_Jh5+b^fR!{%zWPQ ziz}Ao_QZalQZDcW)}kerv15MrEWa#gY9EvAv3fJ~?~yB{kS)gSjX*pi7SqLecf5`! z26S;_3l=TL5uS9c6Fi%jwK4S`Vj=kz%eQ`ZneALlo1X8s+04rHF(lKDMZ#{JYf~kG zF2J>0&0;lU>KT5X>`~j}b85SGS&;%*`SZKnBwJDdX7FB)dU3sfFA>~*nPlZZg3e?PF8g=Ea+N+dg#TEPSr$8*%{lnfCU$1k@f2=l-Ac z>Q_lNF>aW9Yur}$z0vV6?b(pAdm1t_vpX^X`k=i@iF$?V>zwkQ-%rEa+hwaZ?!s3t z+O_@LP?XQ4@*j(`G&IrIS<@Ng92e?;xF_t*hZA?k7w=s4;TY|)`Yc_OI5)`pghPH1 zYoh7LKW%G?z8vrAkLx9`cxB6L-m!7E?b1$g&5%Sc0aFp&Ndnd@_*F7cVq1K z?CjR#-;=mRo5V}B+mG^+&U&p$o>SrSzHUX$<8!@qOwKsg#9-&R)34L7HOKVpT{xKf zSM=N3{{ZdK#@;e*woR-U*|P%{F_uB~ZcCf?_KK}>S-pFYS~C(f47TQqcc3Yu(U4Uy z++`|+5Ki5>5@KqsRawA%6%^$wa6QLPC^>I(=G^}PZ=A7i%GO2|+j&^`;960YxoQs$ zR(tf&w0OE6ou$%FX7d!gSrdH=Sn)3bEV)qUv zG0M!w%gDmHIGl~hk5p?%vg7WU<{kwJBEaKBt;=OgKjeq8?a*)THoaj>`BM_mczh~;2d`W)M~8hFCiP( zA_c)Bco}gW62ymCyZzqa3?-~&3lQ8=#dJ6sf;kqCbR!7W<{m-079&U4$H>fcXF*!FK~dtmo$n@m4D5&r=7 z9FOl`amsT1Kk|UD+D}aVciW(rz4^1Jnt|Q+2Y0cT^IY7i%krEB0E)LRsixtoHo*h3Pvaoh6xn}KHS8h`5 zE&5mZ{dUh}zF~Ol)mmrZ{1AHo0I~B;{i0aXFFYHjAaU%U)gPO$H*+gj)3Ts$TG3?< z2Cfg1C=*xYf^Br-sC%6o%|ye1(Gce6s)x5abO1w!h?fG-z$u2WYvQ9M+VtRn4yw@MU*4bu z@cEz>=c2w8CDB3{HRj5+2r~C=?`qiW`unzZtT-R^?Z~~!^o6**qsm{$U#k_cn8Ch1C2;LFD00UHx+5EsO ze9Ww??%5KvjzEYJq=mzvF_0t8)_+d1u4bv_?uP6oZq1*jV0T=);CVz;u3dhhKF{}Gx%bD06~F#Dw@*vg0G?dq z(m#eCYrj8?p4{(!U+~7q+c7b2OCX74=1=`h+=&~PNk8V6o=dl{Ovxhu0CVfckE&xv zy?OFfC*z?&yM=3_0%kaT5k6M2F*38I{i{dQ8r_u#kz42Uwa>2PdJe&`o0nr56CmJ8 zg9Yj1@{`-o-|KIP_r1Qvaq(^1fbEO`01Xy9^IdqE7gib&Ine`U7|Fz#o9nsh&UDjUXei^c8RKaNLM=%u4KD0Ya#1GHQ}jMTR_Qq@V1YBu85q1zHZqb+2g z0$G9B-QSB)6~E+1Z`8Fo#t?9S5j+$V$V%j#)V&6PD+PPeg|gBna^Vr6R92ZLC5LQB z^y*N>VF}75;n^MlRF$b&Lv|6gKg@NC)I~``Ml2#?3%riM!D?1)Kx}q{+A6N58D`X@ z^-87b)is=4hyWh&<>*H>bi}c;>}OI%BCfMyVHN}u&#y*TOhO6M@W+P*SqTZai7XD0 zYLq;ozI#kkt=qG^Ug%pyD5rj@BF zX^DXPYAg0ArW-)GAaoyc0StR%@d6}zp@+)XWV;1;k`PJQB`_S*f(c>_NoHoLQDT;L z&f8r+UMUseKd3vXv5R@7QsO+|*UTjm{HjxKX@@2?fp(}nUw!P!;@OapNWQC!E1Dj=N-2#MygKp_;}YJnbo zYJqX35HAD;&n-1Tfo5$vAWrR9C!1{ml{P%dh9@?Bmm~-M33vJAIt|n@?vV zF^)XoTt-y-fcUPFbwbU!?l*2_VHjjjB*qw_{{We{ zw_G;x<7Q^i5@s?Gi2w;25~}IMU}fL2V>sUyEeD?5BM5$G>oj5C5@*^4Ns-Z6;MX2E z3CngkHZiT;xNr8GFqF-h+Xj}S6DBc^wWmbB)9mK`-L_Bjc`}rQjn|xGY=(&bnm7WQ zI$5Tq*fxVbt0Q*wO_)Kf+mIIwp&LcXiMB`7R(a)qU2f54S+*`+$*~iWk0{=|cEzzN z4(eOCKJw0Z0peY240L%`vuBGdnVFX?ZMZnox%qomt&(m;R#XGLjRHb{hs}Qcvxj?m zh3sw4#&$jIcwN6600SBJuz`$ShyXjRezDt)k=TBpU|!uUY@224hR)fxWekj)u@?I! ze*2hOGK&&SMSF=o0>?3XzsJmbhDO7@+ZnJDcBuh|fqDA;=T*7Wr2S3y_B6M>vwAyKt-|KxW_VYP+4e%z?T+YNA;2U= zkR0${iRX{_CAt3q4?*^x;xaZ(vc&H9T(xJ@wXt(WHC3xXZyzdqX=A-Xj)DHeoLILck;jg0ISw6-M1h_ zF2Ydm9oHctA>>1iR@{C`;3pemB$>I0X8=VpP~VU-?G&b*)k}Oi{KFqgaR*Z7M3QJU z_?2Qa_B@;4?_%4ZMs{Nv4g`sUJQg~RlK6U9lww#$r9?$J5uilB;SY3;NgfMnZX%qI z^-)Nc>K89kSfyTR&k)sg^3ywa-Ej6@w>NdmxM7KbW>>GCBu9YiO%;=FGn;ZgAoowZ zvG?rl(|Lr+o>aRrt=vCUUy$e%tMJv1UuU&){O!Uql&)QubjTHD!O}kL_Ws^>t&eQO zGL)}cu?b{KMdW88-6wkLyGf2c-z`g$?*9NOy ztlPOjIpv~g=C@tj^6>7EVAXY=`o{U?=2`yh5y^}$gFJhZ5WXX?WQ$AXRp!60y8ReA zHfN7?+ndk{LR=&rfgUWf*;&lUu>O_V!ZROSK_E-SXnfV3R(`N@rMGTT19aK&bET)P zD>1il5BTkNNS_tI?X3M6mwl`4EA9p^Ruj~Wd+s0p8w=%V?*UKvus(ZE&iPC^SR$IamL7yYmkOC zh(G;dSz%f;{Wwf{K5NBj{AY-|3_%uFw6;LP2__Qn~!3;Or_@5}!H@<@-8 zx1;M_6`yfmvuwi()tm@_Mm@M%4gUZj3Vn~M9osVeP0N?$PZCR~+OO6mH)MSiDLI+* zSzKCUhktDo!ob zEB8LA^DXV$h9*`W(!(m$?Ux#N3LhfM{q-j~b>KeUl(DmSZL;UnD9mKrAMqbf<9JFd z$<*@oU**;xvx>w=W$cX4%kJ{UC83{a#1Hes>W|*JezWDSe8;Uyq4_RKh)cGt>Iotx zFQ|^yMTkVxUldB1L=rgiRW(xPZHPd~cU&RB5gMB4?a579$}49#B2c+-ep1|6h(y$$ zF7gJEYEcq7T>o**T{mxOMye zdiuRwf2(@@{`1$W?{;fgxSN&Sd??O4cHwK*#f;)Xfr0!aNsfn#>CaO6pDrCs&9b|T zlCf^x%XcOWJ9}<}s~Tz5dM%vCJk=abyB6>*O6}OfHlEQYgqR-C!&^WN;c9Vad`fA^-xvCIto>1OUyrK}5I-oGQj3vr}Yr#*M& zI_h)b=NpH){nNh#8)SQDZkCaYT+Ez$pTh;)pTDdRhcppNWcUOan~wW~x1QUVeOu@7*o9>#JWx?6_93peHaRO-j8SPcFU}u3Q2(A=*FlCO*Kp*&X)ZL-}c+sO8-g{{Sff zd>NGcL+O8&dF0*4$c889EMLgE6FYdf8aGU1tbhgBb7aX`y;*a0WM$kR>tfu8`J?rZ zl~VH8+Wf@U@~m7f3$Z8qNn`LUKU%Y>o`;UAG+q@z$wD%upbPUsUgjN{)I3iD5LWzz z;ahhcKjA81M$v#Ka3uUfE~;ck<;a+R5Oq%~t8dYW5}(&7)4bIAB=8(=yiaKD4qCd*%I#hh-qBo-~zC*8Lr?Sgf$!EMMp$f(g7F5p|5&$TvE4W(5P8ovcm2@JD*DXIj+R0B^A zC;=LMhz|&*{BI-!NC0ONuzI=b{im(383N%^2% z5u$EdAVX93pde$t z3+_OO75Tad%e`uY-TjerIX>5hG^hTQ=MPL!>Pwbge>bm-;RgMmZ!c>*W!r+x>`C$9 z0I3|;N>={Y9ISn}Y=z6dhve;#LgWLE$?F*yR)bJJ)vjlP)vNnu>-hP1rJhBzd`EA# zU<9WreNwsF^br~=xYr$)Or&6EJbP|hMBFkV&1+Mk`xQqk?Y*aT$==y_p>Kc($v&qYIcJ{5@>z3hW9<<+OR%T?T;uD>-04>`LADpVflwA00zaRO1984`Ye$LNQonn6sO#( zGO{Dx5pFifp$E76q+QPx8JL+Edvs;J%M5y;Mgn<75!8sKF0Lec;^60QXQ$2~EL~MJj4ilf@j!%7qT_4npN6l2fmrpPK zclUN2J-vmoZQ0f`u5Q-_?5X43jleA1tU)j*@k{Jl=KW=>#Lczx0hv7)p4E?A{U5^2 z-aXlci3=j`HIMs@+md#Tt5vIN<%Lz|ZCm4;UvEs9hc$K8=T(>1Uqlg+pp9RO2a(Fd3Ar}7@>#>@e&WZgFIAM)gny5LyqI`if_z7J42 ztSZ(XRPgfgvf$!)*JE@4012q`3q4JVJXg?goNmGsfp}erlnCM^94|9>!brdmxzhv1 zI`ULLB=<2osEYS7WpZ*SBJ5yDJ+YDC#hXD;nX9W1w`vlXWJG5oW=9{W*TSmViM1-b zP!@vM%>q1DJ_8eI4x-^XcS8y4fdQZa$I+)Ru2^Zi3VR#5uM zGI9u^1P+`RKlMLbd|z&#{zLs~#&tYQ$4PfG7zo5u|+7=kmQTUC8sT%iJF8_YZU~WPkCkwp9GC zG=9t-}}p z00p-5+Wa3!%elRV5al0JMtAmfGdt(R# z%z{$MJ^45F{XBo`9TwN^?W<|KcPAGgyEh;|3P`5(@9{{XLI z<*sB7==@^p{ZF=gOAL&Azv*3!&lrPWhO0SRol2QSBn*|fNyMTH(4epRD*`4k9fDqH zN~t^&57Gq30iu{{obfLQCL}qd62UQagaxX~a|1FT3Re?S zOyvEb&<5kcc&n@jY%B-6Av=;TL$C*`x}J!F{-xPF{vY6i8;)A#$g>Zo16EW*WLe}0 zl&KqIR!m7k5d?@18i7y|PcaT+PjLQb;n66F!NK}k0e$d zH1J1ZxhjZ?c%d9uxNm`G;gJ9{A01gsay$N9?R?Fwe&MQB(n(H zj+!hIviCgL#wH?K^;Q<-a9MXm#b(0x9p#azKMvKQp1Xi5*qdIalT&qL~Aay|l=7CUCf-+U%!4_Aubm7He z@j!qo?0~-=A5{T;D(Z&=#p;BI20UtwSY*0!)eL&q>DB)1EWB~`N;e4s*a|M6o3|dC zS2jp)JN5Y9?-t=|7b0Q7%Mg57cd@$fqqoN*+-%yk!ZGYD^aF?sO!=$$+aR^|hzUpr zGhy5SF3v|aT9UPKHr#m6w)}s!689~{nDXeh7#gq z)m4)l+deP*ZVUmP%!AwAE0Yg$ay2rSQnPB$4u9OaxiiPVZvw>4*-A0UZqV?5s5zs7 z&2A?D04!aD68OJ*`34e`8&i=oxj2&bkz=5v4}#4|>F(K-ZQL=JZRyG92~I$?s2GpA z2gtvv+jMO1bGMIdz+;I^B-TL6Q-0z|3@gPyZ%)6PU-Y`{24S~rBIZUYu?rb^lMU(_ zT<$Qo1Bl0riQ&m{8ptDx0#Cb)FQL~$anVo9hHsWJ$<{lOpC$a*T&FM-^3Do`TpHo_wJw4xTyZOz! z-Q1uq$0jG#5&($_P=?Wynpegf?p{x|J@azKyRpZf&z?>+r51p<-|9qxAL<29-`=|B z`F)*%x?^s57+a1!gzV?qh1*~eq{ETqwawV&>bc)^`*&~mR?U;OZdUz6ml=LqU;=GS z52jH(8Fb^XttHE^&wcx4$oAIvm9*}bJ1=6%fg+NL{4($nCvvS{+tWyKHIp?vQCo zuEC^yx~W!NV`WIf?p?5C;zxq1Ym$}28C(v07NaUxFB1`7DykE7mWb4{%IZ9+{X*N) z1L9V;qNGQ03?HW?i#)#3{S5Zd+C8~*d%Yga&GK(-kj;;7kstF(%IhXZe_p;nhqcP! zm(nU#aWGmZ>Lr~4^yq?>&>T}$V5M^2q!(0`1foPpkZ7JCxfxZtU|qK;2=@c1Rxh^? zxa_dGDR){2ofk}$`&jes^AqxU0?RaE0o&j^Nc&fZ_2(*^#%ij6yQ2M)>Pe!_!#C;s;mS~&ZV zU9#Po!;f$!SeMgk!K^rc+mNoX)w6M!zw*QERhPz|`t=XIy~%PCm9s4Cg~20_MJ;vb zosNFa@4Vs>=x!IF2l~DX2lNE%o!ypYr4F>~6SGIdcFlFp`u3qLN zXp!{{UNRR6@6A-KQ}G%2YFzPd0U6 zn^kuZ0dhjggTaM4A^{`MlC^OeeKZKLG&*a=6k_IpXrefs@890v+2=f4ccr{;K=zCb z7N2anT)X%o@h76Wql%W}?w@x{BF<*(YubBMY+Su8d~+`O#sT|hdXha^gK#R#BH43V zUeorz)q|UjJNPocZvHvTz`1tcY;H;>vYbno;vDi*tCczP&gMJa?%2)S@^0LKoUvm& zn8#k(_85&d)l21lIqW@>&<}8%(_loUqx1`uy6J1FHt?n~^Y2)V%)4U$J<`m zyDU5?OL5&K7+~W60DB@w{PG`61M^t_0AKxk@jN?!xBlJzKlZzShYh*!UhDT6lyh?j zx3<}z{{W`o%ex|RKl!)#brD}fkIGMPoqFr9@TZ5j;cd_`!^VxC{{Zzairks!DVHSq zu8AfsKftQccWCrL(t03iEP<6S;RZh8zU}*YFrClLU;bQcUsSyK1f1H58Pw?t?Phec1W$dr)z}8Ze_e<|9w?CYY7xcH&)V95k z6AVV)7B{JIe?M!V9*d^1=#7j_D{{ZMWJVE%Wgg%F@sU#zP9Ed@$uQZmJzQ%=uH+Hh z4=yEj=Z8MK{uMVIt=}Im#^;CboE$s3W)?90y_;v%h1=S8+c1#0434y-x5FJaZ0-Kiw-$}u>}j0K_Xi(DObA29PQ3kOb)VVSk6-22Z64Oz_M68t);Y@D z=N7-av3hmm@aLaC>M88L;>Npn_R;Q}-M1$zpODwticWXZ zU)%KK$5MacW?7!&_XZWKxCHx86CeZMk#0A)4$hX`+q6$!;@A6CD+zJK=T{{V!4{;_?VA5s@LfoC$+E^Rk0U500O2#k3{ z)Fku@eQRI+#~J7U0MQ7{_kXy}v$o?8YHZS&l=E{UE@$4h3y}*Ig|6YoM9ZLB$r!zU zpQrx5C-d^{r-@?V9rmL#2jU{CPOH7tiD2u2CnxKM6W+`%kWVGFcfGE<()Z zV)e^_%H5$Z%aRe)h?jOxtf$(`#OtEmsMi|SkK*uwQaX1<}r&% zw}24|j&{%Tbhizo3I6~&x#7Zb1l<Km+1vwe_j= zu3snhYibfP!^O2baUdB?u|6CYr!(f4nf_UMf2-Km#Jg@;u|VCC?vwEju54pn4T{vELl@_wBQK$Ilky z5+OU^>D(;Osg8gGyZ&FU_^$`;_-B~8n~9B=W?0!aqmc`mz>?l1h3S>!vRJWh)NMxH zxPcLF075UMLZ)Ga_Yn|D1;{)~U^0%MaVkHZn&B7d0m zO;nMAlahXz)PR5;B4leSM&B-FQxXu;Xo~7zhlNEIVgXu5Df zbu1sEG9l2UD@{-o0nj2(@j$gezLC)ZK#(TaS^in-|BoU+TE|l{Dl2XiCV{zxFa(QR>AtMfJ=8Bc&&b(oj9Ic z&#}E+eA#3eN;l2e%eYC5=s*T8z&Uz_=jYp}cf;!2S28aPB*>Zeiju-i1NOuX7k8Oo zHyC6?Ce8CNQgI!?6BwB5+QX8td5pH}7`N`5Hbg$Z^&<$Ha}y+&>dJKorF(My{EKhu zNLhd}jj>pP8V;_Y^1szzWngD-*gN)KWOm#c;mSLXQHh!LET5zZ$5LW`N!;FDCGn1r z*q-3o?`*!E`?hRa!Hgjw(*E3HJ4btp836L&x$%7BS>@>vm6+O$F=Yv2)3dbpfF)g6 z>g%g7BK=wYImY*9+y3W+U`KV^?UNqOZ$tV?;@lTbZqKc6j*drS*S-79v z+jk@DVqF@2RWW{xd$Ebu`*6}fQ|frAy1imxaPW1SH8HLj-GqP?A(X+~TD>8YgLp7@ z21VP#s48w#oO7?qi0==}!4<~eKUKwX8HQSpOGtbv{l}yQ2UQ}ePEJWb6-w#7neFV) zb#M3^J|&|mWLzJZyZpAS#J$UtIsq8f)6;za058z&3E^DA$NYpua4bM$;dX`w-I3W7 z=FYmu4!!wY?SLPI1HkyIz)C@Y(2YV0=fCP881|s7Vq{)*;VioB0InXWCV)Si9Y%;Jw@j&Up+RpFUAJ%X z1|^VP#HEYlstfkd{iVP7s)KAF`=^siIoUk9qdZ;Tu`l5B~tPzu#n2 z{X4_Fc>>`nT}V)R53sX6JiOcq7LG-+df)s|q4^cV^qzI8<~>YuSPo#-EzU?P+`M2r zy(vcBvPH|1Gyon0QtAt?JV{~{{ZH%gBbY6-6bzR(7FBk>;C{*{{YLc_4CL6*U#}5N$r7@Lr3Xy+mzwEoN z82DBt_217U=1#fq{@;DE^eDBBJ*qgi zam9?=()6=(OZ`v;$*WQ(+6D70@1D2e_9uUza!;Ra3u7Ql4(7Hon3pVSFAD?t{oHE(eGr-3np+?-9v zGMR{Ixv6eJVl``s-oH`3zqMbU9uSuMynsN!!2;x>fAubY2oDmwbNSmG?{YlPb>2PG z?oQ#l?gM4prT+l>eYQuwLzV1}PlQ)~e=d1q^>4K-JUlE5QniJT3}_Pa5EYT(AwDpI@dry_47%?snbDh_Px_mC1f7d}>#saXI$k z*LM1Pmf5i3VRqZZ#`SK2{-ZhgXco1G_1ieOcBg-F$%U9eJmcH|4gFFy3XT(W{YQsx zMnASNj^P|wzD`%*vlzQS^-X8&*VV#rnR~AP04=+4JH{^Ad+D`jYL|W3Ub!iKGVI`7 zvbCD@J&)Ud{{XouVP(T^*yC=OH!CFHxJUUd8btMy>pJTky5`?cU-sXz_MM*PyvX8= z?a(7bzjAJyMpjYozmFNiBN9cM{R`2M zi?w@5T<=SN8@oEPqtD(wMu@ zIG)n~0Bw%ppM$z&WP77J&!#=Wxev_BBo_c$c*Zb)<%=zEj3?onW&Z%T@;3KBd|*JG z%V690=tQ)x?Ku*$ena|&jFH>r>MY)WhQ9v*r#|Gr@NLi3pKIY; zhUfkjxzF;)f2UXf0ACaNX?ssA*}0I%mfgPMdxLnl0~`C6MB(}A$ks-2kc{JA4NVm4 z-$&*Bf6m|Y?dT*j=Jd1oE!S?@@h6?S=GoivEzsY;F%VB6^(62BI*Xu>@r0=Dmuh2!y@-S>Z&QpD?1)n{Fqo1N{eZpFR0ZrAK! zVb~9MGW3O^ANiaY=(R0lsm$|P9@^h5`^BLvOQu*v7k=ZKHfd0&ZIq`nyRq zC0??7V~)Pt_4ssR{&lbQaqZrK*5$c&mgdr@&1WNf)cAbY?(OOx>)&qV=3l*q?QOP4 z9y5(4aK^HX4xQ39@Lq4zt+@KXmp@Kq`BI1Kmc_7HmLA2j+p%KbZ)p*Txhca*%2gz| zPYl^_y3Eb}eD@vF*x0z(&ra^%Zx4Mzi_(8T6mQ$;4{YzYv$1Vl zvmWb^BlB3!#z0rPJx2td80*8?cKoYZc-HPhUDSDBH8O4u!b6JnetqwUgZBKswRf?* zu8;$cI`k)!?BW1+hyJcDQiu}#H6A017*ULz7>?t^knuthv`m@%rz21hr$|QF`la32 z8X#B1qT#TK4>{t+LSNK)te4(Scn2Q2^1unw0a=sH_g%*)}|vd zZY{49*T<5_S00bcjjsatPq{7Kl%Os=ML&A;b#}e8pR9Q* z*}&=17C}WWZh>pVR8NzeLCFbD1I5u^!cURpu=s{Ptxl*K{c3=Mfa%4Z40YQFv3--E5GL^#S2e+RjMus2|wjv|xo1a{uUXQ@?QC@lafwF({h@GApk+YGBWAk|UeZY{ z?$;x5!}IoT$mHaLWq$aWc>MvR2tY6#RsFp?es-$> zBL4tUc3y6+=DK};A46d0V{Ue1m5nQNu@XBBYDAi#@Z-UD=dE+ht5T5DQT->ERkmLM z{;FCz-s;}-?ZP%BGGz<6w!n;I+4PRkItr`$dGPP*N1I~g2+OkL&LWV5v|p;?j_YI2 zvAAPg_U7eu3~Yy%*^?^zcR3D)XVGWOaTzvcjgfZ5%gWS@NgPi4?o=#p88-0#q3YU%h0BA)Mu7O0I_gD}Urc)^WZL#@ zOpFby7}$;b68zR&>wfzUCoTj0qKl2|R``0qwfleAFyB}S#Euk^UY;+9F79;REg%SC z(5gIdPK`5Lv~g`+@ZcF5=P`;>`6yqiDV*G!iH_ zAN$xRn*_#F9>~wX_w7@>BbWG7WE<=oV$nSyuJH- zKRN#ZS34|F!i~(VYjz+wh3QauE2)MZxN2+N!C$gsvBBWX)K9WxRGu$oNNrfH&b6B{ zSmIro`XfMp64b0%^>1$FnC5M_=70CrC5e6i0P`XB!2F0?o?|vWBy;$wS!-;$r*GXb za|vkLyB}Bn34Jp86^`b{xqSc_5n2vC7X??l83PA!QF08fn>&qI za{NM;agm->k>G3i&WjIQ?H~l_eGHnh`bBm^VIzKHMMv23+P=K>#rUggM(JR~pa6ha z_3yM`1Fgo%!XbPqFKO&fz12IBS~Il+--;g} zcR6wj+7jPAAef#9aU4paaz;neGIyQyG2g(@H%4ZU_^2~`F2YLTOl=XR-dxs}4}+>W z!+*n+Iro<7hgn6mgD!;G&TG*T3Ks)m`vL*Q**F>Bn~Io;m1V>BAoXT_G;b#AAH|ml zW6lV$@<`DF*Zlds#iv9yP{=GDQPsJTeR{|A3sSR3=ZRO1^@Zn`?*STvoqo=;yU*D7 zguXlzO6R_b<}-rH$rYY+CC}priW6Syg;YjQ&6rc$utYOT!O^Ng7$OXFHDJp4|M`Us z>t+L~VBe+S%6yBc-ve3AH4$=}W9n4<|4%OSQw5uFa!H)zg|Tr+8MfCxUvw1wWz>GP zj$Z*m=VE{P6fL3fhxATsVRN4|?jTYpq`bH{CZ6>tg2)`hQc{&K|5S=E1R7z`gL$38Dgz=&r!27frJqfF4tK5B1>T=H0Q5G(IC_D%JYo0TIX9Rwt( z?!x7Hd4Uan^$^WPDC1t?KH6#eyL<3hcF2D&+l(?fkF9>{7e8^m10(Z+eyvddM051coiYLP5_p- zl5Y*L3Hga*+W-{aiF^5-ok;%xDc+FD(WD;RoVP4f z;k#wW5yijWir1B0OB7PkzvGO(Qbi1aI=yPxc+?+JnBA-Wt!xXuj)p0rn!LH~U~(c{ zQI(<-asovGnfoJcWrY0T|C*Ob2H8~3pwQOm9Sy(#Kyz_v!(_#$9D3`*x2yJi^Ic9? zd9Uvfv=xN%BO{=@;TC&#{4G{n7La6(RP><4uda9M5+{r8r|-A9X6v!mF@7<$sXX(| zm}=$694aV#Snl?35CVPfhdlBN!VLG-x&$M~Mw^sIoykJXR+e{CauJa%g0#t(m+&9N zP?avA-;qqKA}aKiQria;aimkud1M~tfE~ho^8{~MjLwyQS|?ChS#-PbSM4|bmlEYv zQ4t)}+P__46yuFE8rDB^4=l|VcQn2%(D}M=mNHdRs4M^Cd-V4<<<&I1ZHqHGq-Up@ zX_GXU>qe~lEM&~ier~w)vkB0dIIj-pirZT2Kg8ilUR=Ius~oVFjXAl|I@2CRFQ$5c zBsHn(ZY97(v^#a^1kELMjUT@pF{_eR-8^aIdNkvAsdXt3 zgtUi0sJVlpPT5W^i)qaKO;>0uc(p!6oKXJ}XA{{8yBTAeYnzqMwE)K14 z&;_N>&HblozCL*#BFsQ0748XXQ)w9p=24PagR865XqJ9PHNiNoR64#Ut;UE7y2U8V zb0HofL*A_tA*iS|nTPoDNMvs{@skGqM6_C}bQ~4+dSXv`%4-ih5s}|W3b4o!qeR_n zhLlG%%pNbwZ&6!5nV1l=c|pz$6#8HOwJASqjM9h668Cax`j5+TI+=Q@q+*(v#|K)1 z=RzS9Eftfj6=)1gnjr9&WnFfiJ-I_A?nujr9AUifJ>R4{S8iwxWxvNhK_@0}@Dt>9 zQVw3C@5ojKS%^f*Yu4_^zInhBPX-2F0Y^I>OXR!cr^fvJ^Qx{aa)Hbk*=LP$X&h8r z+VkNej8RCc&o)M{VuHPK<@C{x6#g=Lm*}Kk)6@Peu_oaUMG`#^ZcY@P$qPzI?e`2v;V62A#`P7)&r){9M9`oHvt$N>@l`dB#EB}wu zCnu|6Uz;4R7S5FBSDUcpLQ`F+ikhF95tw+uRs%|cmM^( z#$V-oge!3GRNuiIQ9MfxdND8`9bJ9PGy; zaV)2X2iLi=bw$zxwf!ce+N7e z=Azvqmd%yt%bviui`1$KUckbt^e)EE-HY_xGMKzR$H33T-SQ1NrL&+8-Udxm_Wo=G z#s1<7tJK)`Gn8B$wh(tfcTe|r%ECp8X{YlLaIfX(A=OIr^-A}*%bfR+r*q$(NO|7* zg#{o~@D9g{1UY$114$>~skvH~gnVzW`MOHUo~RV0{2(-VFD8_fMaT?-AV z6F5Xn2W5d*^uga3|4}s1blq`U-eOE}C3%7^6*s`p;tldxFyq+aU5vveB*?h;GhgiU_dP{d2XZ;fAf}*J3#-^ zx{G?+Mo6-VP@}#LTLya}Us7cqRlow7aD=Z#SO zlg1CT!0oHYnySZ^CTA^6u_ZEz-T|h=Yx)XrH-!+J78(nXT%I<@{QDHy0VQLe8d3PY ze-t=xUGQ{biNTFeBIt$6D1x_#79nnM?2Ds~$?Wx^US7raVu8=$@T^zuHF z+6<#;f7{0SbN$A<6mg;xAqUqt%nXy)P=~Meg!OAqJ@n&*)#0zSe#Rxi{BHdn`Vo7E z*9;nze(YmES6UKrzyUTTzo~=}yGrp@SM&8SwyT^ODv}d7^}TsC>|3&KPH%>gTyVUW z>1C=!A*=Db2tGYl8?grGp$XGuTj3}Dw4?suuI1=cvas6ogPC_QC+a-n*5fKq$Hfsk zlS%xy>4EG^b#K9XtE|R7PV#>kEf_Y%B7AlYuG-eQ9Y)S5u@rs<=BW*j2s=HTH6WW3 zyEr}4!#<6Z-gmV&Hn&a4NQQUl^skb2^QyE?)9%aVvzfV)as_b^7PEg8kCG^kZ3-Y^ zBsK&y$8Y&}g4@fDF#*ESg%|fi9Hoe86Y(sD5nG+9AcKTCO_R`Y_Ht zWEbGSE_!s-w$O?N`c{6j&zw633#~FAxoc}{9gUml;RWusyQv`G9rkYH&EI9s44mk z6B#;itKf?8qH+WQW&D6W7C9DJ#mKnDg#}Bx(J$c{-AL1iRP92 z+40%VmUOlUylB#6o$ub;gk}JvZI7_L`1~o$Ps5N5t~5k?gytUD9a>CWIt{r}8CRJ{ zV&rT2B-2o?vEWbhDyT5fsoy`$#X(Upxw1pK4GA6kcG*KV!*WZ~;oQ6@{i2!TVk z7%_%FaxnRM5&E<10`pPY`gW?&+OlF6q$yeJBGXF*lm|Jq7L(=wAcskOF*KMF`zK_g zt;N*=mUd4*=PX0`PxdkkQEIa@#j(p0UcOESvKB_!!1HsLbyCIZd?uRzqYqgsHQH>L zl&B+;$&s7qqA% zM_I-bj^Kgrqs5o=m zTA}-;wQA-_sC+yecTLWZos!O1_;JR}iRH_Scg`zT@WhCsi@rzh_v2;|9?N{Kd9yOA zN&J&m`LQhuSQvJEYttW`&4HK^4m-Fp{yyKu9|}1e!|Bgdj4*KhvG67dYmR9!Km{|& zfh;*Yc$O*DoG#EY65=t9&Y#;)-&e|5%4TkZPR%NG0ew)xF0%EX2#0^xOBg~ZwVJ|e z{Z*8mQT5jy5na3wBgNl#za_onq0Rachwd_~mtvUjTzjQZ?@_1^o7n54HgrtbRP3WzY3@f#jaB6hVZ1k{6@?)Ig+vfuqIS$(xuxU0c?er`*e;&%0kSg!|N z8>OjT14YXUOT=Bx6!p+aFxS2x;gzgkIP03`pPNPxG(s-f3k zN57`h*&;^-F^!!E*;;Pn?v3>=h9mORaN%1VIvWWv2`EqBsX($?L>%;nO8<5zSTJu| z5p0I9937aQ#I>7TJi|1&H*XAxwxk4~`4~qTTv|NHtRxovqez8aW;bG;s4*auZLGjH zJ!3UGAo$iuWU`4e?8d2U3Ym$^+QMFq%5CkiE;9Oc#5dcWi6M8}(209K&0)iPC1SoQ z+mXjN5D0Sg9s!u_1_>%is^uM6`LwSYvI^*2hap+;-W708b^+RQt~G1e)AW@Mv?&!d zxY!|Q(`bgUB=ZWIL`jdQ&ws=Gn*$3-(i?He)%?WN>$0Gz#D&Wb5)W_ri1znJwNR{C zM-LNo+XLLQ6UevT+8Okzx8_e&^L7-hM^P*j=5wJajpZuLB<%sY7xMFhdRL+1gwXw2 zyDc!W5Fl9J04a;l-&bD~!Q|#(RXL>bz1ME8D6OFq->}$;qwcybTk7_F_{&<}J-Z`g zX7-S1&l^^B0fX1-M48!dN_{iG5g_}gw4%~Jl5yIQua8bUsLwdkQ{cvnzY)mAai-s% zC-G1f!y|t4c()E-0A}AuwXi+WIxQ*7VIw^v_4-V!)Ug%B&9eQii?iE&^79Ptgvem( zmHsg0edqoqZi_rM${Zew`yaxjAb09Nx!6Zmrt!f-JZf_Si-dG;`I?dgN?%AsC*>-> zxfAJ?F6bmp6Umm?#%I`6agYI){mXipBmAg%*1mfZAw${!I(1$b(fQ)?CwX<36TnI* zWd0B^;B(Tun<>?H;}}pdeIY^?Eu<5G0vlJV`I{_TQf#~}OF7Nb-07HVm&=lKPgL8< zz}0t60r1$%zIJ3^?X`^Ae;ryogVmf*UMFRdt`}OK-Gj zzJ!s|_O9CDh&j8AAwQd{yL0_q4+kpfJZT2$GK8KuRB$3n?x}|ehp^;PASS6JMTRK- zjsCJqfN#+~<5&K6ja(c-A3T=&XxGG$-P26b@ex(tRjT-M%qN1%9pUsxDuOU7E!^`G zIY1YThvVX#u8_)9ZCuW6_dv4}x|BRQ>Bk$tXoo1uZ_%xr#YBeAa4vhqJt?8=pSVR` zr~cww`TpInD^Xfr2oNIMBG(z`_C0-9aqT zN3WYaRyxLnR*!qFf1 zsCw3g<`D~tE2Lzs5OL2|c4Y17 z>A@?WY`yr()VPcChW0+P*gytND7r2Me2`cWyejQ={JysH{*p<FmuEEPbr0g3FOS=_b{zAr9&tKZr-T4>G2_AF|9xn!R=CcG+PkBW-c+ z61fK^b(zf_n`49wwo~bJqximuRjOv{R8Dt+pwB^=CO3rVz-N8)g3t*4-l_H*!OFCs ze;tc;T7a{AP@hn+P|l-<_2*ad!@y6K-e3UXbts8H@hK8&%L^( zuUw0~vPlA#m)|enw=Fl`vZ#NHAxtnu}+NST8OpjrapOtCYOIEgD<*CEs!n z>Ka%6+hsCUy?^3mHW`dm1uP&VZVhM%0N-wvBH13V4UxryW zIq6G>|0t_QbOMXW{siZf|j-$Rt#>t!fvjyAhfaT5QX>DRSg`jfjfNy26-u8AMs^;6>nYv~*+ zq>MXtRqD0XqxGL2XoI+jma#XPSZyIP1g}CC8eXc`s1z$=#bX~M((WVw=8u-VhgQ2O zGWG0gkLzirj!%{&W?K5SGd}{b1jrpiDXwj3r4FKiLphc9BV{CzX&^7CoL-gsk;=7K zmt+rsn|vL?ZG<70c4xAYnvO6{s^I;0w*U6nNd~79#f_#Xi4z!UcD}1`VVH3CT@dwi-0#rVt$$ zY$|k|ss(qEiVDGVg!iQO4v;@yVdO$tLE7hh3Hzcx%&{2$pYGm9jv=q2`@Oy}fBtW& zf*CRfs9vSH!FhaI^ZFXDGs`^QQ8|~jOF2yAdoJvr@vy0o%TuAL5+96_DB@sMQD&OI zlf#6iS&Dq%NdG?h!50$7#bKLRmwLy;^vwuSH!fJ!No?8+UUI%|A?Lph#{5E%x34A_a562hKpw;M!X}w?9T`JZ9xc;VR)>9 zzQPCROixQXF1u!_aiJrjDot-E(yI+ec6Xv4e5kG2)Onzve3mjF_~Q(2I6ZmcZ7`j- zt@n59v`{Jd+&$Z`kyP*&4NJ(!+0KQ-b5msfXW}#5nbDsN+|=%oT`cCE;V={DQjt>; z0NTHH*#QY1D>@xQ51;~^1K5Q}pF4XhVy_Qqc`!yJURrD|NDEG*?SE?iqnHP|2ji>X zfB^2}h^>d(L3GDl#8E+$zn_K=!P!qQO>^UG$)u`nHbAq%w?TcQ&_CL0GP6L{pzta` zjY9Embl5%eT55Usw5U7}4j=hc=c^-Fv3U5qsTjmJ0>I}`^8#X|vv9Z$qbWv%X**xa z*?por(W)4~OPV9=F0Fg}`#wKzSss}7v&QQ8GWd`j7NiyHHvSe2Z8JxVH3OQHH8!AY z00r=ozmLw}bK_g&$3(mN9=qDMQS9N3N>q?>#kJL9aMf+mGc|2*2Vo#yftQ*)uGTH? zPHf3PA4!$$j-O(;c6SjZvevB^fT$-MSxoIWX3ETk00gr>xFmH@ue72E3O*_ zz6veMyL>+f{o(9=t~74|g#WI0zG0D+kpQ52`0!4m(PMh+4wZ0mrCrT(1%({6z|2x` ziqA9irWAM44JWOmt7bzO$6s#8#!e)u{nRfb7v~sG2!7<_Ha@w(mmfs*E->aUVCtDE zf9sE}8+7_LxuGB-mwhx-Ca4L%rF=5kQ3zeNhYt*o z)+d2w+K!r~(TNhlO>J#7aX5G85e=`PA?%ya75v`|F9QOPas}jZMAU-AN*4%#BG#qs z7cRo_M^Gg#15O(K(#7!vws}buK=)kgd6C`zTvfVHh+x~<=&L);SWY1MBwl46(K+3P zCdSP=&wNdEOh1a~z=oT`4@sQ?8=IDO>}ZFAIj()~Z0YnB&nK_9}Ft- zV201WM=#CJ${4}v9@1Sk4cz&SRgpM7y^>gX+0;zNJRJ20`wqn?sF>0S3TZOHuEU(a zKEpGiICQvMf*-m#iC@ztPh){n;=bjMNm~o=y7r*b&b;SmZ@=m$0(y{Fd=5`6)NYJ! zS$D|quc8|#WbagrD3}wxpYSRQGZKsf?tT6t&D9n6>Q?MArl;9zEfy@d~JN5 zl4>D*cR()mrYbH{HR_K@_TyJ9nS(hw77wHNuigzFOQhdLKTa%FeOemwFe_z-EP{A5 z?!(pgM^1%u;2g>m7MvXRf3>l-+*6s;p6& zKLl2d4fh0fL(-=M`h`2ah^ z!f%>GxH`rLYDFQNj7NtxPVtmTH~IYn(~D9HL0S%*7M{PCE{u=TBJSR4VSG-mL=mwO zF29C$>V8e$LpPn@O_4uqs>(s46n1aOWx`U^S(=No`H4Qx|x zGE;_Xi4MXqBUvbYd>4W52%M|9^dAsxk=qbJzfF3RanCUA=F`>j4%jGu>)IUTj4_{7 z8?k~E+<+N@@8QZ`rzv5`V)Pm!4{oY?UFE7Hdy`JGl#zTn(#4*~#5eiQQO_;e z_JIJbZBak0AV27Bm_pM0`rvD>*UI0WOZLx6S$5}62N%0&E+~W;4+IP>>?+Xg-Ce4m2$-=fp-6Gcnb3{PS%^ba zS}e{Ot$L2iva2(d8^y*J`-Po4J4jB!xB0?WEkErcRp%Pj5lLBkqpJR7mvH=mee{b= z(R&tTa^ZcpO@^CBY-|TPS}*8{&|*B*i_?f7Y(pRYY_lwRRYI0_Om;zGOA1%$9P*+` zhBttf@t&}4l?r@!E?%H`#9hNd6=ndvzjpB0!3L`?>D*TIfhx0Nruk_fjNj&&u-)iY4uBFjf{!sb0FtwJ@}~jW5I{^)j!csfeCf|VP;7zRu!e>X=*d7^-L&< zltLAG)0p}|%l-U~-At-cutgqc{;cOw zbjVMseBQ`G#b;i~o415!`pLWmxsQk%<_Aedv0P1QX@*U&jMPn?^C}T1Ij^5ymv#vW zk@QZyC^tqmTMcU7v8miF%Ds3MMH8f(arN;_PS)Ce+sC5~Od}C7OrX#d*n_|=JKSOB zf8G;bqGyyIM`wrnZr zSH-_)^6}Y=XUSytvMYV*Az%={&>=H|Ie?j_xgt)Ac(%?#*LFLws{G%B-y@)(|50o& z$VfuA8T>*8qgSUhx2#Ddj3T?F#^Ud*q>tJy8&Q&d0iS*iXdbIrlm?_B_uX9hIuOFR zm2A!av^ z^Kp&;KMLoh)q!htE&FR5DBNHX^X&`XP(`NS!H1MwXsDY|V|=1BM#NweM6NJ#Il5Td zeGiNc&1govA2{u-X22X}=GrCcKDW{0XRhu9VlPamP*a2mJ`x1c^FZ7ET|Z|qAK_K9 zP}=GGY)!WzEPFa)ruXQooRidPPc}51UTv|jY!SM4!rOB(efT2Avmure+j#Nu+YP6r zZ5B=XPy1^J(525|MA_a=XMpND5g35Wz&vSJK$*JVptCsn9eO@^A!DF+j3`(2!NVwd z&628KB(<3_0nl1(aqARsxV`4>yD5+FJu%)Ly45RjxL%Ps@==9{`GooxqdFXI8-#ui z2{^WP97%BA$vBeGs@}408eT*PlUbK(K^DH<6!$~Li>=@9*N)~i{!u(tZ#oEvq{K4> zpv9&1cMWa8znlv_4Z5Y9kKtVp4poTirYzbhnLX48pAmK%7ZVlUQVx-?v~={@aK^!h~yGZ+Qv1iL)g)!V;&DVtT`?e7R40f{*JlqK-q}v(5 z8S!mKdg<}TY4^R(E5xTYw~Y%fj1;%JlO+&Q7qee@G>HkH!G#z34Z=rT`~W=0%D|fz z1V=>W+!tJU)#Z1PG};@N#`&BE;CKAebOmv8wGl=V$Hx1k0l&8ZFL0!JoKT1-lvq3h zpWC>4cqRkJo?p;;BOe|ShdMdf77nl`0{MS|i)~yz(_z`_oF;Ct;C9&>d$NFSUDc1M za~6SV$j6s~z46cE!>s1`m(S`PfDSJto)}axSoR%^Zec%kd}Q$H>4PWwK0wwdMpQ6{ z3@D5o@;Ck>r+1+mSGC3#d=(`P1j$1`0zx+Er+IQZALQJ5IxDs1pouGxc>^*PSHNFk zdY#V%-m>)|!=V}eoV6yeB8CO-^ijgt=|2!c#NDFCjVT8Em2ATD0avtYcS(z zX$C^!{nq8<$kZUK#L%n^hl)|{ zgh8w9SDP2vD>)S!G!Jr)HN*Fdh7z42`}yWw!MHsWa#whDVnI&stCloUoSKWFy;Amv z5a%|;2#X8x!DqK?;`%`mr}fLOeHgTQj-n*gcbPFh>4&gxo33?ljl;T=Us#I9*<5E( zJD)P))dCm(zh-ae?M0ZIdbEE$$z*ARV3~bN1Xf&j#a==Vi@5r5WZ7u)4k&}J$W_Ws{=3yF zE$Zc$M*sQbYc+K&!{t?lWlx z-enPc0f|kg);Dmt-|yiN2P1FQd_|wOL^h_`vfn3hn71deKP-d=>+2*APVJ<)f^uBn zB8MRlT?OVhy7R6$V7q)^llMDw!37LC|54=6`42(8ZqcQsUg;hs>KUgjbnsz9z3a_v zFF*Y^2@}V~F;4R6hF5t=kH67fV?6?H2$E%DuD5B7o!ad0)9RiE9FHo%^i>eUsw+L%a^Jf@|2%GLMViN zc!6LWrhctw-Nzi4C244>t9z3%VwwpMM=4-P&l8{(w;3fwd!13`-18Ijmv7M}1q_Gf zkLa*kd4*Jg_cr` zhdt%v6%&t9A>~_-Hr?;C2Wl0jQU$KeP=^qscv!=x;`EI^-A$mY6IDyA{d6l(-=ki@ zkiQPi_NFA7W)wZaKD8QW61e>0S@|!~h$?;d_&3Ipf6UKijQVn17~YnNOPI~*cXrFg z6t~)cZ@(e;0!H;*tIP!)=8@5=VjJILQ#x@&c)N#VP5Q#H=jANLgg_J{Ne3O1*ha|= zW}^qk^xUQiH?M9HCfXHu9Q>n@$F@&Vh1rS?bNm`X^ zypFWVp6>;s+{{kk(?{!#BQlyGcu!&^2oiTCqUTr1R zwkS;x6$>@kDQ*guDk9AUS;tEEqh6lIU+My=zwv1^6z{^-{qV(1$KXuxAIy*A#r5u- zI0+tyrXkj4`eO$NiA;#|9;L^BxUXfSH(1h7!gKq+(f=1m*+QFF7X!9>dl$4D&T}0T zlTz4{Nj_Aa5nC5a2m54Bu{sd^9a^Hk@fI`w`26Y(*(Q2;EM3!eQrFP7+Luo4X%8?c zeqkg$DybUDa@)UbM;RQ5?nTTidi#q7z3hkG<5HQsoL^PpfV&dtPgmRyQekP**iRJ6iD}IQw>VIU9Mxn*-c~mNwRI z9_%NuS+l`kZ>2Ojon|=`HQ%iq`$y5NRtJhq zw#&cBiEck#DmHGTIU7#6-SVg2R&jN~{6>x?vlu3xKGTHwmgnG^mo(A(i?%ag(d1y6 zRnZ$Na^dN1lg-Y%;*ggb9*Vw*vo~Q4jYW%d^~S^f>EO&Sqw#Y&co|?nIok7jP>(Mp zu+aK9!_-As=;bNDIcil%XIfYL>ZQBHm8F}MMZpiH=p)*NraG;}@8T&|O@?Y=6w$)2 z62NZ)66R&H1e?#VrrOSh_#uTZhP4TIU!}%5S$W)O5lN%bReVFY%{OVBvme5S*`ek> zU=msgxvyb8)}-d$o(PJJN4DKH6nFzgw}+qCnQDCfeI9gC zx2ca8=}PDZJ6Z(ewRU5Iy4$`%Dh$*oO)uL{{Bt&%^Hdrr~)d8})( zvM+gE$gIr5N5B$^pqTyR7n89vzCf`YFRr0yg)nl&wVWH=99_RqrovQ%bV}P`YB{$% zfmz-MODz&mXMMA%hwX+1G)?fWxdvdw;zoi{b<42 zGWUq_C6GF;Xc&zgU#DCdXm7%T2?1~@nGu*PFIeB#SUEE%%!Bmuv+DWF0Ylgr=YJHH zpfj1r`(0CW>hGHNLBHtl(REKGGMXYnTxJ&=3Xjy@bOe^ z{Pq@a-A?!w;uZTsekjJ($|!75Ba6}Sfw9G{k1kN>m8-5DOk*dL+pF1`Ds{&Hv(C)z0?WUyGJ}zeI|7YZBUiMTwF@$iwIGGtK&RYpJa6+9evxb|iBv`?`w)r*!YiQf z_V+SFqj!r>phU=qjlkHVyAldp&rzLH^{aR~`y{O)yeYuFKa;Sj2+Sc;(e|mG*O-ot zlk$!WMl5klUtKm3tDEIBU5%RT-lsC!XjTIg$qz@+6HxQDeyI^xB}?peYM&qSuh7$y ze~uiEcE?Sj$3be91K7%->*1mvXbvD3mY6S)hQ%yw)DGTsrn;-9T$VRhXR{D&OJ&f? zCh#LTl|tf^Ntv5t6+a0Kl+IW5Mh1J!DXQ72U5SSpNTa2@ssB-MJ%Fmz4WUj;p+YRvPJ+Lz$x@6A?93_uK9rc-0P>$qUi!qICcl){ z;y}XbArA|1L+eiutvWKY^xf;_^n={CvHS1$1u$dd9g-Ic-veD&#@CxPvj%U*(Os2F zsuauHWN;%3jxbqo-XlzZ|L)Ycq->rUNU`*9znL4t00dvq=+ z!TXG1%vI#1omapVnck_!$o3IX@A3M` z7?yVIifh96`XB=SZAMzi5#(JWBDv54wiE+XYwtxZ!n<&)p|;Ka8J(njA7w?NBrktK zTM~#*AIbzXOwf1P=2w!Qt3;3%?aCKWDNgvUMgbHjXtFU|Y!8<;^P3@c}Ab4@t_?4w%hNia*jLR`AZK6AsYGy~i z5G)O!*T61xWVek3Ud2GU-~vH@HP`iT#%w-8`;&LDP=vp+5gdhqPw;|w>zd@sxZGAZ zu>+1@*1z-qC*YfLl~q1_1zREuK$43-HWTI+KwWRT$wQ7E?EFD~G$)G*vi^NtO+Z&{ zz{*sM5Sv+`q+)NXra>U(#kXU}nG~O5KZ1d%O>B_El+4)LV^a@)C|!Zkh1AndO|r{F zgVc23W}<%O)$pm?S&2hkMMix~az?r=%LnN++&_>?ixtq_HM#NLB4DGKL+t#$9qQ>K zMLDyif_RR*y~VfSU;*mrlCgYDOrSN7!rAqn&p&Xc{}s5}whJC)PkIC|_AfFowZsh@ z{28Q@2i#+?tUm!T+tqKlo$xll31)Wg_bRII8GE0Fn{TD*x>Z};ecw2RDukseOl*#q zTx%XU$WFZ@Gsrglh$h+S#aG3ViiQzwbiQ+l*GK>p~L)12yae`sF1X zml3d4bn3i&*X7be4QH#yu)C?Fsf>oV!Re2aoh7+)Z!X?4PyWG7?1YO- z8K`n+8{YCfuz^2T<}_wyz4V{4b1RYk3yHhN&(Xa{>GnCN;v0HG9;XGLZS~U{K6w3o zjJ4{U*0Seo<{&-Rjh(0l;ultx3pt872LWv}R#7Xd&F=>5ar7*rR)&)-(Ns!1iD~6| ztc!7zzpo~kJ@}?Kp0lNwvwWfIC!MI>_KadD-Q}@86H+=z31Z&DZ@BIKkdU&cMzfKCvbF%Bo5B>} z9&i{sE#GSuJZooMC9sb^0tP=*zIJVF0I&(Y!R*~eIwnt>{K{>zPfmiY=@#46+t{<` zl!JRs%cnBB_&Ku^6fJ8SI#*S_0g9C`DQ~NM90Nq8D-mz@0wDDG&ur`Ec=Jo$P+p&e ziGt@-@77Qls7KC!+T(#b0hc#z;$7S4a9x;xk-qPK(mR+$%c;%KvP_de9?f-^|Xw% zpuYvR1MaP+qaIu``p0$}Gvk1w8CXKvMS?=Dp?RP5sFNs)EmYlr6Y_BXX)6GCNcbab;T9#*PlDShqrzW13Q^lxTvXjDv-s8x?mC-WR*Qj*OpZat5d|vbqJEX zdfAzN#$xUG4Tm#4o6M*pDo(YO5WgwnFGZDw#G7Mjm~%m9+3DADoJsK^O4=S-L(QS7 zgT<0r3~qM(H|~!sgOr~XqqvO(Pm`5pmdb z4Zh$*0-Q*3MUYW&8MSn~ZOK^8;5IP@;^OLx_<#mPIEzNh_FX*&P>^>iDVoxbWnndg zWISq?i>udpt3d8z4wJEHKg;CxYXUV6U`BLMagXAGbhm5@w1YwADX3AWRy52miP+CMEoNVi7>U52_{?AMG0e#H~> z`UmsVe+n?V`X35z6$A<}49#Jew%4+MMtnFVJHH0{_lz#o^J8H@o$nE!cqGQX30Z8p zZ>m)%7;`q46-MloC@))Ev+jp5ey{^sogbEZ+a%~R(>6*@tfww~?P4@eP!{Z_`j~Jw zj#L}_a*EW+d5IH_B?MeblndDh>=!c^7apyucV#{(Ea#n;3FhMip$RntOF5LGRb_Y# z_|BxEx*!tr*+g9bQMY`5s{|X#=;PU^b>h$WWbh3fKM!N7VoTKHQ$ z7l)SOE$&|2DNb>BDNgYsL4rF4id%7~rMMLd!QI^hBuH_0g7f@&zkThKTpY1ZU}erR z?=gng;ZNY<&{B305(dFLdUT{6q**gr>_WziB6S>#pV1NNB?yo#8A*9Y^c~eWOboE9 zUSTTYXZ+3tvn71t;KR>GfQVYcxc~Y@^+29DV)5Iy&PbuzFGPnXjX@;ahjsrxp|Z0o z?3@OhP#dpj)ALbtu5q(@nIWbtx9*azf<{n)wIfsvy|)+++TYe z8fYNe{VhpzfAIONBh?qa^siCcmS?;#UqQVV^|}B1_1*o-?!oqLzDRwxoj>`7sq?UW z^n_9n6O+9r*b_U6L4(~X5z)L1{T$u(CVD{%)&_)GT{_KO`batXYo{OMqj`s-3u6B{ zp-?Uy>QLk)vA*l}B~;rnC#EIG6t>g+6Ipx#)ZOzNkb1s;uU z2v#Izr&uu)w6iNnhtqE0pHXrJSR1Igf`ckf{UAAhl?p6Si2+0}@OJzGN ztOxyI|EAflCAhFKzXGgj3-IwV&ENleS9*T>+%c-)_sO!K`>jsA+-K6eaE0%kC5}G) z9P_!cBzLY08vtl~i2G`Dh_}n~zx~W8f0JPCButP`*GkGRnc??BbM87ESE-9%*0&_E zg8e4Hhbkf~>` zZrkGZ=R4zI8fwM=kmv`D@c}fBnH|}r4I8csr|4VKv@-*TW)6RA8GtW*aIVupTblqM z8X7*97Q3%xU)O?zmfleTf;%-cnp@R3pzU`J%}>yb#mB-BOjNSzotH7X?1a??FvTD2 zy3xEF<9vQ886ckY2zP9JyF?A z@7{zg?tj|Yy~fyY-LbQQwR)VCd?ZwsFyyk23NRwf!G<@U8wLJ*D@{V)Pk2J;giL$KyTPtSy z6#^Hkn@&3dLJ$B*6k<`ZAC2cce{wl(zD2v@{ST@0+w(`dYmR? zyw3idsu&eUn#m#>$KS#^{U6f1<(e0#B#R{AzXh4o+; zhA{YK?T#3q=G2HpzI!}JV-T7shxv(`vPt)5s_en%*>!b$PefyPG=*G&$&b2DSPbSrz8AP{3R15sli@5l$Qq=c){Vj8;ngj|lR% zsalESRr712fkYv9zBHtG`+=)_PLcJ%PFIID&Wv`e^9o0sJ9sNEl0gTS@qRV%IMW5Y zxrFr5#-9<1j%H6B$vhFzV)SDQg`cp^%3-O-BS_V04@Ab_q;k^06~znfP)3(2K#gq}BH2*`yJsy_xEV0T32 zRh^!kg8E(cqKpk?0cF}dz6aW*Gnr7)%Fq!))KS#1!{4FLv&y&PT7n0|df1WTi_%h7 zNQ1~U_0s;Vzfou<3k9?nQD(`}(8-Vz@K$<}_d=(>GeZCh?mZIv8a z*Of^^$Pr+>k!sG3XpR5kq>q_@sJD&dO*a{g;M~20k)+lu3D0!B%TQ>ok;HKT6d8%^ zL_zA^SE?g!uFIHBBIuRtRlyjCHs)~(*6!O!-iv02SpJEKa}e+}Mly~2`Na+8&jZ~a z4S~o09G;DDO5GspU<))pKE`2TWZ@Uyt>v^c8BtAt+0WQ`6&;qpgg9zZ=bKgBq;~)T z?{hb^mM_L*1f$X9L3+vek%f?j+Kxxhf{oUM{QPDYxRrV?e?hPxFI8h!l1q!B7I6rB zV43f2oY~x2Tgdwu)FO1pKT&IKF4At4DjJ@k{oq>?z6<9#V$R*M-TOZ66ORq;r9A0H ze<`t_2!(ykjlwpep8{AfwzU7osD=4hSyU&knq%*()Lz z0IK86cP?>zL}{`ad1^|A8IWm-o5j|Q*tfC+)iTRcoO=N)F_VU zYsGxdWLCq`)SC9ZpX|>;Zvbgr%+CxeUefqtUTV4n8Cv#H z0cxAyF$din{SXp&#tJ5baVbMCBID-&Z0p;*atqm=1?yd@-8QRA`=J+tYF=zSp~Oob zbt@n&2}Rq#J;cV_`5Lu~9nPgNH*0KdiAyO{H749Ss$*J`_LzU$XH9rZq=Wn9v*T9;v!Q`Eg9{eOAs>P+bY%SfV<~Z_6Tu`@gIPk{n z@maCv6siFQZ4VPU4uj$>A@dES2E{+pEDWmaN7 zoEEBV`-K{2mfv_DqgDOx=c-#J>nHI8y}{?)?O93Q+^c_x9ETSOLazNYg0I7ytxd<<(p>x~LIF>|t? zh2HlRY7K5OxCI;tk>`sX&g0A$cZZA|OkQmSnU>sx9}3*FC1pS)(n!HU2& zdNg&wJ`}j#papN~}TL*qGm{ z-zQc-M0%MB`TPPl@uZD>OD!^vU%r_vgpvF$d$TlF${_~_;KX04*8Y6Tf!+aO9%BZn~;~`$?ZMA zpukpNqDEXXu64kM8{CO#Y@!n|C5-T)a*9PgTH`Z)G~CK%X;59fc$kM#U&1;EgWcn& zB$0eqhoa^#m^*v4$FA=l%?mchukv_L2V}Sub9Qc&qVLvIzfpfCcUW#fqIwU~g{6HZ zeC{CRthI0(ac2#$`%u2W=$`%4XUn&yWr=B33Re{n#8wEFXG0dC)VG{xH07C2VwB@c z_ow}#<5R`KCM-Rtc`1iHiqN~UjS@Id<}hpmTc;LlpT z6^a`@vv8rHOpb;*iX<)Tmu6E*@atlh4F42PCwH+I1`1Z1@uQX99z>1OND zr@c)hr_UtR`W?+mAfatZrKqkgk6ab`LXcGVvS5d3X+^^=Ux}E6|wjlPX{|q zaO_eTng4b2Nb5$gUlkACY+Xz_f$HaP?Zyc+;i(MvuK6rVjmfim8l4|g?4KSE2LCaJ zat5gSpN=J*q>^I0H4V|;#S)d~{S0o~ptLu!V06_!9~w@6{eq{5*ZQuch+$XDpH>?NKz$t6~_<^x>2j zc0&u800lc~l@Dh6nYJD&HJT)bvSlSxuVTSd%LPB1n=R7U{fSEmM0ial!bTsHt`gWP zwpT~!L2_flYJd4MY@4s z5&?^;-`aN_eB_9che|YZw+93J+bk&zZJD=k<$VLP&DXyG2V?Bt`6AUed3V%@*26bo9YFl(j#`<9B_n}?8nlm1~LG1;IEMy2(m}YwQ zD1}t&0^t?@EEHzcLTirm-cbB4X4yj8R+rjtBXamDG(oB2y`+lO;uA5zJdXjZ2^&Ro z6~tUprwl(^qbcqpV006Q)LrjWinZN5H8#d10pMPjafutz$FvwJln(8;3wxh}T=n-Q zw_c<{32W9asMO2Vu1ewF>Yp`G_d4=l;g9~l&mox~5M=~~Ylckz^j}DUf-qowM5%~0 zA{sSszqS(u&wKQ@2T7EHpFEi10`}Q08Z6gh=}#^~udbTrvkM52Uc=P?*ldSsm4TQ` zagl%6+^Mu7PmN#Ly#^C@_}kslMh{CaHk%v;c4LGa9r_rMFp{H1y}`(1jmq;yVfh`q z&X{yNDmZ}nQ5HPlSpIOgac^&X_k(&1(3=JnoR6EDE+e@{|{+!SW5f<+0IcEvBopLIfEj zhah9NLsTzrYY=pR!4fU!7cwKH#1&XHEzK45J+&aa0ffcc6+?bM6*vZG z)ZkNSXI+yGAj3JYN~jE*kMugeY{M;u`cTAj>rWuDt9I)UB+UM`WY_ho+f`^6Y7*3g zUi}WcZ+@w(rtjUpCi1Mual4uQr?ChC;O@-M`ALB1!W*h1A|fp(t({ci)+E+l%KMlh znlY>)@z=&&Czv_3j(s^zWw?luFK zf+(x3Y<@5vy^v^j98S3}cnHHCtk#5i>$1OOzVMfuKJLyJRQy3AC8;r_AdhB#Lxp1P z{~c|h1~<+Xh8_lGrai*z^+c#)=SdA+p6H`0FQrJwNJMoXnH7`-@%D~$N>KPtH>tEs z92ZL&)mzcaGn#m76;|ToC;XDh9DVJ_!M*ttxx7LEG6kuau|rO)dq?Yyo8K-Yk2W*| zf~w^EWlkX1>`${OA{Zx%S4z(rk~IPTT)6x8LPDdjix&fa94j$}&k`igQ;F&bzvEF~ zD(WeA^|5u7>9#>6*>GM!_$~Xl)hqiZ=PXFj${EWkg~7(H%tDL*U4I{HiKhH~(%20I z!hHL0x_`xd|1N)I_w^SbzuleQptBfE;^S_n8p$77`I9`J2E9@k*_0B*0HKkNXFkS#zjBx5>d?u=wWsq;yy}w}KoHuVehqaZhN-p3EVd#~)OG|5S8UJIIA2Y# zd7HizbMw1S{&n8{3QNz6v+Hb(vHB>}2%#~~?fNnsQLLX_h744O z@z{~*ffOwey%o`0;;nMK^euczLS9RO_iWmhDuh=$BQbRN1J{cjW}0^Ynyu-IW@VwZ z(8gNQA<o>O#PciO|++kIqq zE5;JF+A{u}L8ZTYjArmXiCr7`T zgd1ILTGN~7Qx$K#*WfV_^N6tYh<(W>X)mmeQ*+`v85XVF*V|>h$;bjY&FaYkI93_> zgGDd23CKj2qKlqWunITJ9nr#Q5$@A4Jz6Ob)czAK78~r7olvjMa#O?@SU89%d{}(H zCxcJ!E{!69g*Q6Gor4w@JQbhOA+G)VQu<$U;B3z4Bs84g0&X;$@vEHb0-IsN>i7&Z zv}y=Z9Y^dZdL=r%$mxP^hJ}N)bu&UL#Rek*UM%Ofr`=v(Qqka817 zFwhwYVlBL4YT*^leEJa`h>R8+hWuO>B_YTf$iAaF-wc;Nk0Uc}k+UWkNG&Q8F!P`& zedw6d>0NH7Sn0cw>|7u<1EDxfix{KbE4Q&93=8I;n!UbGw~V{3H(Vvei)hlk^9GN2KX8`VrV*Nu z2su^H(eW3B2=#3n&Xdrhx5h{>Bzu{$Xy>BIHVHb^mMx}t_E3T8KS$KaX)ry|zz|84 z1LyO}@YhSb!Q;8kfW`#}g_)V#OEa-O2({?2HRs&Kq1{2N3rh;x>oJ|r876*Ly&~$a-s+eQ4iV*#mh-;pSU>;;kb71 zk)`1#g$cPB_Y-n(TR7)^7pGs^zGN32NDZWD1q2MKXB&66+3YCE*Np9iMyP5%dJlZP zM7J`%_j+2r>KwnmOMv>_0W6Y%q!TT5qzRbG2KAh7xz%q5>9V9}-Rq&5Z@+PR3YtRW z;F=KUYe9LFP=an?-Ftbz0r*sb5(8s$nV3y9O?A4Ny@p0w zm~I3T+4l%BJv#M1H!A1-hWe4i<4-R`wa=f1xEZ*XhZ23+^hIEn0m#8eBN>t|6&x=UKiDl9EXFdFjtjmOX}5D{zAy^ zmadxe;p}fDREtX^kdn#!;?`|>*=^fny4~MajwAJCazj#TO6Acte$0)Qt36;8_@Sgi zx8vf`a%xsLgbE9$z`VLcyx1(SySDTI0!S z;L|Xhp&Q54I&aO|IMcQr&Bf7v@7T8OIrPs|kl1A0GE`&Qo2)gd^NfeyBC8#dxqwJV z6oup*5A%uKE!M(}@+O$Ax&D!ld7-AO;qrB}{AZW40M2c}7#xhu~-ma;u7% z4AaUs%NUv>F^Le`_Ek&Hl`TJV!PQ8W#-D$+n}2T8mmFSnT+6g3^-ex}W?y_=)FoCB zFH(!)O^{|TQ&)ViE(t@%;9;4!2bPPzO=KH#RF*ag2M0FcQgwWwR)4H-m==RB-C^~X zg#qXDS``j{l_t=A5KS!1zfO``Z9o{z!C!Yn1jnsAJo19G@uJQB=jBuqdhyZyZ}pY( zWzg3?531rLsLZ#_NIUZgjzQ#Q9`^;I1vT7NGVWTg%gHnw1_XR+0}w zy7G7|fqRiN7m48ZM&8vHAyKAP;%k>--$hi!E zDUZtyUP)#B+Se2L*PgV8z44J|_M!WM+BU_yaU0&jE_pKKc<7}Wn-ypu@#dvFcd;=O6KlK#HnqA^2S;0txQk&|5bRgs3b8<9Lkh$LWiEnIJltL9dw;gYv=6hiE{|;9to6#bQ&KN#r z_~&q5+u7zKT)o`um)kJE4@rnqI{`-u$A-rnt4{e`G*gDxZ#)Jeh>1kyLrH>n$MZyqkiAP6#y=Dbna5 zzgpHxfd>(JsNCX;F?lNkDINrEqCePE&4j$E5Xxxloik^lQ}e^a9eO){_M?T4S_=|t z`uz3t>jc2Bw%zZA>27KEV_Z8Gtjf*1I~r0Xy(Q*!W!C-Va;v-{yy&-XzS#10N^7jI zJAwDU*qboU51$zEFq77cB?DKRCOg})*C5RwZlMg{C$kVN;J^n$owLQH_u6MEtXRPg zzjw5eNtg&9zkd&z0M_aA%y;u0d@H>a`240t_Iid^Vkfafi;n-|v)$sJo6{(I`Gk&i z_y`A#9=305P25M61($8*NE~b&^b@Wi zZ*yzlFiyB$BU`06Fa52Z8h)Wls3>wap~i7AO*@9)NgAHy&!F<6RT$S^LFMO{KME%T zaBM|Vp`hVt#^OU)tOz(9^h~~x1;kWQ(dbu&(Csxxg z)kO(j$Ncf|LBX8RY26|tf^6m=ceIYb$|L^2;qm__NLq$WH0&7Zj>^z0X-Nml-cxk!am^R4^kP&dM=$_q16J$8%W8eT!M2wSN`Q$MUn^*0mu;XA?u3 z88$n)$p-*3%kJd&h?d^0g_iF=Trg&aC)xug!ouVkHb4$7#!q@h<&lo0vnvHzFsMDa zB1gIFO4~s`KNRV5Df+u~I=%V|-XKHoy%ZYud>HBiL8j|f@+D@^ksclu1V=XPULm?3 zXBmYFJM46VloUrvfMKt?MZ63OHR}YUioKJsGn(qA*iV{gAPuBP*?vTXnI9H%fdK@` zr>z8B$V>WjM*Yp?-e+dR;yA6zk{{kw5i<(&Y-GZU>Ber$$M>lhD=hcGf!rQv_(HX| zThkN|CnkiTjXArLOhAb8bg5|01Qgz~IgrqATVUEAhO#6lhU!5`yKt*{()}TOm~(o< zWltvLgv{HH6!p#OKMfM1(_kkH^N`G#;Odmw+4@%Uix9qYE-GT$!^31%E~2x!|o2@D!?%qj^Rw z5CYbES39bABbj@;Y$Dag`2Pk446*jl2d4B0GX)V!S7CFo-K@k9{+M5=QA}B&9g`su zuq!S8TH%Mp;=qm}&lD;{@?(-3)eGw1(N+EbApvJ%E6LmptfM~A^OcIpRc#dv5KluU zKa^1kI*P{HM9pX!(8Lh?I&IUGv{q)Fy@2_+LLJ^y4}wgcTIOeD=@+^mzaLJ6xymx@ zr{qTnPQ#niU)dM_ef&-En9%pxF8S5*a5I6_o>WIlItiE2*X^^poM8)m0FtfG23nD8 zWrC(_P7*d;aq&_W$+;IMaT2(v+0ef1j9DJnxk{nyu2x?mr^@fa6vBU{Kt^Rh0L;_k z100cY(J`|>R>hLI*idBc!Ttdt?!w!&7T_pXt#liA$^9YP6wKtb_VHMsw}FN+a_#Zq1Z7g29i5#z4FT_LnQ`E?pJqG%9P0Kq0pX?eN?Sk8?ZUO696&J@=&hLX zUt#o=BZt@eIi8%C9Lmp(A@578u_b;Ttm4a~zQS~I)GV!L6C0Pb1ts5F9j+I;*cyET zAo|8Ls#og0A5K9euN7C6ag~DfZr%rvnQE@Ka^k=4U9KxUPDcSoWDSe1cM^B7Y~CIy z=h!7~&?f;GX=&s=#$>uNS-x~4pk;*soAm~p3uAZ^@8FYyzj)~50KOG1l29#YkEYIncq=` z;*IJJM&FI;2N-N?lfE+a9u^tfl|@H?;PL}W#kLJmp7mg+6s5kzKInaC#8-1NpSvvu z>61|`VXZaiPrIZQUi;30-;nnxcO^(opk$6+Z*}Rz7j_*35}|ISEdwVSn|Jr2Q3zPUgdgueB%*Jd z2t0Jr>W*Qu(Z}V^H?O{{rma`XfGYDAu{((@aCN*I8Xb2e<|5ij%CaAD(Yp}Q&m{UH6;*diy|n6`)j#`}uK^Rw| zeG-`&)VLK_P}AEpcJbjpY!=wrc0CX;j_6Lk6Q}TLK3?A)8R(`D5mG<#HAy8?uz^Rv z6=D9yWRf^8x^c)t|cic`DfLqP{Ju_Zi=Jt{Z$fNg4MY7 zM!UWJGqoy-AuqL_cYKy{2JVLwj)H3f`vsD(tTCUG-Pdgv7&Ii_-+zgHrB;f`j(L2c1xR2vyQ}0 z_5DMn^$}OxLld?-yIqT|I_|aKg`3;E5q}Kj)-@_Fj=`$;(4n;i6i&J6rUk)Zh$hJC z(Tt0v)%y^7cAnnFNKzK-BsFgqywPR35ux5uK0!`ieS^Tcyi9_R4@`+bo=Q~G0*Igx ze&1KKSL$si`UTY&8y!kRb3n%nFaeoN^Ri(1KO|{ENhT+E!XbLP2x-diQ>A&aXdo22 z(#ox$GuW({G6h;oY)P3?FTcEF`dREYT;%_y*nRQYAM>6Lv=|`FzlQI>QcvHutt6$M zOJ{5GU5}hwAih+dBmvprQRIs=x=|yO!>kf|ubiicGlpxY%G; zD>2hcRn6?{&%h<_-G|%b{_2<3u4i$6?-j6m67!dUTAY)2S;v4IHRX#<#qZl2{~%Hq zhXsP^YrXED&)x6nittEerN?9H1O()oU}NDNe_e|5>BYCI`t;+QipQa17FH2VO=D=Z@@rxPj;R}Fu6M~rlHz5PbKib zVCC;`ewy|DPM@LCw`Q|%B7iyE3K~mvnZFqKGX#%zivb(4|HfCVd~T1B6{GHeaL*oW z`9e}%Ann{e;eVnQS_PBZC0er|I^({L5~8gQf??mv-vtkDB=PQ@54w;k{fDI2L429S zu#!qUQ_uG(R`&fcSXI*EX4@Iah_;-qrRm%ivM?6m7p8BoxTq7rECK}5>+B(F4IT$o zb2Zj5AJujjK8P>ct@kxx&N|3>Cg=|=sXt)|ogrH)FcPO+=;8!Eb*}*Pu?9!tW3Jc> zHDHj~jgnEIf8uYN;23D=C z_5_n?yx+IOxpQw89HlWQ3aN-Q^~-n(10867jt!cCu|w2afZV?hDjUxxP^2Z+N+!G{ z8GWyH337p4XjyN^Jc+9C?#rq>7%uhd^F5Bo3`R((a_9b76uq2PD#aR{sU9Zdq9%Ld zEZY9!K~n+`YgP8!;#0`VTKr^gUE3!%JQ=glPJVS^fDBq!{F{$T-!nQ%pZ+7m^9&SV z*#3QWOP$~$;==)@9Z8{*OCsL+^icgG=z7Q?N&#xOKm5zZ`>3`veepKLgybfsxKl10 zHF7niQux!uwdV1ENGxzUuy6`?Q2$$-u;)b@7K31WICCG&W%u*;q4mxHJkG3#3=d_@ zYcc^CC~&H=S!lbwfSH!P^=96D=0i&S@wtb5hCLSU zl8cS!(!gQ$B~dUd>c(X-j5%UV@w~z$rJ$qD7ypaEXQqfx{~=AZ@iaQesGwNFw&rP+ zo(S@ck}SWXa4C;xlqJiFqPD4%-jO{1QFNd}E&fuEC6@?65|sVxt|ue0yG=6xB7;!? z`0nIAlFVhx8mruooA;w~%lNOoBi9>TdFh?!#4aZ_Jh$ZPu~R9ERR!gKP%6 zd*sv7pP~=6Ha4=OF?8{w!8`1`)4pF5qHf<_M&Dfe$f)^Zbcqf3Sw@bxCO$P92J}$2 za;Zh9=DfvGX&~>62}{oz8Y~0<8Y!H29XaM^>IxAvMHu`&mvb>VyH*gEwl!Fc8#DQ` z1l_M|uY>*Tl>WM5b*nQ+MUt^&h#%p%DxXXBHF&iPN2VN(@V7V>F_W0Q9RCrM@WHkvYZ5Cbpk8D4Lyc?RcBpY{7Y4(I#kU-lTg z$66UafjgH8l|Gn2qYoXA(;Tj=JHTubZy4%<^F2-KP$HO1b)j48{w%03F3HSkad^J~ z5y^O-LYsBtgRbr=A40x%M^Ed^YK`&AG)~AYNZwXnNcb{!HtZpQu8Oq`@-$6)h{XFj znN{X9)2TG8hEEQbWP8-5lrl$FF8_%fEebSI)q!!b@BC($Las#GqmN7$T|4Z2!xF0R zUWa=u^g}_OGZ7)1_%H18mL+uLEyO0{}{PyZkeu^FnxmdtVB@_F74ErbL4(HQ$7A`3E%j zpNUf)4cJ=U1ZlsPlu`BEbIp(UKfX!?2fv6~szPE737OJ#%@)Hr(Lx#M1~_Jc>V$5V5N=X0!e6 ztV8HcggnuVoSJi*y5pUQSf09nr(as`mp{SXE>2`ANT^YWIZRM^A{0WA8UY(u*HFjc zvsgN*SPVjTJ)EUBKBSMbdX)REFI9h^s$AP6yR1ywZ4?hjILTI}7RhEa?$53uRJYtw zeH#_#eFJaokH{a{!FL=4jw&t;-)jG=4d}sc}zZVlp28KodB;=Z^ ztnTy2v51l zA&0z3i4wQa3gutgo2H`##ElUxe)IW}7Ozr3DMuqlwHKwhSpHhNjaIe{VbXYP-HOlr zycZg#hjkD^{F@wCKo+SZ0h{)NY>(FOLn&N`&;-gitYe?mQ8<+Fs42B&jAxVi3#lCn zkbAFZ-_M(UTqMkS{2f!4^j_)3Hq(+`*CDI0SL0;8ONv;)zX2}6FbnEwa^qmG$CuchsQDz_uJM$)vGVZ_Yw+QjP z@~S2>Aye}#E@2?HT2r=s2$X?DGidR4Hlh0G0+TqK=I9PJ&HI_@5p$_nY4(c9*L7r| zUu#27HZ{Q`v=N%Y1h2m*pRaG8b~)06WOJx1Ij9N z@twMi#q~aS9=_OGr{^3I-G_hyL5fokoJT6P9WMd?KPIgQEfd}-fhtfQG1)e~4yiAc zeBKrd?K0|p(A-7~BqS(ycy47-Jd{VbFGm#T4q65_DS_u}R{o$LEQShTC4F6;uyy|a z1xut(zI=Cnwf;Nx+TX2^E&F>mK3CW+)|rDzLI@|0xTX}@dq$nSEf#EHt02|$ zRR%(9(xl@oha@z-$S^`IKb@4V{wn$>u?|x4A_gj2b_-5bx-fPi;p4$$%r|pdy6CdQ zK15E(iF91{S~gWZ>OiRY0`Dl`>4wW1zG)FUQ(8EA#tx<$tD zA9mj};PIzK+2J{o)63tj53{h^5c$_}Q_1Zl=Lrg3etu>{di8Gu^RXF&DXAQY=TS2O z7ym|f&5&bw2!8D!)T`K00zhKEDn76_IDYIC7V8ERNfN%=ZB`tCo1Mq&*vY;lif*EX z>X40-$#rIQWeg=-z4neZ*Dq3n3hf4aPZA|k*;8?j#u~&&#W5KfI{Js>IibrV(0_Op5e3>*iR{Q5E{s%?sABd2vA&POK~Rm@X*Cf3~o3f;r9;Y zJjW-qJ@rAay2Hd8iIFi~Ruj(gngTy;M8(Ojwdf3k=>VtCedNAcAL56K3O<-hf?WJb z8ZQ4sTIb~gyrdyhW2B~gE~SV!bPBu}GhSaZTKk;6#5N2BxDV%2;rJAach zjcI@v2Nooja;NPfiDh~Hx^IMd2;#%`FLO3{cI)vj=s17d>_4Q&oLN{<1rXXI1n%~F zY-ORpE2iou2dF)%b$180B1c_)uYPx(3C3wc% znChOwPCU<>??FmZYr6*i=mM`9l1dva^g5g}=FLLFwRt8sUMj$A6F$Ldhbz;JT28KvWPJ-uVng^ zcmMtc7YRyx6MTO6vl|H>3bqyb_1wSTA zVW-5~W))@#g?jgT;G6?$BE!!^U0KyA5byHB$<%`3M z#VV#!YoX<^F+y+g|6;w+X%sU5{cu8ZWJ>-dTg6ZlKE2r_fb2Eos+!?ZZ52jnW##4A zkf4bhMdB3}Z-o@E`7e{a!rB9T>SNQR*pb>J*~QfuC@7vjSw??Am5er)W{3bl^|+qw zfq#Bkj6>TCzH#EVDHBqfENH{8^rRFq!y203I}YpO6oW=fg0Jiw5;bS#fJ@R=ZQ{nSBy_LY ziSAE*$D-*7OEE$}vN+r?)L4M@n))d_Fd{3ZrORqmNno=7m1RTILtE5*Yqs{`iqw8o zkL!AX9?$>d8^V5bCGq|Ziz>+#xH#9Bc3(g)OmPCn&)5r}N{R#_0cV;^QC&l# z?~B(rDhu}SYSj|GZK^j15O$!`<~NaX)~`sx#Y-9n++IsQBA3%q`4Zzl3Hccj`8IK0 zg`h6z{TC6Dl&^0g&2~ACWlMD{y6l8-!BLY=)HlOnGy)yl7H{Jf^;6Z4e?t}D;IlSr z)3$hePSb52Z0QZoPpt9G5&Hjx^@aUwy083B%Qo>|i$I{nmv*%eTD$&DiFCk0^Mgqq zs4PKDdtRP?n}vmaEtwiK(3_X(%2n@Rwr57k)|$f=htFJME3AzkBTpYY0UyQe|5t1NPqIOLcL9*o4imf)AP3?|0Ey7zWb%b}M~DyV&34&={X!K_3Nw5}7ya_ZVYf743Q z$xCw%=%aQGl5B2D#R_DIzdGRM`xSj-`Hn$TC?H)UN^6`!ej$TgbQIM?%yJ?lW%Q() zxLiLMN=Q<&B`(8oIo@V5!{#X+zstLd6pyv|y0MvH_wK8(n=#%015`n)zO~oOl8Ho! zMZ5mFaEyNCQ5^5W5`eiOZ`6>DxQfbBJSgp=Do2!oA|?Q8e~KZ(1GLmd%b7h;C+%-W zAQ_hR58O2>H;4K`#OEV&V@b-j=o4ASR`+IicI=ZG2;H~aa?GV#z=NkIb!U~A%3LFn z+YiiP0VV)SA&1Fvjbnb%nE|agh(%kEfAo*B6lLBA0D`ppj-;(f%DIZ8%Rg5!#m{Q` zjtR%eiI4ozkSgbj-{?P-GCVj(*a2HR;_^v;{ zxb@EZFo`^uXAK9QqA$_FLL~-3JfHyaPX>ppY{FJG`?d$bD4QrPD6w6Sszaaqx#L)n4i z3ZhH;TO(2`ip{wF$Cjl^ijt(+4t>uBuIy`0Ax6@W;|D~pH4U3E1jf$AVQ5IYE>E6JIE1*B1K8m z_?-d>u38;}AcvE+()yi16(t2&*!l_WF5$_e@}~tu&N&9La0aG<0|q=ui%3iff2}G_Z{uRa>n-d2m6x~8{3S@jvb@Ko7&9ufLZ%*rm|0J zXKK4SLoayEmgklXj4^~nF>R1Fg{t>A^+`!TmTyYg*cWmjVrz14d*xrJ!mI~Hy<#{G z$7Ss^A}_;$m1?MajKWyNzxI%wAu$RI3yxY7vl#m(uk*Fz{0v zSM;ZP_oI!Ea(p32C*TTriSN=|ma%ZFlQEHYKlCifG)Vrr)w~0#dTLMQ3@4qsOVP%J zZDU(6^p4w6>fBF@m5Xt{W2M`+D;V;P$w%{7iy2rK@nnDL~0v| z4WL&CL1r_zBWa=wk5IeQ%R$L%LDFMmOv&XVr8;$P0c#m_nD#}uM7bgn?TFCzV_KeS zvuex%j7jW>Z^0kxmjU1wqd1l?*$5s6UsRu6Nvf!qwk8nnBpJvs2D<6z$xKzI7NW=M zlhAcPYN$egQ<-*oytP$kdv72Kf2Qo3ciWpQ$&3M%4=HF@Kc&{K-!aNtmgVg%*;&TQgr;K|-4H$YrX{2BSnl30h3A>y zK3z^9>PFw{#~X9C`D^S6ouk}5drK9re{J@~{6B|ng}v>2gh%BwZCxi=KWxA7mMf(0 zR~yBRCw3>|w1iKc5ltuUs)9&exe7vNJve+6w8k#$vTb|FklZnSLn``^k%@7kZ3}oS zt2Q%t&uMJ?{5IQpdsYNtfiLb}!n80l??6Mc5S80~&|$CPs+-}j?7p$(v;8FAWw=|7 zjGsqoHNTOO+j4QOL1W-!k&%@=oQa>V?b#DDdc9XF({mSP#hx6qGq-CPV1R7n zf$H3zpUV?Xc&KWQ6UrC;ILdIc#^uO@L|&g!&=RM7((DYFW*}9-kO&tV;{$Ag&cR`?C zIpr;6T*|wVk?KfNN9d0r7U#nnmRS?E^vM1p;I(P0@VLfZ@+I`DiEB>+{pm~qeuvjq zM)|&7_6}XFc|+B?FOrrz%Z}@B-mCxwKp^PkADYGG+I1_U{{VKFj7veeP?el+SaHt`w{UK5JKlY*zYgF1 zTZXbf(+G;l^a$S{o$u4+U(_G}0B9Y@bM>~*X-0cS-6xFm&;IJ@(u7jjJuB5VyJtV2 z`M>=iHDAcRlX6!tTr-@@l1U}c5>BO0^5@rAuVZH(<-#Kotrkfgj?eAmdTN}5}SErxH`FZ;NzlUM&57PS{;o5yHctY0i zWIhe?K_JA4Oa3PETkDQ&#(yu~^MAwTE#GL**)y;0+mSVIJEKfgnCe5b$&Z#RC1A0r5b& zcpwN81K@xlKVkwDQ>(8o2tY=O_;5hi=c=rL)FK=d3yL;BVke^Dibxmi=nGW=<5A*_ zi@t~x>VY`@=wY0?@j#xMcq2qlk}?%7#Sor~fW#nQGz311Do_tJX(fCa05o7L)dNp1 zNEl6NQOOdUUOs4PG4Vwg<{bd4B!0B|qGRc(Caf2w<2iwF2Xh*ZA08-%xpT%xmV@p^ z(t5P&c>?7S(;Jcm$cs_tXnq`!NdaywVmrCqA%~C}qf`7OGBTh7oMrov-vk4foP@ae zw;+aT&lsPgq*R~rQw@CU z$h!%hlKIESy)yH;Y(Hq6b);E}<@#jn9dE675ZxjsVR{Ax5*{^;DdX~2>d)Ds42w4a zB4WK(aZa4WQcvcrh^;AgqSgpZxtH)pZF3&$*w49kd;3_*{Fu2YPuK14Ai%zg#{U35 z=QnHSuX28!=X-w!)^1h&e2Cm7qZkp`&Dvy7H(p-<04((Nar#cKN230UZ#Xl@+;(`* zR&wLpbmPeWF4`GH@!+xeT((pFj(_Vqk9s2AJFZEagpb_4eqKZdSdcDdBH!kbSIKNu zyP1w3wdCAMT9J)nWpDUc)V+~v&-rB_{{R6}n9G*W_l7^!8#eCUmYIaC?^Vzhp{t$jr#JCqgYq+XtZ`=6np6I_kP} zj$-}}bf<934)w_Z4CgN6Cp{%sT<+HAQMa&*wsO5I){U9V4)kSgh9TlZw1Z( zUXbM@Ma!qEt68jwc6FLYfd2qOLzI<7vaPrm(}D^Y*hn565|K{fVvDOb*noMgs>8AS zP%zNz=7Q!tzObY#p~07J$dDSVNcMe-l}QOB=q5)R~o2nFcu56CSdDBJH~?G7!Y^*Xv1gzbjyZqnM2#EwmhsQ zd7rToh3I-v@0)g8XO5n3XoPT^hq-SYqk*vP*SBrJ5AR+NYZ}lcfw_KQ2LAwuUTSM{ zPnAFRLzpey_cm;^u0}>fZ?g9Agr1*GC3D6_x+W#>_-jt>s96^5#x}9-4%kKjLJgm9G)8w)=P0jBjodXvjP}+*Fj}6JM1%-=wH!AA``_YKW{t91Be=)XcDQR( z%a4ggJ~KV$awaT3k^M0`Q%5|JV##tq4{Sl?A4tCwtDa?97#`^oB7TM%YB_3kJyjAD zs4YU`J$aQ=PH02{Q*uVK{+RvMLsG!Vk4$|;emU?RABkG>%5WH&chmWZH7A*MSv*_> zMomIM7RJB4Di3)fpS7w?YTg5h>a>KWVFVSnu=uH^=FdE9Q@IduMgU%k?kg%EiMFJ7uBm z;v^gu=k)7;!zvTKibr>?k2vWlmmVq(lWO;_`-6HGW14SRIt#y4XdLRbI`}%2B-*iIV<$H+BJi?jEWB}W8&i!t03Zo)J>LaBv2W{s z92dIxOWStiowj3P!25ax94lC`m8)V#BkP=48A>Ob$9`RT&wnl_^R})7>C8X$%7t*e zDiF+asaXDLY(;y7H};mDdM=S+X}j zRfF#7z&Mnp#f^NznAhDlH@xm#Eq3I9;mhEqgh4}aehKjkt6wotmCxqI*p@ryMvQ&GaBKA$h9~~aRe*RSz5An zGQN!1cdI+r6ffH?FdFT?F_6?1+v8s=_WZBs)_gY0jw?<3*3`Z~E4ub=j7udY7Dd$G`soTsCiM%O`5t;T_w3 zvQ4|BxW=(DLMBCLAb1Zlx=x#)l#_e^0O9ecxxM4Rd$&I3e)XMqF6k%J5-kgH{+n-FCg#B+A+&g_7QB%KrdIpe3>eZ4#9x?qqhNABiU=NiuA*?q6<8zjQ+MWJ>@ zq2uS{d(z+00}WI{LPSxCG00jcP@UY#c{N8Uch*!|y$Zy$4vac)~O zIQiDV{Ks=JbH*d8&FjaPf6uGOr^a6H{XgHmseWfK7FVzgrRZnciIim!S>)e`&3XFc z_}<)EZbPv=2BrroNhdy+*`!5u1XP?()C>=a{W8-;$q;c>%|!(&x!`QH9#Luh`1m> z21GBK29kaVfmK4~L<+7DC)e#oFDjsLuT>Y}Fy_dZaVWk_CsWN6Omb+80rYAS#Q;Su z5G{H#C7?PYzgq;N9DwDT0540$W&|kY&adJJ??gNYaoS=J;*p^~Tmmjr9x$c2f^~ia z&x#;=W@YCgBJK(NBgq&1rV)$*lbe#`IUlh_{{YE3)Q}_nO0sc?JbILC$|+7P2_51e z0pf|_3Akk;+V#}OO8nG7E@f#>d2dV+_$@XbZl-|SFy4qAuC(16uV4h3q_;^fduLZs9XH9U*$UAhdYDr zeb*LI{{V2yx0hg0&Q?Xc@BaW5vlt&Zr(Ql8wtTwl9_qonYt$JA(`qJd%={xDeoGUp z{56`tYkIkVx6mT^x%fL_a1z?nu&vFf($$FW8Nf`>YRUoyyP5zW4*5i%g4fslvzhG` z&v0$H=eIKP#<~9hlzlTGd<4qQRq)T;caLuFICt?gt_!%i5H{`$rraoXV&#gsZ`aIt zw#)4tTz%UsbJ@MYYR*n2!T#5J22&9M$M?Q~B}xz%4!;jO9-02+lPuW!Gj7Ms%fqvF z_55qMi2m)^M(1ffS|o<>T9-Yz-g)?3{{U#5ztqYjrK@m<&RxZ8?qoL3$BH6bPJz;ou*^uoz^|MSHm+-UuyE(Mtmp|@Ri>|sDYpO;JdjOf)G=|%2SI{=xgQ-oQ9fS9 zu*`qj*Fvmkx3cU;f9=qKk8rnkVo($xiNPg$zduejrziSBkTaDd1E<4MR?y)IxwmW? zOrNTJ2O6Kb1&eq$JItr`MpgQ_&7?Lal#^zl3xD~f&{{X692@>DnZQ8@z>`D;rw{EkXjEtu#e^lgL$c|-J zZS&>FdxPFvKFes&FERpTJYf^vISxQ-e#MTvk*;{P^WVBZQ}5%PIiE)u>$^vlip2aYvVsPG%+RW-jGI)NRgJKDkDW7`fA4HRQEep4?{Zk%fW< z%=_lZA?@M-C3=1k;5x~1y>F*(dH!5A-*V*TUO2mbpZ4r&0tvQW{lIuiVzuQKS-kw# zqjv|{`T16Td-9GAxsL00WIw$i`k4O!DDn6rwXyaqc#(~}5gp(4Zhj*CL6L8gsOoWX z;~24TP%&<2_XWhm=?ks1o`=GtepZYS!h806@uMiXGXdf_KT@-Lk*UqE zCie%tC2n&NyIQjrkBf2fUT*&YTJ-*Zo_lzn_3mtpiAdbYmB^hTqb?I`cO!?ryj}#D zNC^J`OsW@LbEaC}tck{Vv18mno*cS`aSJy7CgU4J9{g=i+n&k&H9WX068ce$HylzW zZtVL-M5246@>Q8@xc2`5yEoiBQ4!9$FYa~-%j$>#JwbIg#rn(cJs$`48ted$<%b!8 z_^#P3fAE#5`Z@Lae-6uS_jbX#x1pa1O#cAWx%8LiS}v2fJI7Jd!cd$ckv+YTn>lS)S;VZ~^V=Hrob9tJ=H0tuT*1t+dv02|8l$d-a_fwC zx z#&(^?5xI6>lFDe@1h^cF^j$c=4F24IXF2lvHr3mAt;XaCkeF~sBDek@Cd&>=8{9#v zfV=Tk0Fpda(VLYr#08#~M=z0fFq0DJfnGn-y?jpyh1h^*W&i@RCq>QE9y#xC*8QK` zo~{nX*}U%Yc$=8*hE9s}aKan0!Ko_U}4{{Z3f&gZygZ##}|>6Sst&%HbO z1|zmT_a)sX0)ng4>BFwCS4$fPcjN;wC0NU_!P?_)Yu*;^ z-pI6LE0Q0Uv)lDfM?ePw!FvAyKhGzZm-PKSy}xSP?cm#(m6LM$J-?TYDs&J1A$9Ag z4A#7(8za+*jPoZ0Im$8mVDt{$_yy1HtX#;1my7Hw{FuEpncTr!QA_D3Q|QT{=|lCgSjMt0-q&kG|G@Qksq$J3vz z1pQLtMllC~;#Us(j{I|V^9Q{Bk?pR`jLo|sVBhXNwqikq=2?K`IFh(e*6Y!E@#Wz8 z*mJ_VZQPV*z!G9zyjN*;bJpEP6)OBW^Jq z8FP1(-S2X1V%VPwt08)M-bDN6WbestI9ugRw*ZV#YM@72@I&C=u^J9u2p1Y4HPw(O z)fupl6a$TQL@y0O0ii$&p$Q zx}YOp6b@0c(E|Gr1O%G>h{(NaUzz|2$#>g?y2bpHU`O582P z_c#V-W0!gDjC@0{PluBvO=34;5-u^9NfOV_Mu9D7>ECF%NC9bzRauh}X0Lnh`D70iG9;6+7Pah;? zjKC2SsgYq2Dewps??wZ*F#z#8{E#%0c98nt`9M9sCy7Dge(KA=vU{@^b2E+Oeg@7? zC@l%V5%iOwAZS-V*4dTci8|*VyRmOLJFSSq#qp77#jjyx{{X21--b~?YIEGb^5=QH z`}A?!HcOM8sAkJ-PQ|7H#9$9ky-4$o`nbN9htlbWUnj9_D12E zcICmkoLJnG$~~meXisSsJ}bZJ-!}M;Gn`kS>8?fK*Z1Kl2Ks$DXgp-GJD+c)Mk@ZaMP330Jn{fn(4O9dqkztn|_u)}%g; z>!0vKQu~zp)d^(XAeiFZ?G-bhYykL_`i^%$+?KKX;p$?-;GiA;p(ny2hnZa`!*@?kM&PKayBe$_LsUnEt`d>IOymPak5( z{H3`_kIm2OxL^851&qBq$tV1*Y+t87;of_9UGj3;@iJOM_DClt@HKc^HLn9E3jJh@ zy7axX+S^{u5O(|_8G-d?-fNfUddSj0^0LM2R!w>ovyX4G zKg}Xf$~yd2`kJw84RIrt;V;)d*+Gg$C4y2xXKZ2Omtvh3~+x9%C zCvfD%aUN>@Q&;WXj6jqtA{oGNACTfx>NK(DWj@G9wlIm4RQ*SQ=1&rtgla|-aAHKr zHP*a<>Gr5VMPzPJ7}rE2 zYa=J~LS#-xcHq)sjkVG#Orsz_>R7XiMRlS85I97llWwTO~HOv&We!2bYNMWA^J z1|;jM8f+zS8AXk|gYm$IAf7!!)JmQrW^QX44$&j1=6{N*Y3@kui25Dn)d3-gY<~!> zfI9hk#<}NSW4vz{Z(X@=-MQK}%ia@k8MP$yb>_D9UWq3$ zH z*+;;YsLk5a$KLX+u#{nPF6NAWN?5V44gUZZ=9?4iT-%nY9^ZF#eg(pPtSp^7952)?*tB!;p?q<hR>lxGLwfEM4uEk?;1L+*PiZo z=YDgMbKRsu8NgvhRT#q%z^|jJWWoOzpugK7gq|6wG6{!Gl0oE(G7h<1l z>7q7oV{k+!FUTG!f>=}H5ol0&a0)Vl?nk9=QfkV9ZyNPmjky>J#7@2X^5c4kI zrY5{ftD3WFOa!DVs#E9NJy>#86eiK5>BUbXCUelLEm*a0xCt>F)PtzNwSX90W;``p zS4ZmY76c#&GCW#`#YbLaLmPYB@yL~_9@y~Eg0W`0b8*$-?%4UT^(7eGItL$e=Ibn| zGV(2B#LM!)i65)9Y1AtwrNkC9v1cyHL|YOSGWxr`mHOCA5513S;3F2~NZ?~fQnb+9 z@-i*8nN}Q3zT?3~=Dv#kJ@*W+TN_?f%%^NVJf&BUFD2WXvFHB)Z}Zvqk6G1i;V|m3 z7)sh3DHf?&s?EtR4QR8~YnbwXdV9NL_N|#@Zh2xi2qxAfD{^hhKYH=^ExsP!Cyn&^ zBi>)C+wZx}+)PW7+V-PCjcP-D`oR|3tOVsgieb`t@5acNFmpbnlYUfJh{ynRbHBrJ<^$uxdX?$s zJiT2}1cqg&IdLG7r_Dy7zwrpC1Ja1Ga|{!HEHp~rF54dD?OUSfj*-o7IVR=lId-Dl zXR5}OoRwVBAMr+QDsn&#czK{r%?&jF0D?3_ssXA1fgng1I%=y1pii$<2$w*RBnbjQ zkR*X1T@WGF0zke<6Cg+r1i-1U9!R7?{lO5l@jz5;sEnGb58a{%`1vT=a&mxCwMIks zbO;^_pli?|T+lg2$Rj1^R5ah&)d3KYB7m|5`xH}vuAWK>K=Vb1b>NC=I-Y16Ygf?& zdGSVUHB~KN>`^Tw2=YMSI54h=uhv1`Iz_aSrQ$o&EgsnZ5`L*@JOVBVwprv) zanzay`${1nPTBlVB6M%CAcV|F%0hB3C?a_EKe-oBk_3-@yT78)6!SW&hyMU@{y(NV zMghL{0|lWY+5w;N;8R4C0ucm}2Ot3Y{B=dJ`*tTL?uq#F=!lx^{Rl|AaqNXjJjp4G zE5JSVX68-9d$Y9IyWJ5I=Dg*^u0OYzel9U~?D$3&=5ns%+7aCcsntAm*J zK=^`G)rn**yF_A=KdSA(eqk385p(%0ZO_BH^pD)Nu#Z zLsD*EyC``Gh{a$2;`8e#{6foIhF<>w?d(A@hqHR71L?VbKmd4uSzP-60B5StKZN;t z_U-TO;!>5oGYorC(iTMroSb}@EBf^9&*jW{?%};|*`%DTyOI*s=4I>9lt|)xjGc17lePUhdKb38 zO7?B0+;aD;@!WG_JB~P|sB|w`E12hcuR}RgwFp_pw+vel09wbk1Vl#)3IxMrFF$g` z+bx`p!zSJ=HJ#ZSo{@>vto798dFQUZJcHbSsaEGHSoZEeU;xDC-TJ0_jsu$GZR`9; zZg`yk0GBoG?`M0f-`TUhYBH8Tcm3Awmm(}%9Dbtx#Bz;R`QlG&dj4NT`)~C7+aA`4 zyNzgX8>|I)e5i(u{{ZwX)JLH;@LH^Wwb5l`o1azN)AeRMryyzr>iX4U#-+szw!~#t zi~bSBfyHO)*V#gSrcDSr{kW_3si^%Bs7 za2#lstZ3K*++;*SG9n?qWb;|ER-z{}>BZpnCD@-HR9ce}CA&aO$d+IPK&3ejNou7X zv5{!^7Nkax*P2RzJA{Zd2Cv8BwGzX7J7Qwrh`Vqt&GlDM_&KZxbb&wJB7?)hT@!jy zFcOh76!j!@bHQCok^zXd2)O=`8lhB7&ArF2y)!4U17qZ+jj2j+~a|J>b{*Nuho;!%szmiMNexCqIh&@BqBumqg&$MOY5JN$zS_MN!Isr4&b#_ff5qAqrF5~7wXZy#~J zWu=diD7Jt}!ikc!F7G)x5sY#OkcePKK1$oE_0LAxo;>6xW(>Fjk}Z{fQvxm|;0i6v zjC*EY?!7H&v(?t5#I`Z27&~!DTGks0+-#d*HP8A|>bE%5pQqKtWntgj@@`^fTQ=_7 zEI}VIx%I{6>F2GR6`m*Xg_e;>f$>IaASCa>5ZMw*rie1K?sr@Rgm^8+EmjUkAgWIy zPiSXCjkxz7>3I}BQW=jVL^HTaaI9E}nv?KaWfy#@@>$V6vm>Qdm0K9*QtgP75usLS zwJck=45Z|Ns0&KWxNchR4o3wnrnUCX+V(7<9pm>bx5sZvvAfyKwFpdu+9| zh)V3`2>}@ED0Ai(nYBjVQM6`6`;3l{^H#+BS51YvWtdyH*yNB)=tn}i-d$%;L-zjV zn~9f=e%-#)YC=v84@D)%c_&jV>1~(XczdOoh|EUl1Jts02ak&DF1~l|{=Zy*!=fY* z;JS}GBgf`~rbb1aTQ@J{UWJPmVr6#i!Xp^OaU{?wYg3zVhs*x}sGqO6I9|Th?BN{j zs=|A`!`Xq;`*Hqr)YHXF<>;TEKcD{IZ}9mia@@Bq>n`?o<&|?YD)A=Dh!4x}YG^#E%Hu#@e`D&$amrP|S+CB>|lDRC2nO&Lc zw&m4T*1XYyLkR*vkODQL237nKq9gbtCbz*FADJi?gQ_xZRVi@bhzJq{fpG9ZkR%6# zG5|F|kR%BLKz{TCL{dZ%ssqS!P!F|GhaRX1pl)g@KD-d7s)P_ZM#&lY4ho@D;(<3F zNDvhWrzp{QBQ&Y|&;)2Gs|89R2oeJS00ab8MTdaw)I~@KR8lTFpke{nf&hRZ960qx zOYKF2L=Ff)S)p)DOVeTmyG*!0F08#T5#F>zQQJ~zP&QJ#Fj=D$uP}lM25=>=qyRzt z$^ZnrnlTL3JP;x!T8A1)=*S-^N3=@ervt?J1YD*VUYYH*eJfwo)jkT$F+Hq1R^{tX zMt51gNf$r3c`0e~o4QntVcQYMnDaw?v-0~*sWB`CWyAQCM~(ZM0NTFp9z@1GytpoZ zqpvmQxYKDK-@^53I`g{UEqfSaB4@Y)2kk|h8s_9*x3)?%dj*-aAFv8zUw2=Hm6vJ) zH)bxtQ|tUcH+0PO&g-kh+^jGL+$2b;?Erj&POMyxPkPA3wUIeQ5m!BvF%|Pm-(Sme zM;n*E+yYR=jGy}Da!2n^zhBDu{unaP%`)!0c2^0}=P$A7uivlbGFIN-o0W2Lc!)=f z2R{_r&2^r*w+CU|IW75ewV9cll0oefBaa61)oT&SW(i!Ffw?P^)?zgP^-~Dvb0a7` zX$IA1#@zkLxgY~Ba*~ZHizeZzcHk2Yt$Z9o-JlfJ79jTlwQ9~Zd*Uxb=X7EGz&52+ zaa;6^?+b@n#24n3nd!`i9kr-BDe|o=GWz1jf-PCJUUvrqs#SZ1;~~iChsundiv$MA z)xwlpC89pn8b@@10ah}K+|O|26&sk7X-AJl9<{V?m|JEwyZLuSNbMG^ipp|2MkAR? z8L{gg#NMx5+_yVfQnwqsjAMF21W;T0L_6q6i2duo6CAs~9+}?@r20Z9wuW3Er#0Ed zPUJ)!NfL5F(9;ADM9whckA_^n8n`BS2IfL`AO~NP_ynocns!mD3#WU&GcR7+be$+#w8Hdn30S4%|dx5III5MaL}% z7bwY>ZOU;nB)}5U5!PJ+*1S|8+<+GkbcBot*W37C$BSw9EaK}kBFsRSsD7#5Y!z4n7SA6ZRJ4Q$cL?FRGqWL?c{YF&~b>mm5NhLtOiRo95~ zeZu*>B4qu9yFU=I%T~GBMBJ2!kJNRMr58swZeA$466{zunk?1kxh&iu9!$C8Y)h64 zwueShbzWHVg-Cbd#SsMHT!tVGKt)7t)tkW((-tknYN$p4GyD)kD_!5qPG}%DKmY*4 zpES`Ftq0JRbukp}nDBl}Qiof;e$yLwB?jOP5gJyvth;P30dRFphPAA3xbmgQn`fT| zKC7*Z8-=Tl>0bwsbuegK%OH;EiH?d5ye-2Hf@jm0UJFvOW6-_4G4I~DC|r!dF3uOD z^77^1h~4+Evutm>SjoeTZSJ`L08}o2SZc(s-SIk(e~<0-zI{Gv%ErpUzdU@)GP8Ci zj8EOoczfdWUq_y&Q)0ad96(qSN`Z$EprEIg1#><`|CqLhi_;D~%+O$rOP;KVkji$iM~!Gul84Nb6 z?iH5}dj9~k{qbvex&GagAq?wL225!o%r3I)#ryvNuaoV{$G(44J+<2o9wykLUQ_rr#0q7rwt$z0L2N)3=j+;OzoWXKKeJLAV*6W_p#EYx+)R zasL3%^7A1AOPZ8%U4@d*Aj6W+x-?;K5s0VwscTT^Tb0|fjjjh&i;t!~f$GBt7)(Ih zwmyPm_0B@H9T$1~*&Hw9w_eeMnJZ8xQ3E3B`F~Lge{P@EjcYf*wGv)rf^JOF&jkCY z(IuPFv2IeIYu%BQkKN>-W%{3PSLYyQNn9FqeG*+PL%3qx%g2?7WlI_{JMa;{Y5&+0VkixvVto@t5R4(rJZO;B)K#U=2#9=9R!Y!kdsU>skrspr8 zeewF6kB%}icAK)x+;St^dij4&)6|#;sRD~Ln|-%#N6xvKc{$gok(GK^uTHX@%aie4 zWXCSL)mBx4I`~x-8lQ3pL{~~WB0x3ks+ChjH{7LG*4=0qmbLRy)0ouDrIOk;6^%H# z{v+bFHZD^oF z{8dp=qWck@4nMF&2UHzgplSu81N;1t4mu!s4?v=%8uCSu@7N-mU58WyhmRBuHGaGh z0)A+eIU-TgsDO=++EI}Yst?smIRa4ZvkRa=Yuew4m#L@0dY(nl(Eyr~GzOm^+@YpM z?4(_Z?b3`qf+5q8knWV2ab{!!5;OW?KqyK5zSJ=+k7*XH$G+j>P&iv-{ln^Am1PlD z{m3ki=zT5F6b*SW?{4CM2(Q|picpo$#6)d_^uTfIPZdQC#_hW>dw|_KMm(SF@^X-P z{`J{+^CXV>$decYLBhJMcIzH>*kN>l9<33a7Hw`%qmY$x5-RvT>kHs>YnoK1!Q>n zXcdt8a`!GD#oXP)K}5xsSYHA{AUSiv`GVtQ6urC-wCe4dN%mJeZBpyB}IW5i-h>;Kg z9ZA&k@lv%Mp%Rfbqw6XM@Cz-iV`IpW`g1f0tJyhruxuGWbin#spF|#KyJloxxNk`4 zT$B_uvZIw^%!H~UBQ97VXKeO0+s4g6#~@XUbG8P%AR2 zt01}y#4?Mf+#f;d)gmau>>yrJZf>=Stt%OFkpjeAmTAg?)x_L)yAIzeT!vO<$zGTr z+wK8}fZ(^xV%&Nr(SFX;zHOuf=y&>N*m{Z4z9n{(9QR}Bt5TGNWj3=CKL{YnkH{^# z7-tv>dSak|sWb8Fp2k(}*KN5Wjb}d|5ZuSvZ2thcWB@?Qx=67OL`V70$$5WI*Wx`qejon;Q^a>n z{p;Mc3^nSo0vt zW4F6V=ep52+01aA9wIdZ!+j%^vtwc(? zp3S<(Bml*zR&l2{m1)U#eHJRQuHpxJzs*IJMtI;q)A3PIeo)Sg+=7HK;xKO3KQwD% zvBVK3j!jCY#eYE5mL){-NLeMEF+$aAmROp15y@0QV9w#c%7|&U0HE_IAeD|M8 zR!1X5(-9jaX~kc%Vm6cuf?`JywW8gf$1>01x?~6P%BhIdv%g3;t!etjOf|WM?g&D0 zo<3Bu<}@Ifl$#3l9l!MtddGxeJMhi2H145q5W92x^*y)uHN4{`w?-;{$Vsaomr`+a5 zadJ{uAJS~cklM0IkZm}WuP$QEyE4_CL3i@=Vo35v{-?s#$&qdvm78&K+xvTCHzyNz zEa%1imp;2{N6=dhyiK;;F4=^Q$bk;|3IKQjxc%#_;oIY8!jcj7vThOuupIfV&(WLt z>r`dP&(pfmF&{{eKQ9%(>|^Mb)b3~_68D=0DV$AnP?&w zzUlS;Rq`_- z&fe>r9lK}CoVNUNAIwTLjPD0>Ie_b2&ziklpXKBiBuONfCsnxQjDy8g1Pk^k7tI8Q zAP@%uUla}lr4*ug$GEWb=(4T7w^K#{sO!(A-NIkklX9ZhD_nembH&!2lET!BAhIkL zW~VeT$=hl*c_4&_Mro)TNAW<`JZV%2MF1c&9*rlR3J48+l>rctBnbl50zi-?2?1^+ z%>Y17fdD{|9xcfL@IXL7LMa4NQA?Ly5rb6;0zi-?3y0i*=z$8l0?wlR2;fk{Mu?v@ zVAj>u3!lvs@ zE~+Ski=xPuhyjs)U#jhLar!`yMyJ7gUL~7x(o&1a1`bdw;^cmsN>V?7Xb?8tnMvhx zeat)nL23~IG-(mXgYyUgoS2J$LW;n>nzW3T|UF%e0x{b=YqQ@|4cIc6wLp6-d zBey@PmKIj-rgk*)j+BJ2=+n zYXd$NYgtxRJSe8y=qrMWV=0n^S=q^^t>RW`#}@GDfvp+cEZ4;_8a_L^4Kl zIZYNB#C9ITj?94Mre$2R5EQPs1oSP_EY#QYKi$);$-L1FxhFqA2i`4w z{x;oq5J6ux$|7u3vuYB)ZSpBGaw7VpvzSIn!4>7!yhV}woV&hsx;C~(vh zB{*%YcgB8-kS61`ZQx|Obch`@=#2edR47iG>b#g6?(RE3dtUF56BT9=fpb9}5qs#D zVGQW?lHFeLQ}Di@*W3Cl^F7X~vz1FwCo}R}F?_%ob>{mKxt?_X_K&7mpi`hMtvwc*?6 zNwik_;>UI_Pn_y+zkh5_5$|Q^`}g|GBd^9sT$3}!aTNBfT;8oRP!JEpA(lrD%J3G6 zob;Tgsn)P$gsJPKfnJ;D&&}3I}_8XdG6| zG<91WnG3a}3H%XozVN$Oa6Zfu)3+P-DG{$R#;2LR)gL@if_q*ubVlVCg?);_t#*St zOWODt9>s-L72))u0F}?{$TK+lOGVi5hA>%%BNO^INxKyQ;_T6YBREdDnB{^-jXD;+ zZuifHSN@||vBZuN@((v9NY-5cA1Ezp&IwT^(Ta1f;8;@xxa-$K!B6N?(&WkopIbxg z!&7FUg$(k~?WMq@kv3c>tL^m;4!ql1GOadv46*C=O0wDKx5I(;e zkOu#Ny0xLwv%7OM{9&Iq3<3vS1sjx1_SGK)-JTTGKx_;X$u{n*x)xaZDhZRFA>S9$ zVa4N_8OPIaCY+x;ki0rlp`-~&V8?>LC+YTk;~Qyf1w&_Omk+mw&n!!Q1k!#(y$PqU zf3}32f+3{01mmu*uX6cROg33Qy->IaLYisWJ38A1H*U00 zWV!@EZ<)qIkChJQO58hy%rT2pNdGyrcdaYft*u`4d}v(%wO?X2b&1K8SWZL3tnOd% zmwYG&Y3f2JQ?d&r?~9TB6q5HX=D0Ococ^^!;n|&^R@z;Q*o@OC)0#Ih4)v2rx}w1n zBOP(H?RKw%_)`tzFsu*AJ=-CFu2j;n0l>tbeWBZGM)KkD(~mdE8Hq(GZcr^fwVI z-1A(*$F1!E=26agGI$^&_TwI&O%GC{(UPP!25xI7V`pJo(1e1o@IRn>0HT4rnHy!L zcKWORicp+U)9BeYI}pw^u?`Qv3{P>CE|b|{o2XAS$SkAUgG$dNay=Fy2&_PC;=eak zRyakF^}Yp>p48|pB*rMONiC04mH7^wW!S8?z)#9$h7lTc>uWu9g;m!-VJ>DS7#WCwzy^(xm&7urIucX_ah^3-;4oQq!d zQfu!UEGEAf&iJ$(cC7owgh$&Xs>BIEk~{DF#+Xb!`PcVjkI?UK1EgIife4>)zd|o_ z(gqrhEdhWRi1^&?e}F3{O^4}OK^TxHg0}dREGbe@#_$%VNMK}|Eu9(e0dG81oT$ps| zjqP>3c>^&KNM9us1wSgw(-8>gTlZRPY_?)S@F?>xL7&D5G1spW3_7d&dN`YFeXt8X z2UG}cF(lb>N{KKM|04!NK+HH3VNX9m{m~s137hJtGIkOak@i)kPH+1wJzpsaWjzIka&mqOMZ%7m}!Mz zgWJL99v`I9oLZ0e)7I`Z30n__W;g4^pF^g8UcUDdR7Epr&7@JbmBubh<=^o3DK0t> zplovEZ_o$1rc5a~Y;U_4cAi-e$*fwP2((sxDKXA8Smcs(fgGEps&^|&GhRE3376vU zfSBuAd41XJ9( zdLG+@N${Gn{vTMOG#dYTh(-I#2}Ap8?c{pB{AmxoMf{)f+2U0juEv?+H~R=ASQgj) z;0RyBTT)D(X_R_?! zz5BY|a}1@0zX2i^CeuSP3(e;edeupj3OK*@a7DxYuT4taTW}G^QfeYD<>u7sfjlW_ zw@Xz>6%Mq1b!p&%E~mh3VRM^_4wDWaIpVV(G9^th0BT)oZV+zqYweRKS1#(t!EYHg zcfRw%)s}<;dOh;5CIZwPdf5bLcUP2p9hbJb-{@s+y%Pcsq)2C0Bt;_r?u-Uy4+g6= z*f0BWy|;XKHlctvV{Egg(Qf>3rN@AtJ^!7;>##6>AncJgdgg&%TPu~G1F~d>Y&YRo z)kCZL-zbI0Vj%DSb3J0ZqZ7aZI*1$~%qVTtoOD7W1mG_SVhItVOgM7r7qqIl!(gWb z5<;tQ`_Zl|73lb%AVffF2-|0UK@lcQ{KZ zk18ukm`w7u#LOr9ym{oSD(2{uD%?eLYMxb^W3g{2M}BZH+p*^go0c|C>L_<`^pF98 zHeOt#JB18-f{iyTQ>CxuP&qOl84#}3xWDNael}-5PX%3nklCaOpa0TMMjNXKI7jYU zX-GN)5nhmG0V$JS+F$o*2giQQFrWRQ3@IlE`5)_;xEnxGZ5DE^dO9zu1JWtdNA|ZT zPoK+aN<8K+jKveX785t|?4r1OZ;W%j7wbOG;YDo&w305^IEY25Hr7Wd!krK}Uxx5& z%0wuur}I}cYGRC&UsPly7Bj#GhH13cZaDiT;LlJF>YKO}q(Q-=458v<$T-4x>8J~~ z2s2mcZOxTEYUrGHWs*irTIe|xO1B(z!l~J5BlT?_A^C-u66pCilgm;`_+nhY1>3l- zzgE7+y%Qd4koBN2f%1JH?YQajbLY@Xr6jtz$2z%2RS*iu4yI67S}bd68Jv$Cn|+zM zK>hL=F^f}am_}zrlrnkIq&iw<68SSBZ{c-1 z(ifdhcN_-1O@>|<`JlE-z7j^J$|Sn0C7sm*AY| z>D9X6=V|GrN3*JfrNd3>f`-QXwbLDxk^70aICsKpa&F;j6I*;9=YqfE>pb%3M*;d- zus7TRw?sJ!i5XW@>b_)k<{rWD<-jq*jk+t$64Cn7hFtcK$< zQ7qVlIXugxsu%Yh4nvy*ANo=jPdJLH`TWQG$4(8g_~TldZa-=&ECZ$I=(+bb1G=T& z9ot2VgEAzdaPjM-%Yl{}k{2}&z^|myVL$``FH$CLY}BKl_|=R70DI?n=P>7_oGC?18R7didO3yDpo9qL zbg6Sh#9$%oqB(l>v|bKS&E78SH-B8oCxhl43Yi$zQOWHDu|(FiqTM6c5{)N%<`~bL zqyBVI;Sc0vxmkPFEr0{ODVvbb)I+kqB#CiBD;rI7s-7s{J_+h(be@-W%>tfWEXJh| zQA9hYe3xT_o?PqSW=pqILJCv;tPkdClx($)REh4~xD zkvdl|&9VYhahAY&{ZCEi-ZDNC;|Cnk?W*s=stPLJx}HVdYyLg+OyOO%8MIU)oUyY} zI1(8xz){L(SaSv)UG*49gXcrN05(**0i=TAi|Q;=s2P{09aP40E^9-dI1H{3u&}ag zIV%Qr?)N2z>3(i=>WOpT!ujriDYO;XgM7nYUA}sWawHFOuY@JMnz%>_cKIc4A&7Zs zE~)y1zjd$vX`=%oVT(pit(NVM2p7BV+}AZNO;>b#)t@9CQuYHYzIrNl&0|g<`}2Z; z;8HAIS?R4z` z!Rbeqwxy8r{{hM#OlO<0`=pzMgY$x`S5^nn^j8kJJs!9h75POs-ZrGDc-q^roE&Y0 zT|zu8pM8oA2)5dN=Vl(>0{39qy2Syfb@0I7Jm}K6d$R8A6;Kb{PMrk=hy3W zzvDK_pLGFNDMqnNeVLH#7oB+tP}ojsSUk2l(s0g zyhhIk`AET6ptOI1* zSI3VFd*)}O$Hb9lG{BkbCA2g#h-C_H0Hx@^e)y6YH+x0R^seDNc`3C}GtDBTg9W=B z8K`vc>tw;!^NtzGg@lQZHc;lxY(ool#n-TA&7%qXosLWre~#!nZrCb~-B76wqSgR5 zUPVt|u>zZ|Uc<}2s@+#mNsS4OoZ}}?V@t8<1xohIg}1u4O+;u08+(}e}@Fv z7B;&Q1)<EO?zpVk6|3JH>;cGGRT{CVOi;{C*hzcm>=wG_KPugkmasW zR}SXkyJgOi(uT^|=0-{UV^Qb)8jCS7PxRnQ58HYTC7KXThc_Lx@|1hou)UzHJBZTO z=^BbG`o^whS{{QgKd<;?0bo{0(laohx-dOly@co4Rs$JN^ze>#A7Mjz*84+VouZh+ zz8qICLOZxtpPNmD$mFM5uN!wMa!bB)3-6F-+?v0FJ-daEJedc&{NyGDzdOu>Spns$ z?4Y~e;cgdPGx!-N-AhL{EIaQ*gvAsYxd@x++!=!8!sqfuyDq&2_PZGAD7uOo}s zA6}@rR*%LL+Y;uKi_jg_$fPpHNw3?nWxas21*Wlb`B?ZtEu@7Mj?G6()=+apbEzFb zVzgzUsu3%63q?4n*b1MhmYi7U9`@LQJJ&a{=-m^}7v^M4`UUcjqonU(RvI{_e8jRwRbm zl9;@0Hd=fFQRqh1fL&Faq}_DBZV*KW>~Oz6Wj@c!*O!NcwOOvmjcQ_7d@Y~wK8W58 z7+kL{#s@&UU?zn()EpuDQ!Dk$eUbG&%B4M*G#v(fTnkN~P~T@((mjN|(6W;&7c(pm zYL>45#C80WrYY6ueUpiy~gha#Zl6J8FMgL4=^ z{YgUt6EmFAb&wcnVG9s#X{!exBY*_F_}qqKk^Ap`gYgP=uvl7puhriznO(P`e0Yww zP{AfZ-Y5^5Wt<^T_s#=*9DHKxOKMS?#eju41p`&91j!6Y*7x)fGT47ym=Tc(kmEMk zw2(du$46o!7X9Ff9wx(=rPPUEFr8Wc7w~xzN@jsJOOF#t__j#5w}M8^{>h8(4`P(r zjuvvsySr%|b`7PYw_=TFu?YIh^DPK@ny&NApNOKY)~0iW0X$uB%zjZZUL{KsiiUtQ z#z!SjS=LCIcv*=D6gQI=8{SGp&EwXbA6$s&cvM;h25nc09uqURrSal-O!yz9={uH> zh$2%s=u8nHrKD(_R2fD3_IA8tRg)TV?(h149I5if6a!mhNn9}S6{vKbbufmJ>Qlm- zBj%BnL6+5p(QtcX3#)l(g)8!msa#D99#_v zDnZ04-%tN322TguOPu==+5(e1>nK=4b=%TzGHHK(|3)Jp7_zp!+A7#+BOY4gPrTC= zQhs2$G?5sS!)(9gJ8vCXV0R<9I80u< z|GJqP{p%Yfp{J6af3w2X@y6Ec2bzTOIZVu*Z=xUTHdx9r7ta3&hoElF1*>y|)gbKiK^(`5BG2U9xM4CI1(Cw$I1rbSobH z-RpZ%Gk#BSC1t%6$5LPmO@q$lO*!{>hlfu{Y~R->7E(c;S%{Ics-CczsuZ3giVDn> zYPx5BWN*_Uxw3C{unRlguoU%px%jzjC^U zBRz}7ns~{j>UL?MtcD9w;U!mYRU!Vj>)|6JqCE2(qQj$V6Jz0w@OFj)L?+-|U$T5? zH<0HqG-XQ;VYI@WKBFS?nb6L^NUoekt^gOI9uSkXNPO;c#7mi3xeFFg#i9jJ&WD2D zDS1N|k`0NE);{1MAY42d3PdkLI7YYQ?sC2zNPEbdO3t;b*=GyBdtu*naz^4P>tZM$ z03mtkVPOR)2Ly$oIA)Z-=eJ%ZP^~)r?l)}oq~PR7P^qlTscbDu2L3(i%^sh(Yd_q| zfnyP0%0P-?5}$VmH4}`ZvJG!tLWrSCA;+=y9GExIKPBr7CC64gu8I74;L)(b??d=P z=ZF{MOD&a~+;b>F)SDXILwhF|tM4d2?XUZVD3?TU8=4S-=dpdxSMPeMJOc+Px3@VT zo29H?UKqFWl+n+Hezq!uED8!;e1fez@_vIGnxUQZpb>HYjJYBLRXp?l|0+3g8s6TPuJ z*cseNV`G}X`bEN09W5m@J^vz#DnAyqNBWgA{GTt?o`vxb=Z={c@4ku?Jcr#RfVLzw z4C@p!m%`3Rk;w+^agf8j|v&>l#a;@mqi3OTm5ieD;sZc4JUU_3{vdud-jgwuX$;*=WaIOq@Qz62VD zf3LF&uEK$o4W|~GPXHNK5%uw{A4)V(wXl`+!rN!MYq@s`w4s6)^vqwxFZF=k6bg?Z z|8!nCC!=jVAknbHdk3Z!$p%77D&Dz3kWBP;5vmdqkw>+9kfiZZ6@YeDQiL-QA1VVW z2ZVQ(P~II4eAK}z<-@lm_f*#BWeTP5Qqs?{PgQJoR3 zZSv12Sjlp^`zi&oKoZ5kw-XUd1N(%?Ce!j&sHctz-S#PxC(7C^{=IiifkfLSn1C&< z$P|YkD*5#954ccd%YCXD*kQ%h9TLPdI(5cbZZNz0FDf`&2EAf_td)|&v}3XhNF(vG zXPhDxDB^w*J%^2~>-4qtf;BVQUK6ko^qn&Dsh^YD0~&dZAG<}6LHrRS2!uV9GhqwJ zSFI|3M4#Fylu1z~bfF#-b(a04>Tgz15eRl|P-HKf#M! z*7^m~M0iw6OC?c)_8>k^TGd#AHdk^@`m`B?QNdGZSW`IS2DcFBnGkGJVvgMGe}LV) z^H_y(W-O-*N7GRLW{gsRGT*4xr_CWK3D+p2LzyK>o;Hrif=zkZ-9)#QbLK9Gr(~jd z@r2F4x-Q?OfaTXd>@jKtMjE*xp5 zCA60iugnF#9gBIx{7sV^6;eFX*m!QGs+IN)Y62U=*6@W_1Q#HEoUWo=OG@FlN5>U_^{I4mjCz=M){H)_m@&BNO_ zv!v^PDpSI(@4J0=hZiQRliC_Ru4{J#^U6gARrXupj-(EXjwM@qMGrgOJXbqOdx)N? z-DFyc-xYWc`R8N00q-!5m|eK2$;qw`iofxR2_Dg&R7JrI!Pt1A{en7ted6l<&lZD$ zSn*#<$1Y5mP#r`gbQnf!4E+fD|K6HMZ)LXsQxZ3uScyK<#BzoMuJ$7%VNszUro9)m zk^fu4xb5(fW)KjL-zeubXauw#z9Wr|)8`IGB0BpaBOuBvRYaO?B;X@T-SAdPXh6hh zn-*{*Iu7l%8E&oCrMSEGuNa#!Ox$}y_zKaP@!IT$OHbm;7@AtW~vS!dyLMqjD@9yiyh1^B^ z8pEYM?(e?|ShFU1M9JmZXorXYB){#;^3jagdFp~%8|!zJt|Vt}&U!>Bbw28MWIWRb z($4_ysR*knU#{wn-|kJmzN`E zgc>zsYUFbB;vt%2Nj&?J=BGBPENDkzKnbRDr z7~u4+{A*(i;*%`DTF(SzweB|e+)Wbm+`GV^e20r#glL63%>zFV&GCS&0HDG%xmyUP2O=FazQe(+@i<%fV?irgxz)O#2MLo| zU%A!Mb?N~sR@+7U#asoy8xH>@-@>9jfQJA_Ik!8`4cG(ZU5xKN3<{GN-bIgZCIUXr2rc(7(MitO=ZRrvAw~Zv``ky7$Enn0@ssx#ISE ztj09RM32t2^Q`u?E+cHVhUU?gJ3sENw3(;ny$Hk!S&UtoVVob7BGFrOtfD2 zuAiPBydF-IR1@S^`dxw?>~48x-D=fJr?M5FM5}3?qG>~os@|38R7Jgzo9%>^9*eL~ zu#k)K$Ex%qdm!Z$A+q|@a}47M=rY9~9C0XSrD=b0U`poHsNogy@ZO2frJtC2x6q%J z(Csj$UZD2=T+Fdjr}TuIU5W$ZqN*M0BBmi5=5v%5BcbceUdgSiLAIb>B*KLM2gmCg zB2Z(17DdhlseMrn2$#=^{2f6>6d!;yQ)Q`9X^XSPP|sxLTx*N(Zn38%-_j{mChh`| z-6_^eSN`p4ZezsI$XMVIlzIHm8IGQ=$zB_rGacZvte-L_dM0tNBQ=SMiPWI#ZY*CRP=`lfkxU9dr^=M8KGi&|7>Vj9VnXOX1y*ns_ zs@?`1cI?T2FhwD!A}1(ue)WFjDwIkb*1~1+>_t-jj%Z7Z8;j=CaSRM_J-R;{+`CX7 zUQZS=VwU)QAxwrEa%~i3rB|FZ#=IDK?D2F#z1b$2+PvEPC$h`f2r*;8*5kAF`bhU9ee(zvsP25G$GTtBOoVH}s%jYweu+ z5QBHCg@Ni8y5B)kE=rPm%~2-tYNCVuo61Z1@{eDN)K=qnwks)F5sYj1_!NZ1=vgBPqZV@N5pFaX~UVvT*aJ0Q`^BjL15hJ7E)r`$c`B;2*y} z*?rw6Fage~7y8lL^KF+C$z4^2hVBt|&3w?d-Rk1li4~jwUTSz-M7RZJ3c~=-eb!T#mju(FdlcGiA78~cn{3~&)f-#7^J}I*Plw>lT_gb zem^}8YBo$2a77l>g`sC!86D1UKYMFbYWOJrZlS4vtf%P!>xrbKrcyuuUf@Ff(K2<8 z%6lH!=xV%USw7%M7BBwbTfXY?KfnyqgA?4!{C{_7f{BkT!A5dx`jyz+adOBX*+=8ziMG=dRcy~dqMy2LuN}cV!zx znK}JX_Fp;vJ`Pa@&jiF`oA_5Z$G&ePg&!j-z2gVl46@0f@#A!;TUJNy78D|nqMBz- z7$igzgm=I4ZT_A;^YL}01S#U~Z5SjVK+AuXG9X;?DyG?= z!pPXnY2+_JAZECix_%7Hh{nPh0V>}aXWJN+cpyHqd^)vbb;{8bKp^eWwu13h3=wCw68)~3#n!MI{V$a zM!Wl#FGz%wGrs!%i?L`NTW!-h_2rJv7GbmXMlzuo?rM1S`#HrIQ-sbFcMG6UF;=D_Lh9qP&=$@(a%aW z!N9z*)9?>+htdR&Tv{BP_|PG;!-f5t$nqySYP8t3_!avvW%}xjIcAvp%dUU&6n9!g zKN=z~w4H|5BGv8+l?#a@0J;*(bqxoDN8dMTf)%9KO5^Ty3Rtt43S^Z{Y)yLopnuoY zKu>i|=gthxlN#qPn9|_qA3SH*s4CPO`Fi4gB}YlVXtQ8OkXb~!e zbs~C#$ZA9@T;`8A>^OS(8WxT**gP|XrzGVl+pu&7Ve)-Ww;LqS7h@+^Lm|^|5-OS< zcm}@DLL1Q++_!XD$2R=#H>N4$p4{8fZ$@{|MTVF?D<0OI?b5rl8hP?r-8SE=fDlz;6<~Vt;wRCQCw*} zt*Z6DkdsI)Jvwy-VW-pt(dZn4CZ-prU3T1$Cd=q#+WFu-{D9(aRlV4nHu{mZ$?IuhThlgXh*#Xm&QL9P%h-FelFdaQuA!;bZKok-P)Sm*o;h~9wU9Y zvg^nFU6udVt?LiR?!Gj6a9LXo!^ObQ@NDOZw8KF_%hB!?^qWY$`8tD%Lvc-_udtBj z1$U1o`;Oti+S$iW583q?@3~Cs>fCk*-8|@_*@R6KJ_fHwiB>@c`{<{i@0I!MDo9`a ze#M6A!NNuffsF77KJvv3z#9ixo;ndVvs9dnUFr@iig0FtJ>wkbYtw9i*qlPO5F)Yy94d35e3)|HoI`Rki+RctY zv;<+FUPEnsmSoea`H5(VaHx9KY6d(INuE+T=UtG-ciC`NKQ+Oqs@bu*cCNIyk1P z5I}`lww%t$?ba)-s2_B>!fNK8kruzF>Y<*>C#{6 ztIPQktD9Q7z`LYIX%TRG_tJour{f0?_f3z#EePcvi?l}TXOsT}SXrEvI(+u$tYbIs zy+;k+wRu=$h-&SFi=*+Tn#WJIM_p5-r%tBp{=P03p^d=au)2B z<4Dp5dw;g?N-8%!qWfW?1x&CCeA=(DaDGv8`aXdGA|_3qiG0qUxfN_H*rnDM_km=g zL-tGbo)q3g<(IE_-Bctp&5k_|(fG;9g)Y`42**8+16VyJkP87y^?|@93X&#9V?2dDPYG1 zQ_UuBP(L(F8;h|5UQYNsXUax2)CNYvQ-!7pPA>2klWx^RdXOsQKc_)Bk> z^AoiuQfhjx38VBsKi#oh=%F#UPYd1Vg`ZH7;VGr#Fy|(Ba__m*CuQ(qME|c}@64++ zf_hzK1Ro+MlpTB)n!0YKZ)P8ELwF}BimO~`{gys8HDrw zzh0dNwsKSE@q)tKP$M%AT=b&Ep;12jqFX z6IJp8J?z5n8Q)VowjZd%N_Ek|9q^;Q5&z9I?tBYF`Y&S_;|)!oN{*22p{k+0{1Kg4 zE33DU(wE7~s~392)svtXT@CEdP=v~=LR#)nTJE^QJ#1EK4rHpoG_21Q> z5rY603@PyoI>gkiz)c`@vWp3aLrYkRL0^l(AghjlI~9iSE55{P|C9RzrXri+{cQ^l z_tU^d90yAz_afZ9v6eS7OY5BNj;gsGEd*5eCl^dxBCM%kDC5g9XgW^FJltywq7i;S zrKc`Hr%QVzMkiwf7vw9Umtl%jkR#*Wg=0dM(%}%L;iN(dKYsK&kUZ_0WN{{StX=s! z@U`^UY!#UYKlWc@WW5~xO5+B8*_#mty&1wBpGaneT|#0ffiR)7mXTobQe={ChyM8S z&V6raCA`91-f7RrLLQIr`~?ivw*5+JoNhfZJ7>^=*XBG9mM{HaU@4IOq>J3h-9O7W z?RWX^_|*iJn)2cBHAg0P8e8p*jfurXq|e_EQTg9~bd_ z)ksFEK|d5T0I`Lv%D2(nDXZre|8>mNoK%!-woU42!){Ey$zeBhJ!m8$0TcQ@uC=b? z_Q|rGCcmC-qx&ygsv~7r01uDJ$->YP0LS4 z31RPx~~zwOIhiYvE`Pq}mR3%*Fg^c1SmR*h0GHUVN!Y^@5e|xg@+kCmKJo$oZE# zW2EfwY=(-@T2EKoNGf;qO!XUTIRk}1S+4AxP4sYmZ+}*15E)%XqS-fyY?(2%L-nO~ zX#P4p@%-gifh6H|@iD5ezo#rg%HGpr~=c{XuC2Y#X>7i7%?MfgPWU%g@XEk+TiTlD4 zugOS|FB6=#ZlW*5P9Ln%cqWLo7!A4py>r-M>j03a5phd;tE+dob;M(OrVL!K#ln8@ zhX|7Epl?W?H_^A$Un?&m`LFyWqRe(Js45?*UZjK^3xFSri92x%((jZ`k zOT1dK(?V~*GXt&PrV;#*P}q->$Mk*{FD6xxU8lbVGO%aLr15EYR!|SAn}D<(OE+cS zrx*yvOwh3%UG*J{NJ?ohNKyLB%tjKd2Hcudh)L$iE{n@RUTdlzehUs(=c@8)$#uFfWNhKu{W(~otOvK z)XKH06~oYy8@uQ4;#KoO1N?#R5)3l-2C*(|>afS@C2LLFZ}ou-OGk){L5$@3zMcA9 z_BbOQ>s-eF^mOv+VGE0n?Eivvpq%p6Y_;HFt-Xr1{!sTjuHm_g!ETp%$39paO4GNM zg-bdvd)2pl4w(k~plafp6VkS})9RAw;ZT1nV#DXkH&>x6Y!8L%boX!FhAnZqfr=1m z9k*xQ{O&e-LB{r-EN8pr)oa)vdY$=5CupU!mtUZ~BOLc{OcB8yWa4vRLX;=o3gA{G zTCi@Nl-i@frYMWZnMhF0we|WP=S=N}70SC3L|8 z{;K0U5x1F2u;62+)ruYLR5jsh-|ayFyi3@=PJYv+%;F#+vc@2(n)Y%gry^|rkS?vt z_$$mtw#TKd&KOFLR%nzMq(=gE(S-5~Q0nd`e6j@>InJb8w68VxC-~Qj+>A>O=t`j3 zJJ@|kYi>}g7{`g)DUHvvnD-{!n8)T@0A{zdBN1W_Al8SY^m~KJ;iX7`{R;H(P%jyy zheG(YVAK>V1Oq#0(J_VB;1Q+&tj?zJpP@JKRsbDTbTTbpU0bN40$c_rzTQ1@f%(KkEoAjTQ>Hvze8D@RZw z(pG#jZeL=>%+_b9>I@>wi+XU?3Q38$a;N1r-2cQV6@ypp4vS7}j|(5tRVVNosMxyJ z*3F;&sFYO9%=XpAUTeHCT2AI3-+BR0^gZ1U>nJ*i5rYw)0^m@RXUyvH{k_9pmEOxH znr%5SKV$N@pZ=Os2N!hEbxKZ1lsZqov*Cf9(f@dgxRKvUeQ@L^Air{0yC zccg!QC5>n8|!d?7YBV`rb=UzG4! zn;5j%51Ja;9WADoj{YsAb=tvFdO|A1he3LYDAuVr0cs0sbyf=gb~l)lQAEGc#E+0l z9ZTQ8&nQ(ilLV+y8Xg&KL4>5{{QO~QI>EGd@=|SPNjZ4XZD}b{XG(Qd7+p1FRwg`k z;5gPcvogux#)q`vEEQ<@z{j=xk*T;@)5mjJ&z z#-_vS&0iFTt8YDj7dJGuns2Y34*a0?TcgGQJX@ZB9qUtVq7)l92lyf=V1c6e$jS`x zbos@;#cVZgSCqYmbniK%Eu`rsS9!^ONXf7=rRPS3^6>6~6^J}ntF9jhfGy~AStJan6$T9kn!WU2cm6k z$t#JKaSr>mOwlV?*v2luqQ!nP&7B`D4=;>PHc(4e&U!sgVMramerJ?`{w|F5R?`Fz zzFSo&4-BYAQ+V*^H&J|37yB}!MT3b;nQgiIXFjnJv6M|W5Cbj*dQ8@l*t3`rb7|7z zZiKUGG8>|h5Ct)~kvv(H+AF;_;QhrBt7#$RmhlOzAiq`7aZIt?BF6g$#q***LqV5~ z38e1350G8&t5tKTu~=a4(k&*^y{$C;QpmJ?<1=F%U$uMI(8TcGLl5JvXp>2$dJs7W zm2%;O;$bhZ2u%q9DGil)vfLDbks!LYyoc+(gSmqy;2SP>pN!!934D`+lno}{!a~2L2)K@ry?d<2 z<7!%ESg`x(p=Qd;;m#pVPxfF}R|+2uXWzEU+Q_r+F=H28(;Wj!z#CmUgmo}w>4mCq z=31?K*ovt&&*bg7Dr4giPQSx8`k!l(ISW6qLOF@5MIHZ4#L3`HKcSEhew8A0NxnLx zl*?>=-0pA~lo9}yF(BY+Hn{wpbpOZ_+&92z#CHzUm8#z1cMXgcj+4Jco{imSI#W8= zpdB{#_&i_pdcy24O4Sor(i*Q+zEN-K@;3v5cyy-h;QP|blyntzP2{oWQo7ZQfJQ;B`hyJl?jeYizXfFgabym3LDuG(u@J2QAM&7d)xQjAJ`{y z_OI`@4S&O*m=;4U?b{$Eh5tEK*cTYHO0q{aA9-~iBoFc}$e0+#y+!hyU)?s1pNMx;__SpcBp zM5Dov4fBQYNf1LvpZR~+X+{ivbq@h$7234$GB$_*TvEtDrcX+U^I$?u*eGjkQ3^s8 zA|6sKDV0BacoEzW>mk9BIM*Pc5u*d&bPHq_XQOr%O4X5mv{PN7u(v<8!2Loa{7NJH zV=egg+(rhrM2pa{A|E51M~_h8P>rUQUTB*4?-Mo-zWTQGTw$EucSn zRV($V7XHY%_@c7a{J3+Ne-1{rAzOmEO=ocodS3IGUOPD0cBT<@yaI5*t?CH#|Mev9 z@8U`8A!c7Mv5(u=V`)MU)#NNw@o@{(-J_tfs=^%$Sd)KiO#b{dRkzfvGEg%e~I$6EtH90TM4g}qW!-5akP zrktpIXSI6~kY`vss^p0SW| z)n0eQ^wt5{DXM~EsJ{X+kk9&+yaQ=)YHmMBCOawxhzPZbk=EU;iXWyb^`RdXmiG?z zHG{tAH;!9S7QNSNnOr-YXw{I7P?`J?xUUkRS`2JR>w%S%wl3!(|Yj9|yLGhh_=$XqIGVLJdsBJJ0|Ah!fkd-(O0Tw7)+;< zjV8lNLz}+C5thn!m2a^a>|1$8qeF@<0^T>GXvzzNL-BB4v6z$GRezzEOuVp5U%5+T z-ka@y`UX@HCVhMN(@?j1a9c9T1eUt?rVzwg_hxHvFT{g5LDp3mH#a=mi>KYSdRwL6 zwiN4k2d4ZditWHL>+<)T8=dNHl~7Us$uCLyXE`1^=#;Z-QiCr&8kBXXlZN}+6EegN zv*@A_`CsOzwPZ1RE1WylY)<lM6j6DuAdu?JG?IH^lqkIaUi z=W62a4b)Z2i5ljrrFK1kTae#-()0zs_*I|mYMaUx9)l1$CT&3 zaQI~juij!$Ue5L5t;vPm@ryox_x7V7H(ERSOb>TmKPhye4B2l4O|WQuel;O6?$<8# zX;?DVIWm8xVV`0t{H`M=(BA2x*A<0r*~ME00$!Qwx$d5qKAhAfd~T5sxqOxd!(F3O zORv8+;ke_sk|ikWe`UmD`jSf9ovQ-R6E*ou*zM77Vw`90Uo3t~+0DJo{r-?%fpc!e zK}mXuCnBOV++#h+ae~q1`1ju;&(Xt0Y++_qupU#0Al zA?yD(_1ypU_5U7^(zDY=0Cl2b!YDbkp@bD1u_9WN2ZX%2G6gDE6HmE52+e5R9)ZI2 zrWC1Rh6jPhP8K3M^yx*&ZZth^@`6+|cFqoFcEOCP@I$6pBh>`&pQjQFG2#Uh;nBcd<=i`;AYeGCQK^Fr& z z1t1>3c;{l@bG9=RvA1eyI73%Yc?iD`t-bziR@D8~hb{eT_K0NM&a6*Z|BJ^xMJ0mn zjDkUh#EPUQ%`5J|Hfa{`_*-%{0BhL6(xw4B^SkQxP8Dv#%(^j)ccmBNh%urkotk!; z)2~$Cm1AH^d<&Ml3Qt{CB;sE**v>)uO!!nu{;m?%6tq>5e@P1u`Fcf7MH{@eF^>~s z&6t`H0W*i^V7KBM#=y(UJzy3Z4V(w@l4RT3(2fntL7~2At=@2oh_Nsmh=d;7d zxe>6V_D>mf(Rw%sWrgF@zB*Zo`PCTGi88NZbHSM>GGn2P-CbU|edOBLkgoftiW*D1_=aXjd z9UTUh5X)5upRG5P8HXs{uE!hVe`Y8$_(|Dh$KBX!*?i~=Y*ovt>;;Jg*aB{5zhieBwerW3(a zcJ-)Rze|#*@z%6LZ8MjRq;E!!C$ye3yRP^*^~a|(Tz9Vei@sw5NjZ4F$P;Kp84HTI zxf==FJEoiVwlF}B98C?S^|cE!?Bw-1_cCXw=MeYJzm)qh!H#|P5jhLfSHTG&d_9V- z@H>oq;8%*XwS0L}qMUltTj8{Q{qTUB8LVT_WYfAB+5=Ig*I_?8BObI#={)Xb9b+5p zLJa(RKf3VM7v#2V-@;|}d`P{d)%+X+mBaB$%`Lum@#x;;5?Vz1@o_yn+Sp$0=$y+o zqDkosdzerS`-6>Azxux5kbo=y_+`>by}>$!Y=y7Y_5DhVVDmnyy>FdoaBtzG{7V2(ASx% zEHa^+YyHuB(&!ST;d16e|kaG5Nj&+uQG*`a!*St=K^fxK4AsW{#AssdxDmjVqLx3#|K(? zU7N#NFmA{WvHWiMee3<5!e`l`nfY1wWkQ;pH#LD<^M5<cl#d)|cSY3;SbgQ; zcxG*fbz7<@e2<+3CMu<`j5t}m2r)Jnx#4TmYIpn&O+6NheeMw#B@tV?ejQhT|B7$x zy)JtnNLxjYw3kZJ+LzE!zig@Z#*vCnfA$T`qa_a-;O&$Dc*;)P5-xWvHVFDw4Y(I2sxEqh~u@#5QIo zu~xZ$Q7n6%a_x5$K_!N$s?`}L)`cuKtgzVI9OWLZ7#g@Bgar^9Pnwjv#^uCH<*iXx z(Y)WtrVrk%Ije~yM!y6ZiL!IY)1;MJkqntPy*Z=|kvQt3NdmBwCP1$cI{rhrP4O|e zWOT-pEC~To)D%_RBN*#IF38az)%9s%onPtTX7bUugDNWfv7pqT2A^%kb{Ia)XY?hqC0i@Xc1bsO=Bne4LA}SovdA7d9UA~mBA|8(t48h74Y&JXEUlTE^FJvbV1YqU&v)bW_Zgf}W zN+CFs5$q>H2|8>v7blPAyQw`OMN-XgT*r^+v-(@G+e#Ld8=sVxOJ*yY8rS)|7f)^4 zt-FyuJEzC)^XLo9h!y5|%}kYk9pSkVy$3i@g5-^c{x*#B#kIZ#EIP6!^`nDMf7 z^3)*x&ySEN@k)rQ(jI>+8qUG6O2gWRy#8=|ky}{A9lMse`ei{CKS$RJaAbbM2Khb| zY+6&gJ;?fW+Yl5=W$UYZDTJ|bknm?GzjhkN`M12%$ilR_-aH`BBR#yStG2D~nfDHt zMsCI3nZKne*TqLrRCf1%I>z{MzoBvOPMc3Y)8qfv40s#I@hU0NM=9MO0h(3{52l{W zXQ|*9#-Wn=h8_+L?J6p0sGOEtTcnhQFGc{Q5J4xxS_tb_-=_vm*eTBD<_88-%Dpu+ zvBKl+kND?|rOvtd*QQTr^L;{Hl2epiw5Ic_Q(L12XJ!taF4+s`6KJ43IUM!0iu7;F z`E)+qW@p-PMzi`>a|FC8U)`ZG@`mjYOlmo?B3cERGD@`56yvq!AmZ=g$D|X|*1^Ul zOER&QP;ZX$2NyDdV%kJIH$H<)O1UJJ+ut94f3b3(x%X))(Bq@((pSHn*;*7!MVQzf z&Er)1qvTDKo&2>*uf9U;*D(j!$Gr$Aiw6~#1_Lu(o;*o%o5SrgQ=Gvso&XsBdfxyF`dNdE&b)wS1bg4wH&sehF2_>|V zWsXw6Z{60X8YU6&#^U(XQr=Qw8|pNxdARPgs)ACjhYGP&V$1Q-8n2}iEYK(nS2U2}* zrkNr#C_e08$69pgwO&rQSKdBGr_-4)5krifOEFK0W1Sfx;`x+#SW092xX;8d06Mp@ zmsIpy>!sFCj_#3lP*B5MdIzY$y?In_}vyraMP@3?JoL@15f zYgq30<;6#?K8qdTn~5F)RbyCoB#$mjnbn zPu>?vRfMyIO~<%-e#pK973O6Yax&paUUxq?;II;n`-GI6Inw2P{ub$Zl3RJVg{Ks- zO5)izjR}O1+P&ZD2j0L9AT?Umq?A_QdQXrn`U?Ok_;vX7C-%2K6%1MOYcnvbK+s0Jj#88Y`|c5HPO?(!@UMxS!x zTrVH%WiOdUierpn52+EWbR#W?*2{J|{RmM~t$!fqG>1#c(OM9yxRq!lV;28>gHwDo zJTp+w>exk(#M$@^?WEbd>ebF&27vf$kWn#0e^q%X0) zn`|QYvMvNiKY?$2M!b@v9#ZbbxfR+zpCmShc{@{~UJ{RQwrgAko-6Toi9WnNy3oBt zlVmI9Qn;!+5F9;3z^#ScZ`)ry8W;gwnATQb<$AGv=Prm5PIh;z>ZHvA^zMWa5F4%+ zG*--iP>;6^csjhfe02N^Z?MGV-mli|ZV#Vd_mBWM%*o1b_so_&WW7oTNjN9aVa* z8P{Z(0z;c%->L6Se8KVlTodDL&bJt0D;shUw|un-Bau=JNcjca~P2P_;g)WA*I}^eR7Cvj9zt_DjtJ()l-~GC5Ct zuhoYP=gs2lIZJ(yYsC`=;yh5juQ+4W_?>bislxI)8|XZdN&?hPhZ;N}18-Go_H& z^->6v187T853KX^KQYt42Qct|I0$fqlDt^!aLSH(G&7lw_%?y3{tZtO=h8E_(dvZ0 zUI%8Nwg@W$ff8^`yZ z3WRmbkSi<8iF#?UWmS06BN`lwOhGoop178Uh(OwmO2f^82l-GskFZ?8y-QQnop)H~c zkXlJw^6>TXo8ESR&<_P(g%VFb)$_VgN|fREN6)v7mujofiU3|2&3`v?lu+xtlik>$=$Y&KWKS(|*mak1wgG)PhIiV7$ia0+EZY_b^ z`EiL(C2s^uqV)^}!A3>K6grRoeb2GHTA)?ykMRys>oH!v(wY!);p}C;eg*oFs=JQ7 ze&YB&A*;*9;`{?M7??p*AqYK1&cv z?zddb_0?9*-{RifmHBWVtd$Y7mMN0D`pN04fA+kn-{sRAP zw0JcCBUsM;eld6bIn6MHeyWD355VlK;1wI29hfehY-7e?8-+*B6uptPpvENa$n=@A zK&2LswUny7TIYZ@2RgifJj<8C~vRby{BN+#)nZaMSj8I1FG z8jtO>Jv-6L``-KwwL*)b+EzzX#b5aQ{m~%ZN_3XgT+|@6UoQwVE@+r^=hh}d_?FKQ z=C{+Ijw4%d=N?IP?CK3IcEi;W#+%4)$bLqMUHh2V^1#~}H;t*J;EMG7*q$Mj(C;P! zvQ5vtJ43#t5WE|#&%{ZdEavy?TBUo+JZ1SAc&D@eJn$#qtk)g5(DJ)?Us&ulJ03k_ zZ5NZDY`EsM5tL`+VX*arC~`RmO_!G0M1oJ)67wNXm^e;g@2qyuF5mkod zBRf002XCx$3+fE(vuNq91(oPO4BfuNPfohiS#Dha*xupt{&Dv&Dz|}R|5AsH2Ga+8 zq)pVTi0`V#rR--{i=An!?{f;8LNfY1{Oo?Y76};wNiv<9?*xtS3T{33-)R)lJ|rYl zpaxL%YBE&AjD}(#@rPE(S2FjEFzk2r{1NZO2uuc!g9{jYxLPa1)HWdY|(TErg4I8WQ zAiWPH@U0QhX#k3Crj+U&t*4*JQ+a4p`E#q(aFW~+S}xb)2GeWZCQ)0g;)9FSgat2Y zZze$wff-CyJ^ z@e>uIxS>W&K#JH~4Yu1)?$~BrPAu`=^D$md*5FofRS=O|4zfi%Jxx+B%uYx5WWcxz zvEIg_^}-RqefVctH8D?_kV+2ie5z|M!uu>UlAW4AhPon{GZ^x2mG=k~rm0==|2Ldi zBX*2$#Hnremid=^zXDOzyB!y%n;MU1?jG&?z3^UJNO@^j4v7aLC6mADaCaM(*|S*% z>kDD03u=_~k7P!XI=H6lX3vD*A{+Nmy|}be`#6p`{B-iZ;SUW^bzkFxQ){3%p@n1^6s~rx**Rn|GI@Lr$fvZN!!v`Nd~Q z(|1J+%WNy@4E;^buC}-E+T(dWlan;B4>%|M;vO=%{01oLF{lD}WL!@P?V{mAKum*_)S7SG$(!)+Ob@jcbp&BVB7HlDe%hQ*J&pz(cbAXjeCm znjuMH&z(v#F{TDFUX$5Q%zW&vu;R(JRYC#Wqy=pSfgKCPfR@O@W_(Cdl>u7Cbt2$T zy~l|ScoY!)R%w}ZrlWhPr+ekGbM_JZso<3|W9!ET`_`zddm!6;h8^!a>4sZa3LKk& z?c&FhYE?$7lB5VH`@$!fD*8M?7RPPUH1nTBJ9taEzL)fiR1tmsWV=STfw%fqm2hcK zvS1*U&1`0kCnPf>@$f7o$ZO7TrH{Um8%9z{e<28Xe)s9|{XQ?01)ITasVOU+->GEu z0mxR3R8WXw<~=}X+;$W!_n#%M%#j+YUy98bX@Orq%)bVPBk6oPr+0!(ZLd5^>U>1y8#uA!(d*{V?grQBD|EvT_T=}f6$m5s0q{>Rudek< z+-=v83t{RKW5r-Yn}(cPCmu?ER{lG!0M~YLISoJA9{kcOZa5gWJ7jx@s^;(pbX2qx zAtYkAqq-dK8wmMFIzY;&Cf6(2WHgp#cO!aJ(=FN z%6QWKP=Aq8dW1OM=zQ&R6)e}qveVz3KeefF>G1nX5`q8K79IljUBc;O0F#d1Sr~t+uinCeUP>oR9zJDtp?Iu?6Ryfre z7)adWLQw>UiccwTe=wC0q65`MV%Yp_M1iZ(q319o&=g2Zk$P(onL+T;61hiRi*k~k zBS3ixa{<1=Tk#yB0$>SdDQ6}?=o35LPg-EQ;WIq<ALjxq6(fhB-gYLZiiFs5xR$_D63efX+1OR zm;TH~nx#VZH$#5&GgH?v6+Q*QGs>GmHOJ0wwLay&F;VS7SkG}xSv>=*Q$(te>e3*S;~p~tz0Yra{o(P_j?W3 z7pQnSdqu9+7L3)Hx(St5B@8<7oEjLR8XExljpoaOGtfnw`{?{4=X>nf;Elm)N|0^u z^<-jJTYYGqzGAY-5#fVqyN~{@_(B-M=>5$cx38H6F`_$A=dLKc%oVk3LnH#v&9V$3 zJ#-J0YOCh?rzcl#FOz(Pm9gZ}d`|*%pcL9XUe@nQj6;o=dPi^WWmYNTE4UK#B1gaO z2N`j)DKjVC-&^eccDFsAT#K1jYiAI))0S%?Q^t~n<kx?pQS1093A$F%}Ggk%-Eg zJsoLVHf!AL)&P=_83CcB%?^+~bSy@N++ll=8V;y4d?EmSQ%+F?2vfun+C`p)iEeNe zd%UQQX~bN5SS@SAoyB%2*bShDD6vauxGNu4q?+xKkyjv-#en1&ZPl-sc<>}aqoyS~ zi-JnsZTBVORy8@YQvKb|o2Rpc0gz~~ z)J4%1N#(Lf&b_%}#Z_UkH2IpJHhIp$OWTyoT}Bj#Q`eI6FP2(m zEXDqqDILXQ^qI8tc-e}NF#b+i)HNqI5oPaqhAORn19ph$&G3S}DIJLCLLhWcUxG_N3%vSmL7T;*{a6cMz-gU-(p;OH`{l4Y$?|4@PFF>+ zAA?bMWOJ7LAX)E)-JQp_riL#9 z1|17?JvP%Y)wT?eqtz)^M!B5CH*?#!dcRhY&FE zq*7`g8o>Wd@c(P^z|oI~8A|Zrc|j#LvYwKS2*d9GyWoP5J#G}gj%iBC%c3k^0G+nt z&uavwQI;tF%TPGpVl(>w6i^d^bCOsmWY#i_;);i`8)L}sDbL3^g3=ki;NNkW_Ia8j zl9!MtqI0hv7tT&sctLbcZ9(n_PV3;2tV5X~6@Lg{FF%B;2r4$6K3PWBHA9%%iG-xh zfPlQRH{S$u10G@U>BA@l~{q2If{VWd^BD<~+hJ^rRLbNVD~Cr+;(q;J&sq{p6x&qwKGNgMY->ib4~* zqO83?U6WqUK>QW7`BuYsa;}w^c<*6E{aNT+vGteZ*q0Pn+3D%5{OwmScQsxO7zm5- zzj3k3W1+REExFZZ|NQou1=Yh?vzIynf8FMvUpT!!+at)SJDM%n{AvB=aD;TFs!iVM z-ZkrF2Hs>s!pB7&y{c}LGCQP(4>$T|YGD?L#RM|%kxY|tg7@rh8KlcO6AXf^&kI}a z81{E`l+kg|yndQvb1wyLII^dL`iP0fFGtzPyzPdm3!5;&rvZ` z?CygWmke+OchoAl=|;^fga|fRUXzWw7ABHvBJ4$e#SjJ;$hZ_w^#Pn&McTYpyRCmU zWR-(6mTozEsRH_0JVy?|LTndpHtB3(PF5t<5{?`_iZi)kajeig(fe*$A^W6YjNlzX)^f4x8rHd1Gx|dq@Ti)UrBQahQ zNLJlbA<|(Bc{wI!R_w``cdVO&R+714j(9RM3csM1@M^vP{eh|C{)n+|-y34Fvf=H1 zJi}zN^newyz^e0Bt5d)3s}rIWN{iafD!mRQ^aIDC=5NQLk_XhQFahvPWG0%khPV#9 zri*C1%ga_xUA(h~xde-ONlal9S3tryPHU2<1fl(_BsZR$O7cdWwmc5qB0)Z~q?x3q zj81j!WRnZLwUYV8Stf0lDgF4z9B+?j$QFxpJqL#!FOy5dgV~kh#_l^|(q1l#3Ys4w zf8eGmJWsRF21{}Y{{X^^7MzN+%|1TlamcvZ6Lj?0-R9S4#U5dvp^k(+rO3v#HnEf} zFGipr`9ABZ!`q=(QI@@4q16@be9Y2~$zZojPgiS|znR1J;bQTALl0hcYB4-{EJ~m3kuic zIE%yKSzDC9ND$VOi1e)c|4R=_KgURE=^W`m4h((3m4-|J_V57tECZ>Zilrc*>^BLq zv0wVQ&RG=E>?>Bu6hz-st3Oj*i=BD|GM*qp{j41RX61LO)F8x{sUM~I3@i1AkaEe9 z;Cf2PvMV;^vR|uKq#aPB{<@Bnx`nc${RO!!U^jb4 z9Dd=$nfTYTASu|-`x6*RyV+b@Q=2Dt)GxfPg#|y z^!gh+EZk=32LZAnI;mK8+GWR zL!*t1!?nvPp%O`m*v55{J1XsZ*Ga|XEY<^i!I#`ar<9oOVr%38h%r)vGNi!t8Wklh zlEgUQDN@qR>`Lk^A@gF%!+e+SiX3Qiq^qI#89@Xp%-aevUcB@3G0XZBQ>6FQ5FbZ6 zaRY;`7kj!5K(H~fm`w^Gi&@4nAC4|L)8J*WEt{05!;IS>BD!0;8KVt=gtrkJt7-kL9w6zHYwTi56?);%+0ae>2_xBjF{^@>O)E&2BCXW3)bY8^MbzxvG&oK4)%>ht?n6!Nt@Y<#=**^kSI2Glw=twp)&p?b=|}yLG`lbz%{WMH2W2}#axE8MG9BChH4qFy-YAt ziNjVMF#0v5SL$P@ms6g1vjsJuQk*KA@cSROqcee#hS*^SzvbvJVwTW9KlEzuSnUj0 z=+E}aTbiT(uDAS%{b5Nf1dW_=0#jg>Mrek~FY&QbT}n%4Z}Z>X^4|k0{%?u;ch$f! z_P;A9KfmW82wV>?rPMT{G59&1xG{A#JEeFr;Hj3e&G1aTQl%nFtW+;XWr`I`=DqUq zHKf-D(UPdEyNgs443Xip6ud61N5_1fX@rX*&0O4bQL$RlO5ko8)F4Je>%RFN*&FYO60a?N%)w!hYZT6Yvk< zPXdz`bD>>CxYjkSkJiq_0VS+@ZHRC<+fZUAopgbT+B^OSKx}90xg}e6(L*sRX#WS$ zdMb_9wNg z@42pR1#aIf%7-Gps5n}wrgke|`Py&W5O3@h<<=7K3yI@Hd-T^jO}Ph-YQ;2c_Go}|Pa->v0yAJN0IL|}lf{YJVOQL@;AmTO9s2wf07`ia=R+vS)$B?tFwP@+t4CAtft#Q1g-!h(P zsXK)4#eZG>sm&gw6;35PxZcnk?-Y18y=;|RZA;AI8|S@vhlVlPA}r?dO;O*)`Fbfo ztzx8XJW(gN{JU*-H%&L^fb4RckbeKevQ4}OL0n1@9e~L z^SRrZ!9M`BXKv2K(W4IWcZL4|>a|!3a<)#q`fsh{Qj$2#5mO>~--`^^)Yr^YG_Gltqhj9L#02q!}LD^I@e-d+gqJ0OifG^|q{q zjGl^~53~4p<=8JRC4Zt`xI|5TISdPaxR#qVv@rXQe>2YC&f~LMUG}gq8A?xsh=H0a zqETU|g89+}3C|zo+m7--j16i{?;pX`&-E>3nB+<~R=ke<#3vD^*o zrw{Nuv=PB{!mXBJK%h7+80-ZF5|J?=EJax^!jK7$W_iWRD*girrFiff(qHKndYmbN zNY54*(CWNl-4R9vf$>hZiHF8uydg^;2nmI)V~JBtXag+LV0X9#IAL=gNdgIp0K8)P zsaaxpPY+Nqid%1{i;Ll;?{#4m;9z!)siqL%OMWdd?P(gGT1Kr@*jyY+ Y1|s!~F|(pf=ENe=Gy!(6o_{|5ABBVQF8}}l literal 0 HcmV?d00001 diff --git a/rql-ui/src/assets/favicon.ico b/rql-ui/src/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7399cd58bb0637cfd33570002156ca37147848dc GIT binary patch literal 4286 zcmdVdYitx%7=Yo~mO>SfTSRTtBBWRYUWp^DVea;?*HJZmMNTE67 zbB-g>31{J2OvMb`jq7nPj=*Vn3HhFrQ+Z=7XVzmfhT!N7pJNi1V+Cg7CiomT!nN?+ ziAV2eZxfu4^YFM6 z)>7y0 zn2*UAkK6GeUO);yV=2P$eqZB9)S(QIVK2@{80P;=ti+{o|3vS@*PsWy#`V~TH*qtr zfOTWdMk6}5eT-gk4!dv$!l>oL+b}1NTZNGri>q)E9K$?Y_txrt2*bAM^X3}6H+@#1 z4Rg^MVVM7?a2b|k70mk_%!d7+hwT$^2cE!{Sd7%&O18x657pWG|c}_ z_&zbm-H;tV?;!Y0*0FW;7k0z?^7`M9&UlogVa~&OJ9e%bHvjGq_nc!7#nqUITX7wd za9`BpcYKfOa2?(66&Mcl@hiTA*QH?2^Nr1^_J6ybdn3%TH8u<8c@iAwNtoxKV1A?Z z%h!Wp9gM>s{0VauH#VmO^ZzZ}>w{5-?C`$kaUa5U&F&L^Pw>Hg=~}EuuAI|+FwFm2 zbjh?>=ao1W)_s4R0_VL6p6@8C>0k{u!)K3+(VVo#9d8DFpSTXr_qojXjU4ymA#@ad z=wRKo;4@hNabf=LXAayyu7TH=!<;x@-(Ti_8segalMi4RUWGaHy%HC-oZO14m`*;^ zF8H2^3-`zx48ceE0NoK6?i=&mDW;R}4DYoK6?yu3z4@7q3*h@;0Xhnw&wbm36Ob?5 zht~8gnCCD~4Y8)C+1NZ)66X~E!x-BS8w+4xH6ZrErmqY;*vJbVEk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-uV#H=H7MJ6nQfq{90r;B5V$MN2)@fl&I66_z& zTfX1D(|1}P&(^E3s>T*0e7oElo%LnK!omh`o1Rl0Z}F^QQ)?u~P~i;$4g^u2CTlT3~~C@j2C(yuMF z>**e5tGB^V&8_EL$Xk`#mAk#;jMO8hiH>2_w=9>>y|VN`aGY7#%%yh6a`JDiJyNzl zd!vs}_{oGH_tRQk5NPE+RYuW)VN>-5`IP4UbfyUXPrr-l6E7G7R=(syTDMEYKL z7c-UMB{z%LX?Q&pbl!Pl*_31jy$O#u1TCL)_KwV=;J$oaQ!krJpZ-Tqr__t$U(D<7 z`m-{k?AOQRhDYR1uie7=wnMU~smCR@;d?9^S@0a`Zg>G7xo)vF4;dJdN ziFjcPwj#o&#MqRxz$7Z2PkiYQF^rBU* z45D@y-^}xPGR<1)yX&h7smo6snZLYL!24m$lR=^K4{({AOFk%-?;MiE|U5 zWeIFQyxOcf_`=;|Iq63OUa@vxnUy}rVq3&yCz~U}Q6;M!@AyspYU?w1-C4!YPnQTT zxy7%Xi=F4| zB(~D96=h6mnPx0ISNR0KpOyYg<5-GsmS^b2hv^gTQ%ZNADL5>6dJ5-;<4^21OFFkU zZ<^H6bA82G|6|`046cW@ZnIi)vH#W?|4oJ>!fJDuSTr`=t_2h;`{;AC7H7{qZH`)1aSJdWOtxKzdWA@EhoRu?SF|Ue% z$Cqo=IEp!b`bq$O{42-QzOstFybPY_b3=C4g$%>zopr0I`b|XaE2J literal 0 HcmV?d00001 diff --git a/rql-ui/src/assets/graphicloads_filetype_excel_xls-6.png b/rql-ui/src/assets/graphicloads_filetype_excel_xls-6.png new file mode 100644 index 0000000000000000000000000000000000000000..dd4d61f18ec002e2a8c28bc1839fe0e6edc439c5 GIT binary patch literal 1258 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+081LNZWpAc7&g7wKHq55@6 zb!(H-di=4YUhLv|(?fx_G_FtCaAw}|Tf2|n-gErco-JpV_HC*-d}G_spFeLryu9V; z$^+Lnzy0{?`;YGj&TT(^{m7|nhu^$^_4?h*wFehoxOMXO$fl6%d0+p`S|0&IWde!lbg`oz@@*^`5-SH{17|8nk@ zKA;DS=SF7rhwMGGC2L|()$+Kk$$|N^f^%mC70wDz>-Eo^6p%3?Aa`a^;k=N{34uA& z0@M5b(}Cg>19GMXWlssrn;MoqAtZNlXx5~F|Ns9N%ni=y56GGlm_H}@-KRGNQ=&8a zg0lNVGW&uKUD!2iQ}?Mm`%YdvG-X}Oq_s^yetrM>>&N7E&5L(VEuEgwyfOX6wFAd4 z?_0HR?$q_IfB*iSwxNB+-Z@PR^J`WmEZ;M8#opPqs}m-yuCH5@ShqGYXG(DW+N9iR zA!2c63xLtAQWE4B%perM@ZtyU#Xoo^|Ixf*{%*;|51%eAO86nX^pDPzn>_Ed%$Ize zTQ~POP(5Rkx4TQ_!aG+k06FX>p1!W^kC=Elg^U(3GpS9fmLu77#=>KGdz z2qdQ@H0``;reUFS#YV@5=>^wykG(5iNKDWWW;Tv-Tw^K3(b?Va&meW^%mJqG2@?G* zlNz`lO%4uWk&G}DU9xPcv&fO-=^TbD7HFL~bE@zB$+Kr$v^vf^hfkP4JDMRRfFoF- zKgl&Lu%<9C&ukM@Vv75+XV1hIY701iN=x$0%L^;4%Z#kFb86HGa&Qz02?+}eQxNG; zWHmKoeI&%g^QM5+H8k|9X#(rk4FwZiy58-on&9EA6yTT~TvN>5p|09HB_Znet;Pk5 zg;y+Cy<2^o_!0*;%adPke(|4SkoaiH$*Gf<`2l@v+tJ6pB)w%Yo$9e2gWhl z-aPNc)_K0|q;^u;9LtLx9MeM`&P8olV_q&766NK_SN&}6eg+vkuS*f1%vFA~Yjt;Y zc`CRtzBa$~als*@bYPULmbgZgq$HN4S|t~y0x1R~149d410!8S;}8Q&D?nC}Q!>*kach_&X0QaPfx*+&&t;ucLK6V3xk*(3 literal 0 HcmV?d00001 diff --git a/rql-ui/src/assets/graphicloads_filetype_pdf-6.png b/rql-ui/src/assets/graphicloads_filetype_pdf-6.png new file mode 100644 index 0000000000000000000000000000000000000000..6d2754a5a36ad6fa663a259fe75b6a4538bbc58b GIT binary patch literal 1254 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+081LLg#pAc7|f`<;SB%ufP zF8AzRwiugZMO$Iwa0W!#VRLJcEl%#QI(y!)S^s|RhWBgNKb;>DrWOuV>Er{`T#M z2M>;C<(@1kI$K-+ThMuky8buc>Sh8{i1v{ol zML3p}>=J0^a&lzjNJ&d&cH|3jEYaK4w5LWv!y#0lH^((mP~gdv29Ft{7Y|j)aw90M)2S zvp0iTbAqE^(OcQMv9YmtZTCK{{VS~I$8_@asfB8{P6j(H3O>Eu@vu`IqwP(9f0oYk z4JWme(&o(EERd+Vx?#@Ngvk7FGAp)B>5=(%M%r9l#?I?f#3yr=-|X7m9bKLZE{qZz z&lPV}dz=G|chwTth?11Vl2ohYqEsNoU}Ruup=)5IYiJx|U}Oa+THfEpM)UHx3vIVCg!0MCahPXGV_ literal 0 HcmV?d00001 diff --git a/rql-ui/src/assets/graphicloads_filetype_txt-6.png b/rql-ui/src/assets/graphicloads_filetype_txt-6.png new file mode 100644 index 0000000000000000000000000000000000000000..b5c926178fdfe53a9018be76e37ac1d950aace14 GIT binary patch literal 1156 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 +
+ + + + + + + + + + + + +
Counter example #{{valeur}}
{{Math.trunc(index/rows + 1)}}{{valeur}}
+ + + + + + + + + + + + + + + +
Counter example #{{valeur}}
{{Math.trunc(index/rows + 1)}}{{valeur}}
+
+ + + + +
+
+
+ +
+
+
+ +

Execution summary

+ +

+ Action: check a rule +

+
+ + Execution time: + {{summ.timeExecution/1000}} second + +
+
Indicated support: + {{support}} % +
+
Computed support: + {{summ.support * 100}} % +
+
+
+ +
+
Indicated confidence: + {{confiance}} % +
+
Computed confidence: + {{summ.confidence * 100}} % +
+
+
+ Rule veracity: + {{summ.isTrue}} + + Counter examples: + {{summ.counterExampleNB}} + + Query attributes: + {{summ.attributesList.length}} + +
+ +
    +
  • {{option}}
  • +
+
+
+
+
+ RQL +
+
+
+
+ + + + + + + diff --git a/rql-ui/src/components/DataBaseSchema.vue b/rql-ui/src/components/DataBaseSchema.vue new file mode 100644 index 0000000..5f0b104 --- /dev/null +++ b/rql-ui/src/components/DataBaseSchema.vue @@ -0,0 +1,138 @@ + + + + + diff --git a/rql-ui/src/components/DatabaseTableImport.vue b/rql-ui/src/components/DatabaseTableImport.vue new file mode 100644 index 0000000..769b4a4 --- /dev/null +++ b/rql-ui/src/components/DatabaseTableImport.vue @@ -0,0 +1,517 @@ + + + + + + diff --git a/rql-ui/src/components/Login.vue b/rql-ui/src/components/Login.vue new file mode 100644 index 0000000..4c3fcf6 --- /dev/null +++ b/rql-ui/src/components/Login.vue @@ -0,0 +1,231 @@ + + + + + \ No newline at end of file diff --git a/rql-ui/src/components/Project.vue b/rql-ui/src/components/Project.vue new file mode 100644 index 0000000..b1b5c1c --- /dev/null +++ b/rql-ui/src/components/Project.vue @@ -0,0 +1,669 @@ + + + + + diff --git a/rql-ui/src/components/QueryArea.vue b/rql-ui/src/components/QueryArea.vue new file mode 100644 index 0000000..71dae9d --- /dev/null +++ b/rql-ui/src/components/QueryArea.vue @@ -0,0 +1,886 @@ + + + + + + diff --git a/rql-ui/src/components/RulesArea.vue b/rql-ui/src/components/RulesArea.vue new file mode 100644 index 0000000..8ff498d --- /dev/null +++ b/rql-ui/src/components/RulesArea.vue @@ -0,0 +1,427 @@ + + + + + diff --git a/rql-ui/src/components/SqlArea.vue b/rql-ui/src/components/SqlArea.vue new file mode 100644 index 0000000..75c8050 --- /dev/null +++ b/rql-ui/src/components/SqlArea.vue @@ -0,0 +1,290 @@ + + + + + + \ No newline at end of file diff --git a/rql-ui/src/components/UtilsMixins.vue b/rql-ui/src/components/UtilsMixins.vue new file mode 100644 index 0000000..7503a94 --- /dev/null +++ b/rql-ui/src/components/UtilsMixins.vue @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/rql-ui/src/components/VueDualList.vue b/rql-ui/src/components/VueDualList.vue new file mode 100644 index 0000000..e92a0ae --- /dev/null +++ b/rql-ui/src/components/VueDualList.vue @@ -0,0 +1,151 @@ + + + + + \ No newline at end of file diff --git a/rql-ui/src/components/Workspace.vue b/rql-ui/src/components/Workspace.vue new file mode 100644 index 0000000..31c7318 --- /dev/null +++ b/rql-ui/src/components/Workspace.vue @@ -0,0 +1,337 @@ + + + + diff --git a/rql-ui/src/components/vue-materialize-datatable/package.json b/rql-ui/src/components/vue-materialize-datatable/package.json new file mode 100644 index 0000000..3016667 --- /dev/null +++ b/rql-ui/src/components/vue-materialize-datatable/package.json @@ -0,0 +1,78 @@ +{ + "_from": "vue-materialize-datatable", + "_id": "vue-materialize-datatable@0.7.3", + "_inBundle": false, + "_integrity": "sha512-qOVaUPfNbmBFzZgHYsWl8n2XwsG4H1Y2yz9U0pdm/wcbNeN1lcfcAhCEq5A0a3AaxdefETnk01ndjw60iT9ixg==", + "_location": "/vue-materialize-datatable", + "_phantomChildren": { + "envify": "3.4.1" + }, + "_requested": { + "type": "tag", + "registry": true, + "raw": "vue-materialize-datatable", + "name": "vue-materialize-datatable", + "escapedName": "vue-materialize-datatable", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/vue-materialize-datatable/-/vue-materialize-datatable-0.7.3.tgz", + "_shasum": "1a7aa048f0a9bc8b4df9b6c2b90b371d009bb8f2", + "_spec": "vue-materialize-datatable", + "_where": "C:\\Raedt\\CaldersV1\\rql\\rql-ui", + "author": { + "name": "Yousef Sultan", + "email": "yousef.su.2000@gmail.com" + }, + "bugs": { + "url": "https://github.com/MicroDroid/vue-materialize-datatable/issues" + }, + "bundleDependencies": false, + "dependencies": { + "babel-runtime": "^6.0.0", + "fuse.js": "^2.6.2", + "vue": "^1.0.21" + }, + "deprecated": false, + "description": "Datatable for VueJS with Materialize", + "devDependencies": { + "babel-core": "^6.0.0", + "babel-loader": "^6.0.0", + "babel-plugin-transform-runtime": "^6.0.0", + "babel-preset-es2015": "^6.0.0", + "babel-preset-stage-2": "^6.0.0", + "babel-register": "^6.0.0", + "css-loader": "^0.23.0", + "node-sass": "^3.8.0", + "sass-loader": "^4.0.0", + "vue-html-loader": "^1.2.3", + "vue-loader": "^8.3.0", + "vue-style-loader": "^1.0.0", + "webpack": "^1.12.2" + }, + "homepage": "https://github.com/MicroDroid/vue-materialize-datatable", + "keywords": [ + "Vue", + "Datatable", + "Materialize", + "Table Component" + ], + "license": "MIT", + "main": "./src/DataTable.vue", + "name": "vue-materialize-datatable", + "private": false, + "repository": { + "type": "git", + "url": "git+https://github.com/MicroDroid/vue-materialize-datatable.git" + }, + "scripts": { + "build": "webpack", + "demo": "cd docs && webpack" + }, + "version": "0.7.3" +} diff --git a/rql-ui/src/components/vue-materialize-datatable/src/DataTable.vue b/rql-ui/src/components/vue-materialize-datatable/src/DataTable.vue new file mode 100644 index 0000000..a12c920 --- /dev/null +++ b/rql-ui/src/components/vue-materialize-datatable/src/DataTable.vue @@ -0,0 +1,563 @@ + + + + + diff --git a/rql-ui/src/components/vue-materialize-datatable/src/locales/ar.json b/rql-ui/src/components/vue-materialize-datatable/src/locales/ar.json new file mode 100644 index 0000000..4a607f8 --- /dev/null +++ b/rql-ui/src/components/vue-materialize-datatable/src/locales/ar.json @@ -0,0 +1,7 @@ +{ + "rows_per_page": "عدد النتائج كل صفحة", + "out_of_pages": "من أصل", + "all": "الكل", + "__is_rtl": true, + "search_data": "Search data" +} diff --git a/rql-ui/src/components/vue-materialize-datatable/src/locales/br.json b/rql-ui/src/components/vue-materialize-datatable/src/locales/br.json new file mode 100644 index 0000000..c10ca0d --- /dev/null +++ b/rql-ui/src/components/vue-materialize-datatable/src/locales/br.json @@ -0,0 +1,6 @@ +{ + "rows_per_page": "Linhas por página", + "out_of_pages": "de", + "all": "Todos", + "search_data": "Pesquisar" +} diff --git a/rql-ui/src/components/vue-materialize-datatable/src/locales/cat.json b/rql-ui/src/components/vue-materialize-datatable/src/locales/cat.json new file mode 100644 index 0000000..3593768 --- /dev/null +++ b/rql-ui/src/components/vue-materialize-datatable/src/locales/cat.json @@ -0,0 +1,6 @@ +{ + "rows_per_page": "Files per pàgina", + "out_of_pages": "de", + "all": "Totes", + "search_data": "Buscar dades" +} diff --git a/rql-ui/src/components/vue-materialize-datatable/src/locales/en.json b/rql-ui/src/components/vue-materialize-datatable/src/locales/en.json new file mode 100644 index 0000000..3c79294 --- /dev/null +++ b/rql-ui/src/components/vue-materialize-datatable/src/locales/en.json @@ -0,0 +1,6 @@ +{ + "rows_per_page": "Results per page", + "out_of_pages": "of", + "all": "All", + "search_data": "Search" +} diff --git a/rql-ui/src/components/vue-materialize-datatable/src/locales/es.json b/rql-ui/src/components/vue-materialize-datatable/src/locales/es.json new file mode 100644 index 0000000..8c7e33f --- /dev/null +++ b/rql-ui/src/components/vue-materialize-datatable/src/locales/es.json @@ -0,0 +1,6 @@ +{ + "rows_per_page": "Filas por página", + "out_of_pages": "de", + "all": "Todas", + "search_data": "Buscar datos" +} diff --git a/rql-ui/src/components/vue-materialize-datatable/src/locales/index.js b/rql-ui/src/components/vue-materialize-datatable/src/locales/index.js new file mode 100644 index 0000000..a9825c7 --- /dev/null +++ b/rql-ui/src/components/vue-materialize-datatable/src/locales/index.js @@ -0,0 +1,7 @@ +module.exports = { + en: require('./en.json'), + ar: require('./ar.json'), + es: require('./es.json'), + br: require('./br.json'), + cat: require('./cat.json') +} diff --git a/rql-ui/src/components/vue-materialize-datatable/webpack.config.js b/rql-ui/src/components/vue-materialize-datatable/webpack.config.js new file mode 100644 index 0000000..eb008a2 --- /dev/null +++ b/rql-ui/src/components/vue-materialize-datatable/webpack.config.js @@ -0,0 +1,29 @@ +var path = require('path'); +var webpack = require('webpack'); + +module.exports = { + entry: './src/DataTable.vue', + + output: { + path: path.resolve(__dirname, './dist'), + filename: 'vue-datatable.js' + }, + + module: { + loaders: [ + { + test: /\.js$/, + loader: 'babel', + exclude: /node_modules/, + include: [path.resolve(__dirname, './src')] + }, + { test: /\.vue$/, loader: 'vue'} + ] + }, + + vue: { + loaders: { + scss: "vue-style!css!sass" + } + }, +} diff --git a/rql-ui/src/directives/Dropdown.js b/rql-ui/src/directives/Dropdown.js new file mode 100644 index 0000000..0eac3ba --- /dev/null +++ b/rql-ui/src/directives/Dropdown.js @@ -0,0 +1,27 @@ +export default { + bind: function (el, binding) { + let ddToggle = el.querySelector('.dropdown-toggle') + let ddMenu = el.querySelector('.dropdown-menu') + let closeOnMenuClick = binding.modifiers.closeOnMenuClick + + ddToggle.addEventListener('click', function (evt) { + evt.preventDefault() + let isShown = el.classList.contains('show') + setTimeout(() => { + el.classList.toggle('show', !isShown) + ddMenu.classList.toggle('show', !isShown) + }) + }) + + window.addEventListener('click', function () { + el.classList.remove('show') + ddMenu.classList.remove('show') + }) + + ddMenu.addEventListener('click', function (evt) { + if (!closeOnMenuClick) { + evt.stopPropagation() + } + }) + } +} diff --git a/rql-ui/src/directives/Expandable.js b/rql-ui/src/directives/Expandable.js new file mode 100644 index 0000000..39825fb --- /dev/null +++ b/rql-ui/src/directives/Expandable.js @@ -0,0 +1,54 @@ +let directive = { + dom: null, + scrollbarTransition: { + el: null, + handler: null + }, + inserted: (el, binding) => { + let items = binding.value.menuItems + let scrollbar = binding.value.refs.Scrollbar + let childClassName = binding.value.childClassName + let childHeight = binding.value.childHeight + directive.dom = { + elements: document.getElementsByClassName(childClassName), + handlers: [] + } + let parentId = binding.value.parentId + directive.scrollbarTransition.el = document.getElementById(parentId).getElementsByClassName('vue-scrollbar-transition')[0] + + directive.scrollbarTransition.handler = event => { + scrollbar.calculateSize() + } + + directive.scrollbarTransition.el.addEventListener('transitionend', directive.scrollbarTransition.handler) + + let expandHandler = item => { + return event => { + if (!item.meta.expanded) { + scrollbar.scrollToY(scrollbar.top - childHeight * item.children.length) + } else { + scrollbar.scrollToY(scrollbar.top + childHeight) + } + scrollbar.calculateSize() + } + } + + for (let i = 0; i < items.length; i++) { + let item = items[i] + let domItem = directive.dom.elements[i] + directive.dom.handlers.push(expandHandler(item)) + if (item.children) { + domItem.addEventListener('transitionend', directive.dom.handlers[i]) + } + } + }, + unbind: () => { + directive.scrollbarTransition.el.removeEventListener('transitionend', directive.scrollbarTransition.handler) + + for (let i = 0; i < directive.dom.elements.length; i++) { + directive.dom.elements[i].removeEventListener('transitionend', directive.dom.handlers[i]) + } + } +} + +module.exports = directive diff --git a/rql-ui/src/directives/ResizeHandler.js b/rql-ui/src/directives/ResizeHandler.js new file mode 100644 index 0000000..92735c2 --- /dev/null +++ b/rql-ui/src/directives/ResizeHandler.js @@ -0,0 +1,26 @@ +import store from 'vuex-store' + +export default { + inserted: function (el) { + let getWindowMatch = () => { + return window.matchMedia(store.getters.config.windowMatchSizeLg).matches + } + + let prevMatchlg = getWindowMatch() + + el.addEventListener('transitionend', function () { + store.dispatch('isToggleWithoutAnimation', false) + }) + + window.addEventListener('resize', function () { + if (getWindowMatch() && !prevMatchlg) { + store.dispatch('toggleSidebar', true) + } else if (!getWindowMatch() && prevMatchlg) { + store.dispatch('isToggleWithoutAnimation', true) + store.dispatch('toggleSidebar', false) + } + prevMatchlg = getWindowMatch() + }) + } +} + diff --git a/rql-ui/src/directives/StickyScroll.js b/rql-ui/src/directives/StickyScroll.js new file mode 100644 index 0000000..99f1a58 --- /dev/null +++ b/rql-ui/src/directives/StickyScroll.js @@ -0,0 +1,48 @@ +export default { + bind: (el, binding) => { + let duration = binding.value.duration || 500 + let isAnimated = binding.value.animate + + let observer = new MutationObserver(scrollToBottom) + let config = { childList: true } + observer.observe(el, config) + + function animateScroll (duration) { + let start = el.scrollTop + let end = el.scrollHeight + let change = end - start + let increment = 20 + + function easeInOut (currentTime, start, change, duration) { + currentTime /= duration / 2 + if (currentTime < 1) { + return change / 2 * currentTime * currentTime + start + } + currentTime -= 1 + return -change / 2 * (currentTime * (currentTime - 2) - 1) + start + } + + function animate (elapsedTime) { + elapsedTime += increment + var position = easeInOut(elapsedTime, start, change, duration) + el.scrollTop = position + + if (elapsedTime < duration) { + setTimeout(function () { + animate(elapsedTime) + }, increment) + } + } + + animate(0) + } + + function scrollToBottom () { + if (isAnimated) { + animateScroll(duration) + } else { + el.scrollTop = el.scrollHeight + } + } + } +} diff --git a/rql-ui/src/fonts/Glyphter.eot b/rql-ui/src/fonts/Glyphter.eot new file mode 100644 index 0000000000000000000000000000000000000000..9c9f36ea370d417901c40f07dad01381122157f0 GIT binary patch literal 5688 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 z`4c!zGenerated by Glyphter \ No newline at end of file diff --git a/rql-ui/src/fonts/Glyphter.ttf b/rql-ui/src/fonts/Glyphter.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9d68d8a302712f4eb0858053480df0f08747d6e6 GIT binary patch literal 5520 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 SImn4{>n0DW)Br2r;PYGT(zY%D literal 0 HcmV?d00001 diff --git a/rql-ui/src/fonts/Glyphter.woff b/rql-ui/src/fonts/Glyphter.woff new file mode 100644 index 0000000000000000000000000000000000000000..397ba4051196ced5c6de7a1f2243e9d2b3d85af2 GIT binary patch literal 3440 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rql-ui/src/fonts/glyphicons-halflings-regular.ttf b/rql-ui/src/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1413fc609ab6f21774de0cb7e01360095584f65b GIT binary patch literal 45404 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 G`u_lkUM?>H literal 0 HcmV?d00001 diff --git a/rql-ui/src/fonts/glyphicons-halflings-regular.woff2 b/rql-ui/src/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..64539b54c3751a6d9adb44c8e3a45ba5a73b77f0 GIT binary patch literal 18028 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 literal 0 HcmV?d00001 diff --git a/rql-ui/src/main.js b/rql-ui/src/main.js new file mode 100644 index 0000000..ac51704 --- /dev/null +++ b/rql-ui/src/main.js @@ -0,0 +1,32 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import BootstrapVue from 'bootstrap-vue/dist/bootstrap-vue.esm' +import App from './App' +import router from './router' +import VueResource from 'vue-resource' +import vSelect from 'vue-select' +import 'bootstrap/dist/css/bootstrap.css' +import 'bootstrap-vue/dist/bootstrap-vue.css' +import 'semantic-ui-css/semantic.min.css' +import VueCarousel from 'vue-carousel' +import VueClip from 'vue-clip' +import VueFormWizard from 'vue-form-wizard' +import 'vue-form-wizard/dist/vue-form-wizard.min.css' + +require('./assets/RQL.css') +Vue.use(VueResource) +Vue.http.options.emulateJSON = true +Vue.use(BootstrapVue) +Vue.use(VueCarousel) +Vue.use(VueClip) +Vue.use(VueFormWizard) +Vue.component('v-select', vSelect) +window.bus = new Vue() +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + template: '', + components: { App } +}) diff --git a/rql-ui/src/router/index.js b/rql-ui/src/router/index.js new file mode 100644 index 0000000..e672ac4 --- /dev/null +++ b/rql-ui/src/router/index.js @@ -0,0 +1,62 @@ +import Vue from 'vue' +import Router from 'vue-router' + +import Workspace from '@/components/Workspace' +import DatabaseTableImport from '@/components/DatabaseTableImport' +import Login from '@/components/Login' +import Project from '@/components/Project' + +Vue.use(Router) + +const router = new Router({ + mode: 'history', + base: '/rql', + routes: [ + { + path: '/login', + name: 'Login', + component: Login + }, + { + path: '/workspace', + name: 'Workspace', + component: Workspace + }, + { + path: '/project', + name: 'Project', + component: Project + }, + { + path: '/DatabaseTableImport', + name: 'DatabaseTableImport', + component: DatabaseTableImport + }, + { + path: '/*', + redirect: { name: 'Login' } + } + ] +}) + +router.beforeEach((to, from, next) => { + if (to.path === '/login') { + next() + } + var token = localStorage.getItem('TOKEN') + var projectID = localStorage.getItem('PROJECTID') + if (token !== null) { + next() + } else { + next({path: '/login'}) + } + if (projectID !== null) { + next() + } else if (from.path !== '/project') { + next({path: '/project'}) + } else { + next() + } +}) + +export default router diff --git a/rql-ui/src/sass/_base.scss b/rql-ui/src/sass/_base.scss new file mode 100644 index 0000000..a019138 --- /dev/null +++ b/rql-ui/src/sass/_base.scss @@ -0,0 +1,40 @@ +html { + height: 100%; +} +body { + min-height: 100%; +} + +//Util classes +.ellipsis { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.widget-viewport-height { + height: $widget-viewport-height; +} + +.none { + display: none; +} + +.pointer { + cursor: pointer; +} + +a:not([href]):not([tabindex]) { + color: $white; + cursor: pointer; +} + +a:not([href]):not([tabindex]):hover { + color: $white; + cursor: pointer; +} + +a:not([href]):not([tabindex]):focus { + color: $white; + cursor: pointer; +} diff --git a/rql-ui/src/sass/_fonts.scss b/rql-ui/src/sass/_fonts.scss new file mode 100644 index 0000000..737ee10 --- /dev/null +++ b/rql-ui/src/sass/_fonts.scss @@ -0,0 +1,46 @@ +// Fonts // +@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro); + +@font-face { + font-family: 'Vuestic Icons'; + src: url('#{$icon-font-path}/Glyphter.eot'); + src: url('#{$icon-font-path}/Glyphter.eot?#iefix') format('embedded-opentype'), + url('#{$icon-font-path}/Glyphter.woff') format('woff'), + url('#{$icon-font-path}/Glyphter.ttf') format('truetype'), + url('#{$icon-font-path}/Glyphter.svg#Glyphter') format('svg'); + font-weight: normal; + font-style: normal; +} + +.vuestic-icon { + line-height: 1; +} + +.vuestic-icon:before{ + display: inline-block; + font-family: 'Vuestic Icons'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale +} + +.vuestic-icon-comments:before{content:'\0041';} +.vuestic-icon-components:before{content:'\0042';} +.vuestic-icon-dashboard:before{content:'\0043';} +.vuestic-icon-extras:before{content:'\0044';} +.vuestic-icon-files:before{content:'\0045';} +.vuestic-icon-forms:before{content:'\0046';} +.vuestic-icon-graph:before{content:'\0047';} +.vuestic-icon-auth:before{content:'\0048';} +.vuestic-icon-image:before{content:'\0049';} +.vuestic-icon-maps:before{content:'\004a';} +.vuestic-icon-music:before{content:'\004b';} +.vuestic-icon-settings:before{content:'\004c';} +.vuestic-icon-statistics:before{content:'\004d';} +.vuestic-icon-tables:before{content:'\004e';} +.vuestic-icon-time:before{content:'\004f';} +.vuestic-icon-ui-elements:before{content:'\0050';} +.vuestic-icon-user:before{content:'\0051';} +.vuestic-icon-video:before{content:'\0052';} diff --git a/rql-ui/src/sass/_glyphicons.scss b/rql-ui/src/sass/_glyphicons.scss new file mode 100644 index 0000000..b3e02cb --- /dev/null +++ b/rql-ui/src/sass/_glyphicons.scss @@ -0,0 +1,307 @@ +// +// Glyphicons for Bootstrap +// +// Since icons are fonts, they can be placed anywhere text is placed and are +// thus automatically sized to match the surrounding child. To use, create an +// inline element with the appropriate classes, like so: +// +// Star + +@at-root { + // Import the fonts + @font-face { + font-family: 'Glyphicons Halflings'; + src: url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.eot'), '#{$icon-font-path}#{$icon-font-name}.eot')); + src: url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.eot?#iefix'), '#{$icon-font-path}#{$icon-font-name}.eot?#iefix')) format('embedded-opentype'), + url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.woff2'), '#{$icon-font-path}#{$icon-font-name}.woff2')) format('woff2'), + url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.woff'), '#{$icon-font-path}#{$icon-font-name}.woff')) format('woff'), + url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.ttf'), '#{$icon-font-path}#{$icon-font-name}.ttf')) format('truetype'), + url(if($bootstrap-sass-asset-helper, twbs-font-path('#{$icon-font-path}#{$icon-font-name}.svg##{$icon-font-svg-id}'), '#{$icon-font-path}#{$icon-font-name}.svg##{$icon-font-svg-id}')) format('svg'); + } +} + +// Catchall baseclass +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +// Individual icons +.glyphicon-asterisk { &:before { content: "\002a"; } } +.glyphicon-plus { &:before { content: "\002b"; } } +.glyphicon-euro, +.glyphicon-eur { &:before { content: "\20ac"; } } +.glyphicon-minus { &:before { content: "\2212"; } } +.glyphicon-cloud { &:before { content: "\2601"; } } +.glyphicon-envelope { &:before { content: "\2709"; } } +.glyphicon-pencil { &:before { content: "\270f"; } } +.glyphicon-glass { &:before { content: "\e001"; } } +.glyphicon-music { &:before { content: "\e002"; } } +.glyphicon-search { &:before { content: "\e003"; } } +.glyphicon-heart { &:before { content: "\e005"; } } +.glyphicon-star { &:before { content: "\e006"; } } +.glyphicon-star-empty { &:before { content: "\e007"; } } +.glyphicon-user { &:before { content: "\e008"; } } +.glyphicon-film { &:before { content: "\e009"; } } +.glyphicon-th-large { &:before { content: "\e010"; } } +.glyphicon-th { &:before { content: "\e011"; } } +.glyphicon-th-list { &:before { content: "\e012"; } } +.glyphicon-ok { &:before { content: "\e013"; } } +.glyphicon-remove { &:before { content: "\e014"; } } +.glyphicon-zoom-in { &:before { content: "\e015"; } } +.glyphicon-zoom-out { &:before { content: "\e016"; } } +.glyphicon-off { &:before { content: "\e017"; } } +.glyphicon-signal { &:before { content: "\e018"; } } +.glyphicon-cog { &:before { content: "\e019"; } } +.glyphicon-trash { &:before { content: "\e020"; } } +.glyphicon-home { &:before { content: "\e021"; } } +.glyphicon-file { &:before { content: "\e022"; } } +.glyphicon-time { &:before { content: "\e023"; } } +.glyphicon-road { &:before { content: "\e024"; } } +.glyphicon-download-alt { &:before { content: "\e025"; } } +.glyphicon-download { &:before { content: "\e026"; } } +.glyphicon-upload { &:before { content: "\e027"; } } +.glyphicon-inbox { &:before { content: "\e028"; } } +.glyphicon-play-circle { &:before { content: "\e029"; } } +.glyphicon-repeat { &:before { content: "\e030"; } } +.glyphicon-refresh { &:before { content: "\e031"; } } +.glyphicon-list-alt { &:before { content: "\e032"; } } +.glyphicon-lock { &:before { content: "\e033"; } } +.glyphicon-flag { &:before { content: "\e034"; } } +.glyphicon-headphones { &:before { content: "\e035"; } } +.glyphicon-volume-off { &:before { content: "\e036"; } } +.glyphicon-volume-down { &:before { content: "\e037"; } } +.glyphicon-volume-up { &:before { content: "\e038"; } } +.glyphicon-qrcode { &:before { content: "\e039"; } } +.glyphicon-barcode { &:before { content: "\e040"; } } +.glyphicon-tag { &:before { content: "\e041"; } } +.glyphicon-tags { &:before { content: "\e042"; } } +.glyphicon-book { &:before { content: "\e043"; } } +.glyphicon-bookmark { &:before { content: "\e044"; } } +.glyphicon-print { &:before { content: "\e045"; } } +.glyphicon-camera { &:before { content: "\e046"; } } +.glyphicon-font { &:before { content: "\e047"; } } +.glyphicon-bold { &:before { content: "\e048"; } } +.glyphicon-italic { &:before { content: "\e049"; } } +.glyphicon-text-height { &:before { content: "\e050"; } } +.glyphicon-text-width { &:before { content: "\e051"; } } +.glyphicon-align-left { &:before { content: "\e052"; } } +.glyphicon-align-center { &:before { content: "\e053"; } } +.glyphicon-align-right { &:before { content: "\e054"; } } +.glyphicon-align-justify { &:before { content: "\e055"; } } +.glyphicon-list { &:before { content: "\e056"; } } +.glyphicon-indent-left { &:before { content: "\e057"; } } +.glyphicon-indent-right { &:before { content: "\e058"; } } +.glyphicon-facetime-video { &:before { content: "\e059"; } } +.glyphicon-picture { &:before { content: "\e060"; } } +.glyphicon-map-marker { &:before { content: "\e062"; } } +.glyphicon-adjust { &:before { content: "\e063"; } } +.glyphicon-tint { &:before { content: "\e064"; } } +.glyphicon-edit { &:before { content: "\e065"; } } +.glyphicon-share { &:before { content: "\e066"; } } +.glyphicon-check { &:before { content: "\e067"; } } +.glyphicon-move { &:before { content: "\e068"; } } +.glyphicon-step-backward { &:before { content: "\e069"; } } +.glyphicon-fast-backward { &:before { content: "\e070"; } } +.glyphicon-backward { &:before { content: "\e071"; } } +.glyphicon-play { &:before { content: "\e072"; } } +.glyphicon-pause { &:before { content: "\e073"; } } +.glyphicon-stop { &:before { content: "\e074"; } } +.glyphicon-forward { &:before { content: "\e075"; } } +.glyphicon-fast-forward { &:before { content: "\e076"; } } +.glyphicon-step-forward { &:before { content: "\e077"; } } +.glyphicon-eject { &:before { content: "\e078"; } } +.glyphicon-chevron-left { &:before { content: "\e079"; } } +.glyphicon-chevron-right { &:before { content: "\e080"; } } +.glyphicon-plus-sign { &:before { content: "\e081"; } } +.glyphicon-minus-sign { &:before { content: "\e082"; } } +.glyphicon-remove-sign { &:before { content: "\e083"; } } +.glyphicon-ok-sign { &:before { content: "\e084"; } } +.glyphicon-question-sign { &:before { content: "\e085"; } } +.glyphicon-info-sign { &:before { content: "\e086"; } } +.glyphicon-screenshot { &:before { content: "\e087"; } } +.glyphicon-remove-circle { &:before { content: "\e088"; } } +.glyphicon-ok-circle { &:before { content: "\e089"; } } +.glyphicon-ban-circle { &:before { content: "\e090"; } } +.glyphicon-arrow-left { &:before { content: "\e091"; } } +.glyphicon-arrow-right { &:before { content: "\e092"; } } +.glyphicon-arrow-up { &:before { content: "\e093"; } } +.glyphicon-arrow-down { &:before { content: "\e094"; } } +.glyphicon-share-alt { &:before { content: "\e095"; } } +.glyphicon-resize-full { &:before { content: "\e096"; } } +.glyphicon-resize-small { &:before { content: "\e097"; } } +.glyphicon-exclamation-sign { &:before { content: "\e101"; } } +.glyphicon-gift { &:before { content: "\e102"; } } +.glyphicon-leaf { &:before { content: "\e103"; } } +.glyphicon-fire { &:before { content: "\e104"; } } +.glyphicon-eye-open { &:before { content: "\e105"; } } +.glyphicon-eye-close { &:before { content: "\e106"; } } +.glyphicon-warning-sign { &:before { content: "\e107"; } } +.glyphicon-plane { &:before { content: "\e108"; } } +.glyphicon-calendar { &:before { content: "\e109"; } } +.glyphicon-random { &:before { content: "\e110"; } } +.glyphicon-comment { &:before { content: "\e111"; } } +.glyphicon-magnet { &:before { content: "\e112"; } } +.glyphicon-chevron-up { &:before { content: "\e113"; } } +.glyphicon-chevron-down { &:before { content: "\e114"; } } +.glyphicon-retweet { &:before { content: "\e115"; } } +.glyphicon-shopping-cart { &:before { content: "\e116"; } } +.glyphicon-folder-close { &:before { content: "\e117"; } } +.glyphicon-folder-open { &:before { content: "\e118"; } } +.glyphicon-resize-vertical { &:before { content: "\e119"; } } +.glyphicon-resize-horizontal { &:before { content: "\e120"; } } +.glyphicon-hdd { &:before { content: "\e121"; } } +.glyphicon-bullhorn { &:before { content: "\e122"; } } +.glyphicon-bell { &:before { content: "\e123"; } } +.glyphicon-certificate { &:before { content: "\e124"; } } +.glyphicon-thumbs-up { &:before { content: "\e125"; } } +.glyphicon-thumbs-down { &:before { content: "\e126"; } } +.glyphicon-hand-right { &:before { content: "\e127"; } } +.glyphicon-hand-left { &:before { content: "\e128"; } } +.glyphicon-hand-up { &:before { content: "\e129"; } } +.glyphicon-hand-down { &:before { content: "\e130"; } } +.glyphicon-circle-arrow-right { &:before { content: "\e131"; } } +.glyphicon-circle-arrow-left { &:before { content: "\e132"; } } +.glyphicon-circle-arrow-up { &:before { content: "\e133"; } } +.glyphicon-circle-arrow-down { &:before { content: "\e134"; } } +.glyphicon-globe { &:before { content: "\e135"; } } +.glyphicon-wrench { &:before { content: "\e136"; } } +.glyphicon-tasks { &:before { content: "\e137"; } } +.glyphicon-filter { &:before { content: "\e138"; } } +.glyphicon-briefcase { &:before { content: "\e139"; } } +.glyphicon-fullscreen { &:before { content: "\e140"; } } +.glyphicon-dashboard { &:before { content: "\e141"; } } +.glyphicon-paperclip { &:before { content: "\e142"; } } +.glyphicon-heart-empty { &:before { content: "\e143"; } } +.glyphicon-link { &:before { content: "\e144"; } } +.glyphicon-phone { &:before { content: "\e145"; } } +.glyphicon-pushpin { &:before { content: "\e146"; } } +.glyphicon-usd { &:before { content: "\e148"; } } +.glyphicon-gbp { &:before { content: "\e149"; } } +.glyphicon-sort { &:before { content: "\e150"; } } +.glyphicon-sort-by-alphabet { &:before { content: "\e151"; } } +.glyphicon-sort-by-alphabet-alt { &:before { content: "\e152"; } } +.glyphicon-sort-by-order { &:before { content: "\e153"; } } +.glyphicon-sort-by-order-alt { &:before { content: "\e154"; } } +.glyphicon-sort-by-attributes { &:before { content: "\e155"; } } +.glyphicon-sort-by-attributes-alt { &:before { content: "\e156"; } } +.glyphicon-unchecked { &:before { content: "\e157"; } } +.glyphicon-expand { &:before { content: "\e158"; } } +.glyphicon-collapse-down { &:before { content: "\e159"; } } +.glyphicon-collapse-up { &:before { content: "\e160"; } } +.glyphicon-log-in { &:before { content: "\e161"; } } +.glyphicon-flash { &:before { content: "\e162"; } } +.glyphicon-log-out { &:before { content: "\e163"; } } +.glyphicon-new-window { &:before { content: "\e164"; } } +.glyphicon-record { &:before { content: "\e165"; } } +.glyphicon-save { &:before { content: "\e166"; } } +.glyphicon-open { &:before { content: "\e167"; } } +.glyphicon-saved { &:before { content: "\e168"; } } +.glyphicon-import { &:before { content: "\e169"; } } +.glyphicon-export { &:before { content: "\e170"; } } +.glyphicon-send { &:before { content: "\e171"; } } +.glyphicon-floppy-disk { &:before { content: "\e172"; } } +.glyphicon-floppy-saved { &:before { content: "\e173"; } } +.glyphicon-floppy-remove { &:before { content: "\e174"; } } +.glyphicon-floppy-save { &:before { content: "\e175"; } } +.glyphicon-floppy-open { &:before { content: "\e176"; } } +.glyphicon-credit-card { &:before { content: "\e177"; } } +.glyphicon-transfer { &:before { content: "\e178"; } } +.glyphicon-cutlery { &:before { content: "\e179"; } } +.glyphicon-header { &:before { content: "\e180"; } } +.glyphicon-compressed { &:before { content: "\e181"; } } +.glyphicon-earphone { &:before { content: "\e182"; } } +.glyphicon-phone-alt { &:before { content: "\e183"; } } +.glyphicon-tower { &:before { content: "\e184"; } } +.glyphicon-stats { &:before { content: "\e185"; } } +.glyphicon-sd-video { &:before { content: "\e186"; } } +.glyphicon-hd-video { &:before { content: "\e187"; } } +.glyphicon-subtitles { &:before { content: "\e188"; } } +.glyphicon-sound-stereo { &:before { content: "\e189"; } } +.glyphicon-sound-dolby { &:before { content: "\e190"; } } +.glyphicon-sound-5-1 { &:before { content: "\e191"; } } +.glyphicon-sound-6-1 { &:before { content: "\e192"; } } +.glyphicon-sound-7-1 { &:before { content: "\e193"; } } +.glyphicon-copyright-mark { &:before { content: "\e194"; } } +.glyphicon-registration-mark { &:before { content: "\e195"; } } +.glyphicon-cloud-download { &:before { content: "\e197"; } } +.glyphicon-cloud-upload { &:before { content: "\e198"; } } +.glyphicon-tree-conifer { &:before { content: "\e199"; } } +.glyphicon-tree-deciduous { &:before { content: "\e200"; } } +.glyphicon-cd { &:before { content: "\e201"; } } +.glyphicon-save-file { &:before { content: "\e202"; } } +.glyphicon-open-file { &:before { content: "\e203"; } } +.glyphicon-level-up { &:before { content: "\e204"; } } +.glyphicon-copy { &:before { content: "\e205"; } } +.glyphicon-paste { &:before { content: "\e206"; } } +// The following 2 Glyphicons are omitted for the time being because +// they currently use Unicode codepoints that are outside the +// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle +// non-BMP codepoints in CSS string escapes, and thus can't display these two icons. +// Notably, the bug affects some older versions of the Android Browser. +// More info: https://github.com/twbs/bootstrap/issues/10106 +// .glyphicon-door { &:before { content: "\1f6aa"; } } +// .glyphicon-key { &:before { content: "\1f511"; } } +.glyphicon-alert { &:before { content: "\e209"; } } +.glyphicon-equalizer { &:before { content: "\e210"; } } +.glyphicon-king { &:before { content: "\e211"; } } +.glyphicon-queen { &:before { content: "\e212"; } } +.glyphicon-pawn { &:before { content: "\e213"; } } +.glyphicon-bishop { &:before { content: "\e214"; } } +.glyphicon-knight { &:before { content: "\e215"; } } +.glyphicon-baby-formula { &:before { content: "\e216"; } } +.glyphicon-tent { &:before { content: "\26fa"; } } +.glyphicon-blackboard { &:before { content: "\e218"; } } +.glyphicon-bed { &:before { content: "\e219"; } } +.glyphicon-apple { &:before { content: "\f8ff"; } } +.glyphicon-erase { &:before { content: "\e221"; } } +.glyphicon-hourglass { &:before { content: "\231b"; } } +.glyphicon-lamp { &:before { content: "\e223"; } } +.glyphicon-duplicate { &:before { content: "\e224"; } } +.glyphicon-piggy-bank { &:before { content: "\e225"; } } +.glyphicon-scissors { &:before { content: "\e226"; } } +.glyphicon-bitcoin { &:before { content: "\e227"; } } +.glyphicon-btc { &:before { content: "\e227"; } } +.glyphicon-xbt { &:before { content: "\e227"; } } +.glyphicon-yen { &:before { content: "\00a5"; } } +.glyphicon-jpy { &:before { content: "\00a5"; } } +.glyphicon-ruble { &:before { content: "\20bd"; } } +.glyphicon-rub { &:before { content: "\20bd"; } } +.glyphicon-scale { &:before { content: "\e230"; } } +.glyphicon-ice-lolly { &:before { content: "\e231"; } } +.glyphicon-ice-lolly-tasted { &:before { content: "\e232"; } } +.glyphicon-education { &:before { content: "\e233"; } } +.glyphicon-option-horizontal { &:before { content: "\e234"; } } +.glyphicon-option-vertical { &:before { content: "\e235"; } } +.glyphicon-menu-hamburger { &:before { content: "\e236"; } } +.glyphicon-modal-window { &:before { content: "\e237"; } } +.glyphicon-oil { &:before { content: "\e238"; } } +.glyphicon-grain { &:before { content: "\e239"; } } +.glyphicon-sunglasses { &:before { content: "\e240"; } } +.glyphicon-text-size { &:before { content: "\e241"; } } +.glyphicon-text-color { &:before { content: "\e242"; } } +.glyphicon-text-background { &:before { content: "\e243"; } } +.glyphicon-object-align-top { &:before { content: "\e244"; } } +.glyphicon-object-align-bottom { &:before { content: "\e245"; } } +.glyphicon-object-align-horizontal{ &:before { content: "\e246"; } } +.glyphicon-object-align-left { &:before { content: "\e247"; } } +.glyphicon-object-align-vertical { &:before { content: "\e248"; } } +.glyphicon-object-align-right { &:before { content: "\e249"; } } +.glyphicon-triangle-right { &:before { content: "\e250"; } } +.glyphicon-triangle-left { &:before { content: "\e251"; } } +.glyphicon-triangle-bottom { &:before { content: "\e252"; } } +.glyphicon-triangle-top { &:before { content: "\e253"; } } +.glyphicon-console { &:before { content: "\e254"; } } +.glyphicon-superscript { &:before { content: "\e255"; } } +.glyphicon-subscript { &:before { content: "\e256"; } } +.glyphicon-menu-left { &:before { content: "\e257"; } } +.glyphicon-menu-right { &:before { content: "\e258"; } } +.glyphicon-menu-down { &:before { content: "\e259"; } } +.glyphicon-menu-up { &:before { content: "\e260"; } } diff --git a/rql-ui/src/sass/_icons-styles.scss b/rql-ui/src/sass/_icons-styles.scss new file mode 100644 index 0000000..74454db --- /dev/null +++ b/rql-ui/src/sass/_icons-styles.scss @@ -0,0 +1,54 @@ +@import url(http://weloveiconfonts.com/api/?family=brandico|entypo|fontelico|iconicfill|iconicstroke|maki|openwebicons|typicons|zocial); + +/* brandico */ +[class*="brandico-"]:before { + font-family: 'brandico', sans-serif; + font-style: normal; +} + +/* entypo */ +[class*="entypo-"]:before { + font-family: 'entypo', sans-serif; + font-style: normal; +} + +/* fontelico */ +[class*="fontelico-"]:before { + font-family: 'fontelico', sans-serif; + font-style: normal; +} + +/* iconicfill */ +[class*="iconicfill-"]:before { + font-family: 'IconicFill', sans-serif; + font-style: normal; +} + +/* iconicstroke */ +[class*="iconicstroke-"]:before { + font-family: 'IconicStroke', sans-serif; + font-style: normal; +} + +/* maki */ +[class*="maki-"]:before { + font-family: 'maki', sans-serif; + font-style: normal; +} + +/* openwebicons */ +[class*="openwebicons-"]:before { + font-family: 'OpenWeb Icons', sans-serif; + font-style: normal; +} + +/* typicons */ +[class*="typicons-"]:before { + font-family: 'Typicons', sans-serif; + font-style: normal; +} + +/* zocial */ +[class*="zocial-"]:before { + font-family: 'zocial', sans-serif; +} diff --git a/rql-ui/src/sass/_icons.scss b/rql-ui/src/sass/_icons.scss new file mode 100644 index 0000000..c8595d4 --- /dev/null +++ b/rql-ui/src/sass/_icons.scss @@ -0,0 +1,76 @@ +.i-nav-notification { + display: inline-block; + height: 32px; + width: 22px; + background: url('assets/icons/nav-notification.png') no-repeat center center; +} + +.i-nav-messages { + display: inline-block; + height: 21px; + width: 26px; + background: url('assets/icons/nav-messages.png') no-repeat center center; +} + +.i-vuestic { + display: inline-block; + width: 129px; + height: 15.4px; + background: url('assets/icons/vuestic.svg') no-repeat center center; +} + +.i-menu-expanded { + display: inline-block; + width: 24px; + height: 20px; + background: url('assets/icons/menu-expanded.svg') no-repeat center center; +} + +.i-menu-collapsed { + display: inline-block; + width: 24px; + height: 20px; + background: url('assets/icons/menu-collapsed.svg') no-repeat center center; +} + +.i-vuestic-fresh { + display: inline-block; + width: 51px; + height: 48px; + background: url('assets/icons/vuestic-fresh.svg') no-repeat center center; +} + +.i-vuestic-clean-code { + display: inline-block; + width: 56px; + height: 50px; + background: url('assets/icons/vuestic-clean-code.svg') no-repeat center center; +} + +.i-vuestic-free { + display: inline-block; + width: 45px; + height: 51px; + background: url('assets/icons/vuestic-free.svg') no-repeat center center; +} + +.i-vuestic-responsive { + display: inline-block; + width: 47.5px; + height: 49px; + background: url('assets/icons/vuestic-responsive.svg') no-repeat center center; +} + +.i-vuestic-rich { + display: inline-block; + width: 57px; + height: 55px; + background: url('assets/icons/vuestic-rich.svg') no-repeat center center; +} + +.i-vuestic-vue { + display: inline-block; + width: 55px; + height: 47.8px; + background: url('assets/icons/vuestic-vue.svg') no-repeat center center; +} diff --git a/rql-ui/src/sass/_material-forms.scss b/rql-ui/src/sass/_material-forms.scss new file mode 100644 index 0000000..c7bb104 --- /dev/null +++ b/rql-ui/src/sass/_material-forms.scss @@ -0,0 +1,357 @@ +$shadow-inset: inset 0 2px 2px 0 rgba(0,0,0,.14); +$shadow-0: 0 0 1px rgba(0, 0, 0, 0); +$shadow-2: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12); +$shadow-3: 0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12); +$shadow-4: 0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2); +$shadow-6: 0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2); +$shadow-8: 0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2); + +// Font Sizes +$mf-font-size: 1rem !default; +$mf-active-font-size: $mf-font-size * 0.6 !default; +$mf-active-top: -$mf-font-size * 0.6 !default; + +// Margin & Paddings +$mf-gap: $mf-font-size * 1.5 !default; +$mf-min-height: 2.25rem; +$mf-spacer: $mf-font-size / 8 !default; +$mf-fieldset-margin: 0 0 $mf-gap * 2 !default; +$mf-checkbox-gap: $mf-font-size * 2 !default; +$mf-checkbox-top: 0 !default; +$mf-radio-margin: $mf-font-size / -4 !default; +$mf-icon-gutter: 1.375rem; +$mf-icon-top: 0.4375rem; + + // Colors +$mf-input-color: $body-color !default; +$mf-border-color: #999 !default; +$mf-label-color: lighten($mf-border-color, 10%) !default; +$mf-active-color: darken($mf-border-color, 10%) !default; +$mf-focus-color: $brand-primary !default; +$mf-error-color: $brand-danger !default; +$mf-focus-border-color: $charcoal !default; + +// Animation +$mf-transition-speed: 0.28s !default; + + +.button-container { + text-align: center; +} + +// The Styles for the form +fieldset { + //margin: $mf-fieldset-margin; + padding: 0; + border: none; +} + +.form-group { + position: relative; + display: flex; + flex-direction: row; + min-height: $mf-min-height; + margin-top: ($mf-font-size * 0.2); + margin-bottom: ($mf-gap * 1.5); + + .input-group { + align-self: flex-end; + } + + .input-icon { + position: absolute; + top: $mf-icon-top; + color: $mf-label-color; + } + + @include text-emphasis-variant(".text-secondary", $mf-label-color); + + .input-group { + position: relative; + display: block; + } + + &.select-form-group { + .dropdown-toggle::after { + display: none; + } + + .dropdown-menu { + width: 100%; + } + + .dropdown-item { + cursor: pointer; + justify-content: space-between; + + .selected-icon { + display: none; + margin-left: 0.35rem; + } + + &.selected { + color: $mf-focus-color; + + .selected-icon { + display: inline-block; + } + } + } + + .input-icon { + color: $mf-active-color; + font-size: 0.8rem; + top: 1rem; + } + + .bar::before { + display: none; + } + } + + &.form-group-w-btn { + .btn { + align-self: flex-end; + } + } + + &.with-icon-right { + input { + padding-right: $mf-icon-gutter; + } + + .icon-right { + right: 0; + } + } + + &.with-icon-left { + input, + textarea + { + padding-left: $mf-icon-gutter; + + ~ .control-label { + padding-left: $mf-icon-gutter; + } + } + + select, + input:focus, + input:valid, + input.form-file, + input.has-value, + textarea:focus, + textarea:valid, + textarea.form-file, + textarea.has-value { + color: $mf-input-color; + + ~ .control-label { + padding-left: 0; + } + } + + .icon-left { + left: 0; + } + } + + .error-icon, .valid-icon { + display: none; + } +} + +.form-inline { + > .form-group, + > .btn { + display: inline-block; + margin-bottom: 0; + } +} + +.form-help { + margin-top: $mf-spacer; + margin-left: $mf-spacer; + color: $mf-label-color; + font-size: $mf-active-font-size; + + .form-group & { + position: absolute; + width: 100%; + } + + .checkbox & { + position: relative; + margin-bottom: $mf-font-size; + } +} + +.form-group { + // scss-lint:disable QualifyingElement, NestingDepth + input, textarea.chat { + height: ($mf-font-size * 1.9); + } + + textarea { + resize: none; + } + + select { + width: 100%; + font-size: $mf-font-size; + height: ($mf-font-size * 1.6); + padding: $mf-spacer $mf-spacer ($mf-spacer / 2); + background: none; + border: none; + line-height: 1.6; + box-shadow: none; + } + + .control-label { + position: absolute; + top: ($mf-font-size / 4); + left: 0; + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + pointer-events: none; + padding-left: $mf-spacer; + z-index: 1; + color: $mf-label-color; + font-size: $mf-font-size; + font-weight: normal; + transition: all $mf-transition-speed ease; + } + + .bar { + position: relative; + border-bottom: ($mf-font-size / 16) solid $mf-border-color; + display: block; + + &::before { + content: ''; + height: ($mf-font-size / 8); + width: 0; + left: 50%; + bottom: ($mf-font-size / -16); + position: absolute; + background: $mf-focus-border-color; + transition: left $mf-transition-speed ease, width $mf-transition-speed ease; + z-index: 2; + } + } + + input, + textarea { + display: block; + background: none; + padding: $mf-spacer $mf-spacer ($mf-spacer / 2); + font-size: $mf-font-size; + border-width: 0; + border-color: transparent; + line-height: 1.9; + width: 100%; + color: transparent; + transition: all $mf-transition-speed ease; + box-shadow: none; + } + + input[type="file"] { + line-height: 1; + + ~ .bar { + display: none; + } + } + + &.show input, + select, + input:focus, + input:valid, + input.form-file, + input.has-value, + textarea:focus, + textarea:valid, + textarea.form-file, + textarea.has-value { + color: $mf-input-color; + + ~ .control-label { + font-size: $mf-active-font-size; + color: $mf-focus-color; + font-weight: 600; + text-transform: uppercase; + top: $mf-active-top; + left: 0; + } + } + + select, + input, + textarea { + &:focus { + outline: none; + + ~ .control-label { + color: $mf-focus-color; + } + + ~ .bar { + &::before { + width: 100%; + left: 0; + } + } + } + } +} + +.valid { + .legend.legend, + &.form-group .control-label.control-label { + // Prevent !importantRule + color: $mf-focus-color; + } + + .valid-icon { + display: inline-block; + color: $mf-focus-color; + } +} + +.has-error { + .legend.legend, + &.form-group .control-label.control-label { + // Prevent !importantRule + color: $mf-error-color; + } + + .error-icon { + display: inline-block; + color: $mf-error-color; + } + + &.form-group { + .icon-right { + color: $mf-error-color; + } + } + + &.form-group, + &.checkbox { + .form-help, + .helper { + color: $mf-error-color; + } + } + + .bar { + &::before { + background: $mf-error-color; + left: 0; + width: 100%; + } + } +} diff --git a/rql-ui/src/sass/_mixins.scss b/rql-ui/src/sass/_mixins.scss new file mode 100644 index 0000000..2997700 --- /dev/null +++ b/rql-ui/src/sass/_mixins.scss @@ -0,0 +1,59 @@ +@mixin theme-button-variant($color, $background, $border, $shadow) { + $hover-bg: lighten($background, 10%); + $disabled-bg: darken($background, 15%); + $active-bg: darken($background, 15%); + $disabled-color: darken($background, 30%); + + background-color: $background; + color: $color; + box-shadow: $shadow; + border: $border; + + &:hover{ + color: $color; + background-color: $hover-bg; + } + + &.active, + &:active, + &:not([disabled]):not(.disabled):active, + &:not([disabled]):not(.disabled).active { + background-color: $active-bg; + box-shadow: $shadow; + color: $color; + + &:focus { + box-shadow: $shadow; + } + } + + &[disabled], &[disabled]:hover { + background-color: $disabled-bg; + color: $disabled-color; + opacity: 0.5; + } +} + +@mixin circle-progress-bar($progressColor, $size, $width, $startColor: $gray-lighter, $innerColor: $white) { + + + $step: 1; + $loops: round(100 / $step); + $increment: 360 / $loops; + $half: round($loops / 2); + + @for $i from 0 through $loops { + &.progress-bar.value-#{$i*$step} { + @if $i < $half { + $nextdeg: 90deg + ( $increment * $i ); + background-image: linear-gradient(90deg, $startColor 50%, transparent 50%, transparent), + linear-gradient($nextdeg, $progressColor 50%, $startColor 50%, $startColor); + } + @else { + $nextdeg: -90deg + ( $increment * ( $i - $half ) ); + background-image: linear-gradient($nextdeg, $progressColor 50%, transparent 50%, transparent), + linear-gradient(270deg, $progressColor 50%, $startColor 50%, $startColor); + } + } + } +} diff --git a/rql-ui/src/sass/_override-bootstrap.scss b/rql-ui/src/sass/_override-bootstrap.scss new file mode 100644 index 0000000..ac60bec --- /dev/null +++ b/rql-ui/src/sass/_override-bootstrap.scss @@ -0,0 +1,465 @@ +//Navbar +.navbar .navbar-nav > .nav-item > .nav-link { + padding-right: 38px; + padding-left: 38px; + line-height: 0; +} + +.navbar .navbar-nav > .nav-item { + display: flex; + align-items: center; +} + +//Typography +h1, .h1 { + margin-bottom :2.25rem; +} +h2, .h2 { + margin-bottom :2rem; +} +h3, .h3 { + margin-bottom :1.5rem; +} +h4, .h4 { + margin-bottom :1rem; +} + +.blockquote { + padding: 0 ($spacer *1.625); + margin: 2.5rem 0 2.5rem 1rem; + border-left: $blockquote-border-width solid $blockquote-border-color; + line-height: 2rem; + color: $blockquote-small-color; + font-style: oblique; +} + +.blockquote-footer { + &::before { + content: "--- "; // em dash, nbsp + } +} + + + +//Buttons + +.btn { + box-shadow: $btn-box-shadow; + font-family: inherit; + letter-spacing: 3px; + text-transform: uppercase; + cursor: pointer; + + &.dropdown-toggle.theme-toggle { + @include button-size($btn-padding-y, $btn-padding-x, $font-size-base, $btn-line-height, $btn-border-radius); + } + + &:focus, &:active, &.focus { + box-shadow: $btn-box-shadow; + } +} + +.btn.btn-sm { + @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $font-size-base, $btn-line-height-sm, $btn-border-radius); +} + +.btn.btn-micro { + @include button-size($btn-padding-y-micro, $btn-padding-x-micro, $font-size-smaller, $btn-line-height-sm, $btn-border-radius); +} + +.btn.btn-primary { + @include theme-button-variant($white, theme-color("primary"), $btn-border, $btn-box-shadow); + + &.hover { + background-color: lighten(theme-color("primary"), 10%) !important; + color: $white; + } + + &.focus { + background-color: darken(theme-color("primary"), 15%); + color: $white; + } +} + +.btn.btn-secondary { + @include theme-button-variant($white, theme-color("primary"), $btn-secondary-theme-border, none); + + color: theme-color("primary"); + border: $btn-secondary-theme-border; + background-color: $white; + + &[disabled], &[disabled]:hover { + background-color: $white; + color: theme-color("primary"); + border: 2px solid theme-color("primary"); + } + + &:hover { + border: 2px solid lighten(theme-color("primary"), 10%); + } + + &.hover { + border: 2px solid lighten(theme-color("primary"), 10%) !important; + background-color: lighten(theme-color("primary"), 10%) !important; + color: $white; + } + + &:active, &:focus, &.focus { + border: 2px solid darken(theme-color("primary"), 15%) !important; + background-color: darken(theme-color("primary"), 15%) !important; + color: $white; + } + +} + +.btn.btn-danger { + @include theme-button-variant($white, theme-color("danger"), $btn-border, $btn-box-danger-shadow); +} + +.btn.btn-warning { + @include theme-button-variant($white, theme-color("warning"), $btn-border, $btn-box-warning-shadow); +} + +.btn.btn-info { + @include theme-button-variant($white, theme-color("info"), $btn-border, $btn-box-info-shadow); + } + +.btn.btn-success { + @include theme-button-variant($white, theme-color("primary"), $btn-border, $btn-box-success-shadow); +} + +.btn.btn-dark { + @include theme-button-variant($white, theme-color("dark"), $btn-border, $btn-box-dark-shadow); +} + +.btn.btn-pale { + @include theme-button-variant($white, theme-color("pale"), $btn-border, $btn-box-pale-shadow); + &:hover { + background-color: lighten(theme-color("pale"), 5%); + &:focus, &:active, &.active { + background-color: darken(theme-color("pale"), 15%); + } + } +} + +.btn.btn-with-icon { + position: relative; + padding: $btn-padding-y $btn-with-icon-padding-x; + .btn-with-icon-content { + display: flex; + align-items: center; + justify-content: center; + margin-left: $btn-with-icon-text-margin; + } + + i { + position: absolute; + left: $btn-with-icon-padding-x; + top: $btn-with-icon-icon-top; + font-size: $btn-with-icon-icon-size; + } + + &.rounded-icon { + width: $btn-with-icon-rounded-size; + height: $btn-with-icon-rounded-size; + border-radius: 50%; + padding: 0; + + i { + left: $btn-with-icon-rounded-icon-left; + } + + &.btn-micro { + height: $btn-with-icon-rounded-size-micro; + width: $btn-with-icon-rounded-size-micro; + flex: none; + + i { + font-size: $btn-with-icon-rounded-font-micro; + left: $btn-with-icon-rounded-position-left; + top: $btn-with-icon-rounded-position-top; + } + } + } +} + +.btn-group { + box-shadow: $btn-box-shadow; + border-radius: $btn-border-radius; + .btn { + padding-left: $btn-group-button-padding-x; + padding-right: $btn-group-button-padding-x; + box-shadow: none; + } +} + +.btn.dropdown-toggle { + position: relative; + + .arrow-down { + position: absolute; + font-size: $btn-dd-arrow-size; + right: 1rem; + top: calc(50% - #{$btn-dd-arrow-size}/1.4); + } + + &::after { + display: none; + } +} + +.btn-group { + color: $white; +} + +// Dropdowns & Selects +.dropdown-menu { + border-radius: 0; + padding: $dropdown-menu-padding-y $dropdown-menu-padding-x; + background: transparent; + border: none; + .dropdown-menu-content{ + background-color: $dropdown-background; + box-shadow: $dropdown-box-shadow; + } +} + +.dropdown-item { + display: flex; + flex-direction: row; + align-items: center; + height: $dropdown-item-height; + font-size: $font-size-sm; +} + +//Grid + +.row > .col-8-custom { + @include media-breakpoint-between(md, xl) { + width: 12.5%; + } + + @include media-breakpoint-only(sm) { + width: 25%; + } + + @include media-breakpoint-only(xs){ + width: 100%; + } +} + +//Icons +.error-icon { + display: inline-block; + color: $theme-red; +} + +.success-icon { + display: inline-block; + color: $vue-green; +} + +//Tables +.table-striped { + tbody tr:nth-of-type(odd) { + background-color: $striped-row-odd; + } + tbody tr:nth-of-type(even) { + background-color: $striped-row; + } +} + +.table { + + thead tr { + border-bottom: 2px solid rgb(85, 85, 85); + color: $vue-green; + font-size: 14px; + font-weight: bold; + text-transform: uppercase; + } + + td, th, thead th, thead td { + border: none; + vertical-align: middle !important; + padding: .5rem; + } + + .badge { + vertical-align: text-top; + } + + .table-info { + background-color: #dcf1ff; + } + + .table-warning { + background-color: #fff1c8; + } + + .table-success, .table-success > td, .table-success > th { + background-color: #c8fac6; + } + + .table-danger { + background-color: #ffcece; + } + +} + +.first-td-padding { + td:first-child { + @extend .pl-4; + } +} + +.sort-icon { + float: none !important; + margin-left: .2rem; + top: 1px; + font-size: 1rem; +} + +th.sortable:hover { + color: $vue-green !important; + opacity: .6; +} + +//Badges +@mixin badge-variant($bg) { + color: $white; + background-color: $bg; + + &[href] { + @include hover-focus { + color: $white; + text-decoration: none; + background-color: darken($bg, 10%); + } + } +} + +.badge { + min-width: $badge-min-width; + display: inline-block; + font-weight: bold; + text-transform: uppercase; + font-size: .625rem; + color: $white; + letter-spacing: .0625rem; +} + +.badge-violet { + @include badge-variant($theme-violet); +} + +.badge-dark-blue { + @include badge-variant($dark-blue); +} + +.badge-success { + @include badge-variant($badge-success-bg); +} + +//Alerts + +.alert { + position: relative; + display: flex; + flex-direction: row; + align-items: center; + + .badge { + margin-right: 0.63rem; + } + + &.with-close { + padding-right: $with-close-pr; + } + + .alert-close { + position: absolute; + right: 20px; + font-size: $font-size-base; + top: calc(50% - #{$font-size-base}/2); + cursor: pointer; + } +} + +.alert-success { + box-shadow: $alert-success-shadow; + + .alert-close { + color: $brand-primary; + } +} + +.alert-warning { + box-shadow: $alert-warning-shadow; + + .alert-close { + color: $brand-warning; + } +} + +.alert-danger { + box-shadow: $alert-danger-shadow; + + .alert-close { + color: $brand-danger; + } +} + +.alert-info { + box-shadow: $alert-info-shadow; + + .alert-close { + color: $brand-info; + } +} + +@function get-alert-def($type, $csspart) { + @if $csspart == 'bg' { + @if $type == 'success' { + @return $alert-success-bg; + } @else if $type == 'danger' { + @return $alert-danger-bg; + } @else if $type == 'warning' { + @return $alert-warning-bg; + } @else if $type == 'info' { + @return $alert-info-bg; + } + + @return theme-color-level($type, -10); + } @else if $csspart == 'border' { + @if $type == 'success' { + @return $alert-success-border; + } @else if $type == 'danger' { + @return $alert-danger-border; + } @else if $type == 'warning' { + @return $alert-warning-border; + } @else if $type == 'info' { + @return $alert-info-border; + } + + @return theme-color-level($type, -9); + } @else if $csspart == 'color' { + @if $type == 'success' { + @return $alert-success-text; + } @else if $type == 'danger' { + @return $alert-danger-text; + } @else if $type == 'warning' { + @return $alert-warning-text; + } @else if $type == 'info' { + @return $alert-info-text; + } + + @return theme-color-level($type, 6); + } +} + +@each $color, $value in $theme-colors { + .alert-#{$color} { + @include alert-variant(get-alert-def($color, 'bg'), get-alert-def($color, 'border'), get-alert-def($color, 'color')); + } +} diff --git a/rql-ui/src/sass/_override-custom-libs.scss b/rql-ui/src/sass/_override-custom-libs.scss new file mode 100644 index 0000000..182af56 --- /dev/null +++ b/rql-ui/src/sass/_override-custom-libs.scss @@ -0,0 +1,167 @@ +.abc-checkbox, .abc-radio { + margin-bottom: 20px; + + label { + .abc-label-text { + display: inline-block; + position: relative; + top: 2px; + padding-left: 13px; + } + + &::before{ + width: 22px; + height: 22px; + border: 2px solid $input-border-color; + @include transition(border 0.15s ease-in-out, color 0.15s ease-in-out, background-color 0.15s ease-in-out); + } + + } +} + +.abc-checkbox { + padding-left: 20px; + + label{ + &::before{ + border-radius: 0; + @include transition(border 0.15s ease-in-out, color 0.15s ease-in-out, background-color 0.15s ease-in-out); + } + + &::after { + width: 20px; + height: 20px; + top: 2px; + left: 2px; + } + } + + input[type="checkbox"], + input[type="radio"] { + + &:focus + label::before{ + outline: none; + } + + + &:checked + label::after{ + font-family: "Ionicons"; + content: "\F2BC"; + font-size: 15px; + } + + &:disabled + label{ + opacity: 0.5; + } + } +} + +.abc-radio { + + label { + + &::after { + width: 10px; + height: 10px; + top: 7.5px; + left: 6px; + } + } + + input[type="radio"] { + + &:focus + label::before { + outline: none; + } + } +} + +//Medium Editor +.medium-editor-toolbar, +.medium-editor-toolbar-form, +.medium-editor-toolbar-actions, +.medium-editor-toolbar-anchor-preview { + background-color: $brand-primary; + border-radius: $btn-border-radius; + box-shadow: $btn-box-shadow; +} + +.medium-editor-toolbar { + max-width: 80%; + box-shadow: none; + .medium-editor-toolbar-actions { + overflow: hidden; + } + + .medium-editor-action { + @extend .btn.btn-primary; + height: $medium-editor-button-size; + padding: $btn-padding-y $btn-group-button-padding-x; + box-shadow: none; + border-radius: 0; + + &.medium-editor-button-active { + background-color: darken($brand-primary, 15%); + } + } +} + +.medium-editor-toolbar-form { + color: $white; + overflow: hidden; + + .medium-editor-toolbar-input { + height: $medium-editor-button-size; + background: $brand-primary; + box-sizing: border-box; + color: $white; + padding-left: 16px; + width: 220px; + + &::-webkit-input-placeholder { + color: rgba($white, .8); + } + &:-moz-placeholder { /* Firefox 18- */ + color: rgba($white, .8); + } + &::-moz-placeholder { /* Firefox 19+ */ + color: rgba($white, .8); + } + &:-ms-input-placeholder { + color: rgba($white, .8); + } + } + + a { + color: $white; + transform: translateY(2px); + } + + .medium-editor-toolbar-close { + margin-right: 16px; + } +} + +.medium-toolbar-arrow-under:after { + border-color: $brand-primary transparent transparent transparent; + top: $medium-editor-button-size; +} + +.medium-toolbar-arrow-over:before { + border-color: transparent transparent $brand-primary transparent; +} + +.medium-editor-toolbar-anchor-preview { + @include button-size($btn-padding-y, $btn-padding-x, $font-size-base, $btn-line-height, $btn-border-radius); + .medium-editor-toolbar-anchor-preview { + margin: 0; + } +} + +.medium-editor-anchor-preview { + max-width: 50%; + a { + color: $white; + text-decoration: none; + } +} diff --git a/rql-ui/src/sass/_typography.scss b/rql-ui/src/sass/_typography.scss new file mode 100644 index 0000000..e4e0c03 --- /dev/null +++ b/rql-ui/src/sass/_typography.scss @@ -0,0 +1,113 @@ +h1, h2, h3, h4, h5, h6, strong, b { + font-weight: 600; +} + +.vue-highlighted-text { + background-color: $vue-turquoise; +} + +.vue-selected-text, ::selection { + background-color: $brand-primary; + color: $white; +} + +ul.vue-list-inner, ol.vue-list-inner { + li:first-child { + margin-top: 1.5rem; + } + + li:last-child { + padding-bottom: 0; + } +} + +ul.vue-unordered { + padding : 0; + list-style-type : none; + + ul { + padding : 0; + list-style-type : none; + } + + li { + padding-left : 1.563rem; + padding-bottom :1.5rem; + &::before { + content : ""; + display : inline-block; + width : 0.75rem; + height : 0.75rem; + position : relative; + right : 1.563rem; + top : 0.0625rem; + margin-right : -0.75em; + border-radius : 0.75rem; + background-color : $vue-green; + } + + li { + &::before { + background-color : $white; + border : 2.5px solid $vue-green; + } + } + } +} + +ol.vue-ordered { + padding : 0; + counter-reset : olCounter; + + li { + list-style : none; + padding-left : 1.563rem; + padding-bottom :1.5rem; + } + + > li:before { + counter-increment : olCounter; + content : counter(olCounter) ". "; + display : inline-block; + width : 0.75rem; + height : 0.75rem; + position : relative; + right : 1.563rem; + top : 0.0625rem; + margin-right : -0.75em; + } + + ul { + padding : 0; + list-style-type : none; + li { + padding-left : 1.563rem; + &::before { + content : ""; + display : inline-block; + width : 0.75rem; + height : 0.75rem; + position : relative; + right : 1.563rem; + top : 0.0625rem; + margin-right : -0.75em; + border-radius : 0.75rem; + background-color : $vue-green; + } + + } + } + +} + +.vue-misc { + margin-top: 5.625rem; + margin-bottom: 2rem; +} + +//Well +.well { + padding : 1.9rem 2.2rem 1.9rem 1.6rem; + // background-color : #f7f7f7; + background-color: $light-gray; +} diff --git a/rql-ui/src/sass/_variables.scss b/rql-ui/src/sass/_variables.scss new file mode 100644 index 0000000..3b1de52 --- /dev/null +++ b/rql-ui/src/sass/_variables.scss @@ -0,0 +1,348 @@ +// Colors // +$gray-light: #acb5be !default; +$light-gray: #eee; +$lighter-gray: #ddd; +$charcoal: #555; +$darkest-gray: #333; +$almost-black: #161616; +$vue-green: #4ae387; +$light-green: #c8f9c5; +$light-blue: #dcf1ff; +$light-yellow: #fff1c8; +$light-pink: #ffcece; +$vue-darkest-blue: #34495e; +$vue-turquoise: #dbf9e7; +$white: #fff; +$theme-red: #e34a4a; +$theme-orange: #f7cc36; +$theme-blue: #4ab2e3; +$theme-violet: #db76df; +$theme-pale: #d9d9d9; +$brand-primary: $vue-green !default; +$brand-danger: $theme-red; +$brand-warning: $theme-orange; +$brand-info: $theme-blue; +$brand-success: $vue-green; +$light-gray2: #eff4f5; +$dark-gray: #282828; +$gray: #adb3b9; +$violet: #db76df; +$dark-blue: #0045b6; +$breadcrumbs-gray: #b4b4b4; + +$colors-map: ( + brand-danger: $brand-danger, + brand-primary: $brand-primary, + brand-info: $brand-info, + brand-success: $brand-success, + brand-warning: $brand-warning, + black: black, + white: white, + lighter-gray: $lighter-gray +); + +$theme-colors: ( + "primary": $brand-primary, + "secondary": $white, + "success": $light-green, + "info": $brand-info, + "warning": $brand-warning, + "danger": $brand-danger, + "light": $light-gray2, + "dark": $almost-black, + "pale": $theme-pale +); + +// Layout // +$body-bg : $light-gray; +$top-nav-bg : $darkest-gray; +$body-color : $vue-darkest-blue !default; +$layout-padding : 24px; +$layout-padding-right : 44px; + +$top-nav-height : 72px; +$nav-padding-left : $layout-padding; +$nav-padding-right : $layout-padding-right; +$navbar-brand-container-left: 75px; + +$sidebar-bg : $darkest-gray; +$sidebar-width : 225px; +$sidebar-top : calc(#{$top-nav-height} + #{$layout-padding}); +$sidebar-left : $layout-padding; + +$content-wrap-ml : calc(#{$sidebar-left} + #{$sidebar-width} + 35px); +$content-wrap-pr : $layout-padding-right; +$content-wrap-pt : $layout-padding; +$content-wrap-pb : $layout-padding; + +$greeny-box-shadow: 0 4px 9.6px 0.4px rgba($vue-green, .5); + +$min-z-index : -1000; + +//Auth +$auth-wallpaper-ivuestic-h: 2.625rem; +$auth-wallpaper-oblique-line: $dark-gray; + +//Mobile Layout +$top-mobile-nav-height: 5.625rem; +$layout-mobile-padding: 0.1875rem; +$layout-mobile-padding-right: .375rem; + +$sidebar-mobile-width: calc(100% - #{$layout-mobile-padding-right}); +$sidebar-mobile-top: $top-mobile-nav-height+$layout-mobile-padding; +$sidebar-mobile-left: $layout-mobile-padding; +$content-mobile-wrap-margin: 1.125rem; +$sidebar-mobile-z-index: 1000; + +$content-mobile-wrap-pl: 1rem; +$content-mobile-wrap-pr : 1rem; +$content-mobile-wrap-pt : 2rem; +$content-mobile-wrap-pb : $layout-padding; +$content-mobile-wrap: $content-mobile-wrap-pt $content-mobile-wrap-pr $content-mobile-wrap-pb $content-mobile-wrap-pl; + +$nav-mobile-padding-h : .875rem; +$nav-mobile-pt: 3rem; +$nav-mobile-pb: 1.375rem; +$nav-mobile-brand-width: 4rem; +$nav-mobile-brand-top: .875rem; +$nav-mobile-brand-left: calc(50% - #{$nav-mobile-brand-width}); + +$droppdown-mobile-mp: 1.9375rem; +$dropdown-mobile-show-b: 2rem; + +//Auth mobile +$auth-mobile-nav-ivuestic-h: 1.5rem; +$auth-mobile-main-h: calc(100% - #{$top-mobile-nav-height}); +$auth-content-padding-t: 2.875rem; + + +// Typography +// ------------------------- + +//$text-color: $gray !default; + +$font-family-sans-serif : 'Source Sans Pro', sans-serif !default; + +$font-size-root : 16px; + +$font-size-base : 1rem !default; +$font-size-larger : 1.2rem; +$font-size-large : 1.5rem; +$font-size-mini : 0.8rem; + +$font-weight-bold : 700 !default; +$font-weight-semi-bold : 600 !default; +$font-weight-normal : 400 !default; +$font-weight-thin : 300 !default; +$font-weight-base : $font-weight-thin !default; + +$font-size-smaller : 85% !default; + +$font-size-h1 : 2.625rem !default; +$font-size-h2 : 2.25rem !default; +$font-size-h3 : 1.75rem !default; +$font-size-h4 : 1.375rem !default; + +$headings-line-height : 1 !default; + +$blockquote-border-color : $vue-green; +$blockquote-small-color: $gray-light; +$blockquote-border-width : 0.375rem; +$blockquote-font-size : 1.5rem; +//Navbar +$navbar-dd-item-height : 48px; + +//Breadcrumbs +$breadcrumbs-height : 54px; +$breadcrumbs-arrow-font: 0.7rem; +$breadcrumbs-arrow-content: "\f054"; + +//Sidebar +$sidebar-link-height : 64px; +$sidebar-submenu-link-height : 48px; +$sidebar-link-pl : 25px; +$sidebar-submenu-link-pl : 74px; +$sidebar-link-active-bg : $almost-black; +$sidebar-arrow-right : 16px; +$sidebar-menu-item-icon-size : 19px; +$sidebar-viewport-height: calc(100vh - #{$top-nav-height} - #{$content-wrap-pt} - #{$content-wrap-pb}); + +$sidebar-hidden-top : -150px; +$sidebar-hidden-top-mobile : $sidebar-mobile-top; +$sidebar-hidden-height-mobile: 0; +$sidebar-box-shadow: 0px 8px 14.72px 1.28px rgba(#65a977, 0.3); + +//Widgets +$widget-bg : $white; +$widget-padding : 1.5625rem; +$widget-larger-padding: 45px; +$widget-box-shadow : 0px 4px 70px -18px rgba(112, 112, 112, 1); +$widget-danger-shadow: 0px 4px 70px -16px $brand-danger; +$widget-info-shadow: 0px 4px 70px -16px $brand-info; +$widget-viewport-height : $sidebar-viewport-height; +$widget-header-border: 2px solid $light-gray; +$widget-header-height: 55px; +$widget-body-no-header-height: 100%; +$widget-body-with-header-height: calc(100% - #{$widget-header-height}); +$widget-mb: 1.875rem; +$info-widget-border: 0.5rem solid $brand-primary; + +// Links +$link-color: $brand-primary; +$link-hover-color: lighten($link-color, 10%); +$link-hover-decoration: none; + +//Buttons +$input-btn-border-width: 0px; +$btn-line-height: 1.25; +$btn-line-height-sm: $btn-line-height; +$btn-padding-x: 3.9rem; +$btn-padding-y: 1.1rem; +$btn-padding-y-sm: 0.7rem; +$btn-padding-x-sm: 2.5rem; +$btn-padding-y-micro: 0.625rem; +$btn-padding-x-micro: 1.8rem; +$btn-with-icon-text-margin: 1.875rem; +$btn-with-icon-padding-x: 2.8125rem; +$btn-with-icon-rounded-size: 3.5rem; +$btn-with-icon-rounded-size-micro: 2.25rem; +$btn-with-icon-rounded-font-micro: 1.5rem; +$btn-with-icon-rounded-position-top: .4rem; +$btn-with-icon-rounded-position-left: .46rem; +$btn-with-icon-icon-top: .75rem; +$btn-with-icon-rounded-icon-left: 1.23rem; +$btn-with-icon-icon-size: 2rem; +$btn-group-button-padding-x: 1.53rem; +$btn-box-shadow: $greeny-box-shadow; +$btn-box-danger-shadow: 0px 4px 70px -16px $brand-danger; +$btn-box-warning-shadow: 0px 4px 70px -16px $brand-warning; +$btn-box-success-shadow: $greeny-box-shadow; +$btn-box-info-shadow: 0px 4px 70px -16px $brand-info; +$btn-box-pale-shadow: 0px 4px 70px -16px $theme-pale; +$btn-box-dark-shadow: 0px 4px 70px -16px $almost-black; +$btn-border-radius: 1.875rem; +$btn-dark-color: $white; +$btn-dark-bg: $darkest-gray; +$btn-dark-border: $darkest-gray; +$btn-pale-bg: $theme-pale; +$btn-pale-color: $white; +$btn-dd-arrow-size: 1rem; +$btn-border: none; +$btn-secondary-theme-border: 2px solid $brand-primary; + +//Dropdowns +$dropdown-link-color : $white; +$dropdown-box-shadow : $greeny-box-shadow; +$dropdown-background: $darkest-gray; +$dropdown-link-color: $white; +$dropdown-link-hover-color: $white; +$dropdown-link-hover-bg: $almost-black; +$dropdown-link-active-color: $white; +$dropdown-link-active-bg: $almost-black; +$dropdown-item-padding-x: 25px; +$dropdown-item-padding-y: 0; +$dropdown-item-height: 40px; +$dropdown-menu-padding-y: 10px; +$dropdown-menu-padding-x: 0; +$dropdown-min-width: 15rem; +$dropdown-simple-visible-items: 4; +$dropdown-multi-visible-items: 4; +$dropdown-show-b: 1.125rem; + +//Modals +$modal-header-padding-x: $widget-padding; +$modal-header-padding-y: 0; +$modal-header-height: $widget-header-height; +$modal-header-border: $widget-header-border; +$modal-content-border-width: 0; +$modal-content-border-radius: 0; +$modal-inner-padding: 25px; +$modal-footer-btns-padding-bottom: 20px; +$modal-footer-btns-margin-x: 10px; +$modal-md: 650px; +$modal-lg: 850px; + +//Forms +$input-border-color: $lighter-gray; +$input-bg-disabled: $white; + +$vuestic-switch-bg: $brand-primary; +$vuestic-switch-padding: 0.313rem 2.375rem; +$vuestic-switch-border-size: 0.125rem; + +//Progress Bars +$progress-bar-value-font-size: 0.6875rem; +$progress-bar-circle-diameter: 3.125rem; +$progress-bar-circle-bw: .0678rem; +$progress-bar-circle-overlay-diameter: calc(#{$progress-bar-circle-diameter} - 2*#{$progress-bar-circle-bw}); +$progress-bar-vertical-height: 5.75rem; +$progress-bar-width-thin: .125rem; +$progress-bar-width-basic: .5rem; +$progress-bar-width-thick: 1.5rem; + +//Tables +$table-bg-accent: $white; +$table-border-width: 0; +$table-border-color: #eceeef; +$striped-row-odd: $white; +$striped-row: $light-gray2; +$state-success-bg: #c8fac6; +$state-danger-bg: #ffcece; +$state-warning-bg: #fff1c8; +$state-info-bg: #dcf1ff; + +//Badges +$badge-padding-y: 0.28rem; +$badge-min-width: 5rem; +$badge-font-size: 0.7rem; +$badge-success-bg: $brand-success; +$badge-warning-bg: $theme-orange; +$badge-danger-bg: $theme-red; +$badge-info-bg: $theme-blue; + +//Alerts +$alert-padding-x: 1.25rem !default; +$alert-padding-y: .75rem !default; +$alert-margin-bottom: $widget-mb; +$with-close-pr: 3.125rem; + +$alert-border-radius: 0; +$alert-border-width: 0; + +$alert-success-bg: $light-green; +$alert-success-text: $body-color; +$alert-success-border: transparent; +$alert-success-shadow: 0px 4px 9.6px 0.4px rgba(79, 206, 145, 0.5); + +$alert-info-bg: $light-blue; +$alert-info-text: $body-color; +$alert-info-border: transparent; +$alert-info-shadow: 0px 4px 9.6px 0.4px rgba(79, 142, 206, 0.5); + +$alert-warning-bg: $light-yellow; +$alert-warning-text: $body-color; +$alert-warning-border: transparent; +$alert-warning-shadow: 0px 4px 9.6px 0.4px rgba(206, 178, 79, 0.5); + +$alert-danger-bg: $light-pink; +$alert-danger-text: $body-color; +$alert-danger-border: transparent; +$alert-danger-shadow: 0px 4px 9.6px 0.4px rgba(206, 79, 79, 0.5); + +//Icons +$bootstrap-sass-asset-helper: false; +$icon-font-name: 'glyphicons-halflings-regular'; +$icon-font-svg-id: 'glyphicons_halflingsregular'; +$icon-font-path: './fonts/'; + +//Tabs + +$tab-content-pt: 3.125rem; +$tab-content-pb: 1.5rem; + +//PreLoader +$vuestic-preloader-left: calc(50% - 140px/2); +$vuestic-preloader-top: calc(50% - 104px/2); + +//Medium Editor +$medium-editor-button-size: $btn-padding-y * 2 + $font-size-base * $btn-line-height; diff --git a/rql-ui/src/sass/main.scss b/rql-ui/src/sass/main.scss new file mode 100644 index 0000000..60ec4ad --- /dev/null +++ b/rql-ui/src/sass/main.scss @@ -0,0 +1,23 @@ +@import "~normalize.css"; + +@import "mixins"; +@import "variables"; +@import "fonts"; + +@import "~bootstrap/scss/bootstrap"; +@import "~font-awesome/css/font-awesome.css"; + +@import "~ionicons/dist/css/ionicons.css"; +@import "~awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.scss"; +@import "~medium-editor/src/sass/medium-editor"; +@import "_icons-styles.scss"; + +@import "base"; +@import "typography"; +@import "icons"; +@import "material-forms"; + +@import "override-bootstrap"; +@import "override-custom-libs"; + +@import "glyphicons"; diff --git a/rql-ui/static/.gitkeep b/rql-ui/static/.gitkeep new file mode 100644 index 0000000..e69de29