diff --git a/.gitattributes b/.gitattributes index 3ed770f0c..ec137c8c6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,6 +14,5 @@ *.tis text *.png binary *.jpg binary -*.sh text text +*.sh text eol=lf *.plist text eol=lf -*compile_shaders*.sh text eol=lf diff --git a/.gitignore b/.gitignore index ce627e7c1..d5023c5ff 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,5 @@ /_output/ *.pyc *.das.inl -*.sh.log +*.dshl.log ShaderLog-* diff --git a/DagorEngine.rev.txt b/DagorEngine.rev.txt index 79f0ff72c..946517a81 100644 --- a/DagorEngine.rev.txt +++ b/DagorEngine.rev.txt @@ -1 +1 @@ -7c0d114dca5d924ef032d22d724c67eaea1faf30 +5c60bace2d9f412c90ae821004b0c3ee648309e7 diff --git a/build_all.cmd b/build_all.cmd index b00208d08..7a1ff520f 100644 --- a/build_all.cmd +++ b/build_all.cmd @@ -14,6 +14,8 @@ pushd prog\tools\dargbox call create_vfsroms.bat cd shaders call compile_shaders_pc11.bat +call compile_shaders_metal.bat +call compile_shaders_spirV.bat popd pushd prog\samples\physTest @@ -21,6 +23,8 @@ jam jam -f jamfile-test-jolt cd shaders call compile_game_shaders-dx11.bat +call compile_game_shaders-metal.bat +call compile_game_shaders-spirv.bat popd pushd samples\skiesSample\prog @@ -28,6 +32,8 @@ jam cd shaders call compile_shaders_dx12.bat call compile_shaders_pc11.bat +call compile_shaders_metal.bat +call compile_shaders_spirv.bat call compile_shaders_tools.bat popd @@ -36,5 +42,7 @@ jam cd shaders call compile_shaders_dx12.bat call compile_shaders_pc11.bat +call compile_shaders_metal.bat +call compile_shaders_spirv.bat call compile_shaders_tools.bat popd diff --git a/build_all_linux.sh b/build_all_linux.sh new file mode 100644 index 000000000..ba36d0f79 --- /dev/null +++ b/build_all_linux.sh @@ -0,0 +1,20 @@ +pushd prog/tools +./build_dagor3_cdk_mini_linux.sh +popd + +pushd prog/tools/dargbox +../../../tools/dagor3_cdk/util-linux64/vromfsPacker-dev darg.vromfs.blk -platform:PC +popd + +pushd prog/samples/physTest +jam +jam -f jamfile-test-jolt +popd + +pushd samples/skiesSample/prog +jam +popd + +pushd samples/testGI/prog +jam +popd diff --git a/build_all_macOS.sh b/build_all_macOS.sh new file mode 100644 index 000000000..b9e847dd2 --- /dev/null +++ b/build_all_macOS.sh @@ -0,0 +1,20 @@ +pushd prog/tools +./build_dagor3_cdk_mini_macOS.sh +popd + +pushd prog/tools/dargbox +../../../tools/dagor3_cdk/util-macosx/vromfsPacker-dev darg.vromfs.blk -platform:PC +popd + +pushd prog/samples/physTest +jam +jam -f jamfile-test-jolt +popd + +pushd samples/skiesSample/prog +jam +popd + +pushd samples/testGI/prog +jam +popd diff --git a/prog/1stPartyLibs/daScript/daslib/is_local.das b/prog/1stPartyLibs/daScript/daslib/is_local.das index ecaefa6ab..798badf53 100644 --- a/prog/1stPartyLibs/daScript/daslib/is_local.das +++ b/prog/1stPartyLibs/daScript/daslib/is_local.das @@ -28,7 +28,7 @@ def is_shared_expr ( expr:ExpressionPtr ) return false elif expr is ExprAt let ea = expr as ExprAt - if ea.subexpr._type!=null && ea.subexpr._type.dim |> length!=0 + if ea.subexpr._type!=null && (ea.subexpr._type.baseType==Type tArray || ea.subexpr._type.isArray) return is_shared_expr(ea.subexpr) elif expr is ExprField let ef = expr as ExprField diff --git a/prog/1stPartyLibs/daScript/examples/test/main.cpp b/prog/1stPartyLibs/daScript/examples/test/main.cpp index 8a998a712..0b0cebabb 100644 --- a/prog/1stPartyLibs/daScript/examples/test/main.cpp +++ b/prog/1stPartyLibs/daScript/examples/test/main.cpp @@ -537,6 +537,7 @@ int main( int argc, char * argv[] ) { #endif uint64_t timeStamp = ref_time_ticks(); bool ok = true; + // ok = run_all_standalone_context_tests() && ok; ok = run_compilation_fail_tests(getDasRoot() + "/examples/test/compilation_fail_tests") && ok; ok = run_unit_tests(getDasRoot() + "/examples/test/unit_tests", true, false) && ok; ok = run_unit_tests(getDasRoot() + "/examples/test/optimizations", false, false) && ok; diff --git a/prog/1stPartyLibs/daScript/examples/test/unit_tests/lambda_capture_modes.das b/prog/1stPartyLibs/daScript/examples/test/unit_tests/lambda_capture_modes.das index 33f0eb83a..fb03d81e3 100644 --- a/prog/1stPartyLibs/daScript/examples/test/unit_tests/lambda_capture_modes.das +++ b/prog/1stPartyLibs/daScript/examples/test/unit_tests/lambda_capture_modes.das @@ -19,7 +19,7 @@ def test_delete assert ( pB==null ) invoke(lam) delete lam - assert(g_counter==2) // b and c were deleted, a stayed do to copy, not move, not clone + assert(g_counter==1) // only C was safe to delete return true diff --git a/prog/1stPartyLibs/daScript/include/daScript/simulate/aot_builtin_matrix.h b/prog/1stPartyLibs/daScript/include/daScript/simulate/aot_builtin_matrix.h index d268751cf..9de0be93e 100644 --- a/prog/1stPartyLibs/daScript/include/daScript/simulate/aot_builtin_matrix.h +++ b/prog/1stPartyLibs/daScript/include/daScript/simulate/aot_builtin_matrix.h @@ -33,8 +33,10 @@ namespace das { return ret; } float3x4 float3x4_neg ( const float3x4 & mat ); + float float3x4_det ( const float3x4 & mat ); float3x3 float3x3_inverse( const float3x3 & src); float3x3 float3x3_neg ( const float3x3 & mat ); + float float3x3_det ( const float3x3 & a ); float4x4 float4x4_from_float34 ( const float3x4 & mat ); float3x3 float3x3_from_float44 ( const float4x4 & mat ); float3x3 float3x3_from_float34 ( const float3x4 & mat ); @@ -70,6 +72,12 @@ namespace das { return v_mat44_mul_vec4(va, b); } + inline float float4x4_det(const float4x4 &a) { + mat44f va; + memcpy(&va,&a,sizeof(float4x4)); + return v_extract_x(v_mat44_det(va)); + } + inline float3 float3x3_mul_vec3(const float3x3 &a, float3 b) { mat33f va; va.col0 = a.m[0]; va.col1 = a.m[1]; va.col2 = a.m[2]; return v_mat33_mul_vec3(va, b); diff --git a/prog/1stPartyLibs/daScript/jamfile b/prog/1stPartyLibs/daScript/jamfile index 3ec1f728f..b8a751481 100644 --- a/prog/1stPartyLibs/daScript/jamfile +++ b/prog/1stPartyLibs/daScript/jamfile @@ -39,6 +39,11 @@ if $(daScript_trackAllocations) = 1 { CPPopt += -DDAS_TRACK_ALLOCATIONS=$(daScript_trackAllocations) ; } +if $(daScript_sanitizer) = 1 { + Target = $(Target:S=~sa$(daScript_sanitizer).lib) ; + CPPopt += -DDAS_SANITIZER=$(daScript_sanitizer) ; +} + if $(Platform) = macosx { CPPopt += -Wno-deprecated-declarations ; } diff --git a/prog/1stPartyLibs/daScript/src/ast/ast_generate.cpp b/prog/1stPartyLibs/daScript/src/ast/ast_generate.cpp index d0628036e..14994545b 100644 --- a/prog/1stPartyLibs/daScript/src/ast/ast_generate.cpp +++ b/prog/1stPartyLibs/daScript/src/ast/ast_generate.cpp @@ -456,6 +456,7 @@ namespace das { if ( !fl.type->constant && !fl.capturedConstant && fl.type->needDelete() ) { if ( !fl.doNotDelete && !fl.capturedRef ) { if ( fl.type->isPointer() && fl.type->firstType && fl.type->firstType->constant ) continue; + if ( ls->isLambda && !fl.type->isSafeToDelete() ) continue; // we don't do unsafe delete for lambda auto fva = make_smart(fl.at, "__this"); auto fld = make_smart(fl.at, fva, fl.name); fld->ignoreCaptureConst = true; diff --git a/prog/1stPartyLibs/daScript/src/ast/ast_infer_type.cpp b/prog/1stPartyLibs/daScript/src/ast/ast_infer_type.cpp index 37efde433..deff134d8 100644 --- a/prog/1stPartyLibs/daScript/src/ast/ast_infer_type.cpp +++ b/prog/1stPartyLibs/daScript/src/ast/ast_infer_type.cpp @@ -2758,31 +2758,49 @@ namespace das { if ( classDotMethod->rtti_isField() ) { auto eField = static_pointer_cast(classDotMethod); if ( eField->value->type && !eField->value->type->isAutoOrAlias() ) { + Structure * stt = nullptr; if ( eField->value->type->baseType==Type::tStructure ) { - auto stt = eField->value->type->structType; + stt = eField->value->type->structType; + } else if ( eField->value->type->baseType==Type::tPointer && eField->value->type->firstType && eField->value->type->firstType->baseType==Type::tStructure ) { + stt = eField->value->type->firstType->structType; + } + if ( stt ) { auto sttf = stt->findField(eField->name); if ( sttf ) { - if ( sttf->init && sttf->init->rtti_isAddr() ) { - auto fnAddr = static_pointer_cast(sttf->init); - if ( fnAddr->func ) { - int fnArgSize = int(fnAddr->func->arguments.size()); - int fromFnArgSize = int(expr->arguments.size()-1); - bool allHaveInit = true; - for ( int ai=fromFnArgSize; aifunc->arguments[ai]->init ) { - allHaveInit = false; - break; - } + if ( sttf->init ) { + smart_ptr fnAddr; + if ( sttf->init->rtti_isAddr() ) { + fnAddr = static_pointer_cast(sttf->init); + } else if ( sttf->init->rtti_isCast() ) { + auto cast = static_pointer_cast(sttf->init); + if ( cast->subexpr->rtti_isAddr() ) { + fnAddr = static_pointer_cast(cast->subexpr); } - if ( allHaveInit ) { + } + if ( fnAddr ) { + if ( fnAddr->func ) { + int fnArgSize = int(fnAddr->func->arguments.size()); + int fromFnArgSize = int(expr->arguments.size()-1); + bool allHaveInit = true; for ( int ai=fromFnArgSize; aiarguments.emplace_back(fnAddr->func->arguments[ai]->init->clone()); + if ( !fnAddr->func->arguments[ai]->init ) { + allHaveInit = false; + break; + } + } + if ( allHaveInit ) { + for ( int ai=fromFnArgSize; aiarguments.emplace_back(fnAddr->func->arguments[ai]->init->clone()); + } + reportAstChanged(); + return Visitor::visit(expr); } - reportAstChanged(); - return Visitor::visit(expr); + } else { + error(fnAddr->target + " is not fully resolved yet", "", "", + expr->at, CompilationError::invalid_argument_count); } } else { - error(fnAddr->target + " is not fully resolved yet", "", "", + error(fnAddr->target + " expecting class_ptr or cast class_ptr", "", "", expr->at, CompilationError::invalid_argument_count); } } else { diff --git a/prog/1stPartyLibs/daScript/src/ast/ast_parse.cpp b/prog/1stPartyLibs/daScript/src/ast/ast_parse.cpp index 6aec3777b..7ecd86c74 100644 --- a/prog/1stPartyLibs/daScript/src/ast/ast_parse.cpp +++ b/prog/1stPartyLibs/daScript/src/ast/ast_parse.cpp @@ -299,11 +299,9 @@ namespace das { int64_t file_mtime = access->getFileMtime(fileName.c_str()); int64_t saved_mtime = 0; *serializer_read << saved_mtime; + string saved_filename{}; *serializer_read << saved_filename; - string saved_filename; *serializer_read << saved_filename; - DAS_ASSERTF(saved_filename == fileName, "expected the same order of modules"); - - if ( file_mtime != saved_mtime ) { + if ( saved_filename != fileName || file_mtime != saved_mtime ) { serializer_read->seenNewModule = true; return false; } diff --git a/prog/1stPartyLibs/daScript/src/builtin/module_builtin_math.cpp b/prog/1stPartyLibs/daScript/src/builtin/module_builtin_math.cpp index 593099515..3babb9603 100644 --- a/prog/1stPartyLibs/daScript/src/builtin/module_builtin_math.cpp +++ b/prog/1stPartyLibs/daScript/src/builtin/module_builtin_math.cpp @@ -382,6 +382,11 @@ namespace das { return res; } + float float3x3_det ( const float3x3 & a ) { + mat33f va; va.col0 = a.m[0]; va.col1 = a.m[1]; va.col2 = a.m[2]; + return v_extract_x(v_mat33_det(va)); + } + float3x4 float3x4_neg ( const float3x4 & mat ) { float3x4 res; res.m[0] = v_neg(mat.m[0]); @@ -391,6 +396,12 @@ namespace das { return res; } + float float3x4_det ( const float3x4 & mat ) { + mat44f res; + v_mat44_make_from_43ca(res, (const float*)&mat); + return v_extract_x(v_mat44_det43(res)); + } + float4x4 float4x4_identity_m ( void ) { float4x4 mat; matrix_identity<4,4>((float*)&mat); @@ -753,6 +764,8 @@ namespace das { SideEffects::none,"float3x4_mul_vec3p")->args({"x","y"}); addExtern(*this, lib, "*", SideEffects::none,"float4x4_mul_vec4")->args({"x","y"}); + addExtern(*this, lib, "determinant", + SideEffects::none,"float4x4_det")->arg("x"); addExtern(*this, lib, "inverse", SideEffects::none, "float3x4_inverse")->arg("x"); addExtern(*this, lib, @@ -767,6 +780,8 @@ namespace das { SideEffects::none, "float3x4_nequ")->args({"x","y"}); addExtern(*this, lib, "-", SideEffects::none,"float3x4_neg")->arg("x"); + addExtern(*this, lib, "determinant", + SideEffects::none,"float3x4_det")->arg("x"); initFloatNxNIndex(addExtern)), SimNode_ExtFuncCallRef>(*this, lib, "[]", SideEffects::none, "floatNxN_ati")->args({"m","i","context","at"})); initFloatNxNIndex(addExtern)), SimNode_ExtFuncCallRef>(*this, lib, @@ -813,7 +828,9 @@ namespace das { SideEffects::none, "float3x3_nequ")->args({"x","y"}); addExtern(*this, lib, "-", SideEffects::none,"float3x3_neg")->arg("x"); - initFloatNxNIndex(addExtern)), SimNode_ExtFuncCallRef>(*this, lib, + addExtern(*this, lib, "-detertminant", + SideEffects::none,"float3x3_det")->arg("x"); + initFloatNxNIndex(addExtern)), SimNode_ExtFuncCallRef>(*this, lib, "[]", SideEffects::none, "floatNxN_ati")->args({"m","i","context","at"})); initFloatNxNIndex(addExtern)), SimNode_ExtFuncCallRef>(*this, lib, "[]", SideEffects::none, "floatNxN_atci")->args({"m","i","context","at"})); diff --git a/prog/1stPartyLibs/quirrel/quirrel/include/squirrel.h b/prog/1stPartyLibs/quirrel/quirrel/include/squirrel.h index 54852782f..53a35d152 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/include/squirrel.h +++ b/prog/1stPartyLibs/quirrel/quirrel/include/squirrel.h @@ -213,6 +213,20 @@ enum CompilationOptions : SQUnsignedInteger { #undef BIT +typedef struct tagSQCompilerMessage { + int intId; + const char* textId; + int line; + int column; + int columnsWidth; + const char* message; + const char* fileName; + bool isError; +} SQCompilerMessage; + +typedef void (*SQ_COMPILER_DIAG_CB)(HSQUIRRELVM v, const SQCompilerMessage *msg); + + /*vm*/ SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize); SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize); @@ -264,6 +278,7 @@ SQUIRREL_API SQBool sq_isvartracesupported(); SQUIRREL_API void sq_lineinfo_in_expressions(HSQUIRRELVM v, SQBool enable); SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable); SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f); +SQUIRREL_API void sq_setcompilerdiaghandler(HSQUIRRELVM v, SQ_COMPILER_DIAG_CB f); SQUIRREL_API SQCOMPILERERROR sq_getcompilererrorhandler(HSQUIRRELVM v); /*stack operations*/ @@ -425,12 +440,11 @@ SQUIRREL_API void sq_resetanalyzerconfig(); SQUIRREL_API bool sq_loadanalyzerconfig(const char *configFileName); SQUIRREL_API bool sq_loadanalyzerconfigblk(const KeyValueFile &config); -SQUIRREL_API bool sq_switchdiagnosticstate_t(const char *diagId, bool state); -SQUIRREL_API bool sq_switchdiagnosticstate_i(int32_t id, bool state); +SQUIRREL_API bool sq_setdiagnosticstatebyname(const char *diagId, bool val); +SQUIRREL_API bool sq_setdiagnosticstatebyid(int32_t id, bool val); SQUIRREL_API void sq_invertwarningsstate(); SQUIRREL_API void sq_printwarningslist(FILE *ostream); -SQUIRREL_API void sq_disablesyntaxwarnings(); -SQUIRREL_API void sq_enablesyntaxwarnings(); +SQUIRREL_API void sq_enablesyntaxwarnings(bool on); SQUIRREL_API void sq_checkglobalnames(HSQUIRRELVM v); SQUIRREL_API void sq_mergeglobalnames(const HSQOBJECT *bindings); @@ -468,7 +482,7 @@ SQUIRREL_API void sq_mergeglobalnames(const HSQOBJECT *bindings); #if defined(__GNUC__) || defined(__clang__) # define SQ_UNUSED_ARG(x) x __attribute__((__unused__)) #else -# define SQ_UNUSED_ARG(x) x +# define SQ_UNUSED_ARG(x) #endif #ifdef __cplusplus diff --git a/prog/1stPartyLibs/quirrel/quirrel/sq/sq.cpp b/prog/1stPartyLibs/quirrel/quirrel/sq/sq.cpp index a06893aea..10260991e 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/sq/sq.cpp +++ b/prog/1stPartyLibs/quirrel/quirrel/sq/sq.cpp @@ -43,7 +43,6 @@ SQInteger quit(HSQUIRRELVM v) void printfunc(HSQUIRRELVM SQ_UNUSED_ARG(v),const SQChar *s,...) { - (void)v; /* UNUSED */ va_list vl; va_start(vl, s); scvprintf(stdout, s, vl); @@ -54,7 +53,6 @@ static FILE *errorStream = stderr; void errorfunc(HSQUIRRELVM SQ_UNUSED_ARG(v),const SQChar *s,...) { - (void)v; /* UNUSED */ va_list vl; va_start(vl, s); scvprintf(errorStream, s, vl); @@ -240,7 +238,7 @@ int getargs(HSQUIRRELVM v,int argc, char* argv[],SQInteger *retval) bool flip_warnigns = false; if (static_analysis) { - sq_enablesyntaxwarnings(); + sq_enablesyntaxwarnings(true); } char * output = NULL; @@ -346,7 +344,7 @@ int getargs(HSQUIRRELVM v,int argc, char* argv[],SQInteger *retval) case 'W': if (isdigit(argv[arg][2])) { int id = atoi(&argv[arg][2]); - if (!sq_switchdiagnosticstate_i(id, false)) { + if (!sq_setdiagnosticstatebyid(id, false)) { printf("Unknown warning ID %s\n", &argv[arg][2]); } } @@ -364,7 +362,7 @@ int getargs(HSQUIRRELVM v,int argc, char* argv[],SQInteger *retval) } break; default: - if (static_analysis && isalpha(argv[arg][1]) && sq_switchdiagnosticstate_t(argv[arg] + 1, false)) { + if (static_analysis && isalpha(argv[arg][1]) && sq_setdiagnosticstatebyname(argv[arg] + 1, false)) { break; } unknown_opt: diff --git a/prog/1stPartyLibs/quirrel/quirrel/sqmodules/sqmodules.h b/prog/1stPartyLibs/quirrel/quirrel/sqmodules/sqmodules.h index 0f9dd4f0f..93c926176 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/sqmodules/sqmodules.h +++ b/prog/1stPartyLibs/quirrel/quirrel/sqmodules/sqmodules.h @@ -36,7 +36,7 @@ class SqModules compilationOptions.debugInfo = false; compilationOptions.doStaticAnalysis = false; compilationOptions.useAbsolutePath = false; - sq_disablesyntaxwarnings(); + sq_enablesyntaxwarnings(false); } HSQUIRRELVM getVM() { return sqvm; } diff --git a/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqapi.cpp b/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqapi.cpp index 974bd010f..f56a91ca8 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqapi.cpp +++ b/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqapi.cpp @@ -1401,6 +1401,11 @@ SQCOMPILERERROR sq_getcompilererrorhandler(HSQUIRRELVM v) return _ss(v)->_compilererrorhandler; } +void sq_setcompilerdiaghandler(HSQUIRRELVM v, SQ_COMPILER_DIAG_CB f) +{ + _ss(v)->_compilerdiaghandler = f; +} + SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up) { @@ -1876,12 +1881,12 @@ bool sq_loadanalyzerconfigblk(const KeyValueFile &config) { return SQCompilationContext::loadConfigFile(config); } -bool sq_switchdiagnosticstate_t(const char *diagId, bool state) { - return SQCompilationContext::switchDiagnosticState(diagId, state); +bool sq_setdiagnosticstatebyname(const char *diagId, bool state) { + return SQCompilationContext::enableWarning(diagId, state); } -bool sq_switchdiagnosticstate_i(int32_t id, bool state) { - return SQCompilationContext::switchDiagnosticState(id, state); +bool sq_setdiagnosticstatebyid(int32_t id, bool state) { + return SQCompilationContext::enableWarning(id, state); } void sq_invertwarningsstate() { @@ -1892,16 +1897,12 @@ void sq_printwarningslist(FILE *ostream) { SQCompilationContext::printAllWarnings(ostream); } -void sq_disablesyntaxwarnings() { - SQCompilationContext::switchSyntaxWarningsState(false); -} - -void sq_enablesyntaxwarnings() { - SQCompilationContext::switchSyntaxWarningsState(true); +void sq_enablesyntaxwarnings(bool on) { + SQCompilationContext::switchSyntaxWarningsState(on); } void sq_checkglobalnames(HSQUIRRELVM v) { - StaticAnalyzer::reportGlobalNameDiagnostics(v); + StaticAnalyzer::reportGlobalNamesWarnings(v); } void sq_mergeglobalnames(const HSQOBJECT *bindings) { diff --git a/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqcompilationcontext.cpp b/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqcompilationcontext.cpp index 308cf5bcb..cf90c3804 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqcompilationcontext.cpp +++ b/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqcompilationcontext.cpp @@ -253,8 +253,6 @@ bool SQCompilationContext::loadConfigFile(const char *configFile) { } bool SQCompilationContext::loadConfigFile(const KeyValueFile &config) { - - //for (auto && v : config.getValuesList("format_function_name")) //{ // string functionName(v); @@ -323,21 +321,6 @@ const char *SQCompilationContext::findLine(int lineNo) { return _linemap[lineNo]; } -static const char *strstr_nl(const char *str, const char *fnd) { - - int len = strlen(fnd); - - while (*str != '\0' && *str != '\n') { - if (*str == *fnd) { - if (strncmp(str, fnd, len) == 0) { - return str; - } - } - ++str; - } - - return nullptr; -} void SQCompilationContext::printAllWarnings(FILE *ostream) { for (auto &diag : diagnosticDescriptors) { @@ -357,7 +340,7 @@ void SQCompilationContext::flipWarningsState() { } } -bool SQCompilationContext::switchDiagnosticState(const char *diagName, bool state) { +bool SQCompilationContext::enableWarning(const char *diagName, bool state) { for (auto &diag : diagnosticDescriptors) { if (strcmp(diagName, diag.textId) == 0) { if (diag.severity != DS_ERROR) { @@ -369,7 +352,7 @@ bool SQCompilationContext::switchDiagnosticState(const char *diagName, bool stat return false; } -bool SQCompilationContext::switchDiagnosticState(int32_t id, bool state) { +bool SQCompilationContext::enableWarning(int32_t id, bool state) { for (auto &diag : diagnosticDescriptors) { if (id == diag.id) { if (diag.severity != DS_ERROR) { @@ -542,6 +525,20 @@ void SQCompilationContext::vreportDiagnostic(enum DiagnosticsId diagId, int32_t const char *msg = message.c_str(); + auto diagMsgFunc = _ss(_vm)->_compilerdiaghandler; + if (diagMsgFunc) { + SQCompilerMessage cm; + cm.intId = desc.id; + cm.textId = desc.textId; + cm.line = line; + cm.column = pos; + cm.columnsWidth = width; + cm.message = msg; + cm.fileName = _sourceName; + cm.isError = isError; + diagMsgFunc(_vm, &cm); + } + if (_raiseError && errorFunc) { errorFunc(_vm, msg, _sourceName, line, pos, extra); } diff --git a/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqcompilationcontext.h b/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqcompilationcontext.h index a99600ecb..df875a1cf 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqcompilationcontext.h +++ b/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqcompilationcontext.h @@ -241,8 +241,8 @@ class SQCompilationContext static void printAllWarnings(FILE *ostream); static void flipWarningsState(); - static bool switchDiagnosticState(const char *diagName, bool state); - static bool switchDiagnosticState(int32_t id, bool state); + static bool enableWarning(const char *diagName, bool state); + static bool enableWarning(int32_t id, bool state); static void switchSyntaxWarningsState(bool state); Arena *arena() const { return _arena; } diff --git a/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqstate.cpp b/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqstate.cpp index f80dc5ed7..b4c2f1ffa 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqstate.cpp +++ b/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqstate.cpp @@ -18,6 +18,7 @@ SQSharedState::SQSharedState(SQAllocContext allocctx) : defaultLangFeatures(0) { _compilererrorhandler = NULL; + _compilerdiaghandler = NULL; _printfunc = NULL; _errorfunc = NULL; _debuginfo = false; diff --git a/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqstate.h b/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqstate.h index 944ac8caa..dfcb34d42 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqstate.h +++ b/prog/1stPartyLibs/quirrel/quirrel/squirrel/sqstate.h @@ -122,6 +122,8 @@ struct SQSharedState SQCOMPILERERROR _compilererrorhandler; SQPRINTFUNCTION _printfunc; SQPRINTFUNCTION _errorfunc; + SQ_COMPILER_DIAG_CB _compilerdiaghandler; + bool _debuginfo; bool _notifyallexceptions; bool _lineInfoInExpressions; diff --git a/prog/1stPartyLibs/quirrel/quirrel/squirrel/static_analyzer/analyzer.cpp b/prog/1stPartyLibs/quirrel/quirrel/squirrel/static_analyzer/analyzer.cpp index 51d414177..49b32a769 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/squirrel/static_analyzer/analyzer.cpp +++ b/prog/1stPartyLibs/quirrel/quirrel/squirrel/static_analyzer/analyzer.cpp @@ -2115,7 +2115,7 @@ static bool isDivOperator(enum TreeOp op) { } bool isPureArithOperator(enum TreeOp op) { - return TO_USHR <= op && op <= TO_SUB || TO_PLUSEQ <= op && op <= TO_MODEQ; + return (TO_USHR <= op && op <= TO_SUB) || (TO_PLUSEQ <= op && op <= TO_MODEQ); } bool isRelationOperator(enum TreeOp op) { @@ -8012,15 +8012,6 @@ void NameShadowingChecker::visitFunctionDecl(FunctionDecl *f) { Visitor::visitFunctionDecl(f); } -static bool isFunctionDecl(const Expr *e) { - if (e->op() != TO_DECL_EXPR) - return false; - - const Decl *d = static_cast(e)->declaration(); - - return d->op() == TO_FUNCTION || d->op() == TO_CONSTRUCTOR; -} - void NameShadowingChecker::visitTableDecl(TableDecl *t) { Scope tableScope(this, t); @@ -8092,12 +8083,7 @@ void NameShadowingChecker::visitForeachStatement(ForeachStatement *stmt) { nodeStack.pop_back(); } -static bool checkInBindings(const SQChar *id) { - - return knownBindings.find(id) != knownBindings.end(); -} - -void StaticAnalyzer::reportGlobalNameDiagnostics(HSQUIRRELVM vm) { +void StaticAnalyzer::reportGlobalNamesWarnings(HSQUIRRELVM vm) { auto errorFunc = _ss(vm)->_compilererrorhandler; if (!errorFunc) @@ -8130,7 +8116,8 @@ void StaticAnalyzer::reportGlobalNameDiagnostics(HSQUIRRELVM vm) { for (auto it = usedGlobals.begin(); it != usedGlobals.end(); ++it) { const std::string &id = it->first; - if (checkInBindings(id.c_str())) + bool isKnownBinding = knownBindings.find(id) != knownBindings.end(); + if (isKnownBinding) continue; if (declaredGlobals.find(id) != declaredGlobals.end()) @@ -8184,8 +8171,7 @@ void StaticAnalyzer::mergeKnownBindings(const HSQOBJECT *bindings) { if (sq_isstring(key)) { SQInteger len = _string(key)->_len; const SQChar *s = _string(key)->_val; - std::string name(s); - knownBindings.emplace(name); + knownBindings.emplace(std::string(s, s+len)); } pos._unVal.nInteger = idx; } diff --git a/prog/1stPartyLibs/quirrel/quirrel/squirrel/static_analyzer/analyzer.h b/prog/1stPartyLibs/quirrel/quirrel/squirrel/static_analyzer/analyzer.h index c09da3bff..1a305212f 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/squirrel/static_analyzer/analyzer.h +++ b/prog/1stPartyLibs/quirrel/quirrel/squirrel/static_analyzer/analyzer.h @@ -17,7 +17,7 @@ class StaticAnalyzer { void runAnalysis(RootBlock *r, const HSQOBJECT *bindings); static void mergeKnownBindings(const HSQOBJECT *bindings); - static void reportGlobalNameDiagnostics(HSQUIRRELVM vm); + static void reportGlobalNamesWarnings(HSQUIRRELVM vm); static void checkTrailingWhitespaces(HSQUIRRELVM vm, const SQChar *sn, const SQChar *code, size_t codeSize); }; diff --git a/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/quirrel_static_analyzer.cpp b/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/quirrel_static_analyzer.cpp index d2d8c5f7e..550e49568 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/quirrel_static_analyzer.cpp +++ b/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/quirrel_static_analyzer.cpp @@ -3407,7 +3407,7 @@ class Analyzer } if (!!(flags & RT_NOTHING) && - !!(flags & (RT_NUMBER | RT_STRING | RT_TABLE | RT_CLASS | RT_ARRAY | RT_CLOSURE | RT_UNRECOGNIZED | RT_THROW))) + !!(flags & (RT_BOOL | RT_NUMBER | RT_STRING | RT_TABLE | RT_CLASS | RT_ARRAY | RT_CLOSURE | RT_UNRECOGNIZED | RT_THROW))) { if ((flags & RT_THROW) == 0) ctx.warning("all-paths-return-value", node->tok); diff --git a/prog/gameLibs/daSkies2/shaders/clouds_vars.sh b/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/tests/expected_fail/empty.txt similarity index 100% rename from prog/gameLibs/daSkies2/shaders/clouds_vars.sh rename to prog/1stPartyLibs/quirrel/quirrel/static_analyzer/tests/expected_fail/empty.txt diff --git a/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/tests/expected_fail/w239.nut b/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/tests/expected_fail/w239.nut index c32aef4fa..66827e838 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/tests/expected_fail/w239.nut +++ b/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/tests/expected_fail/w239.nut @@ -1,10 +1,10 @@ //expect:w239 -::userName <- require("sq3_sa_test").userName -::serverName <- require("sq3_sa_test").serverName +::userName <- require("empty.txt")?.userName +::serverName <- require("empty.txt")?.serverName -let function isLoggedIn() { //-declared-never-used +let function isLoggedIn() { //-declared-never-used -all-paths-return-value if (::userName == "") return false; diff --git a/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/tests/expected_fail/w239_sqconfig.nut b/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/tests/expected_fail/w239_sqconfig.nut index a0815e37c..a894596c8 100644 --- a/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/tests/expected_fail/w239_sqconfig.nut +++ b/prog/1stPartyLibs/quirrel/quirrel/static_analyzer/tests/expected_fail/w239_sqconfig.nut @@ -1,9 +1,9 @@ //expect:w239 -::serverName <- require("sq3_sa_test").serverName +::serverName <- require("empty.txt")?.serverName -let function returnBoolFunctionName() { //-declared-never-used +let function returnBoolFunctionName() { //-declared-never-used -all-paths-return-value if (::serverName == "") return diff --git a/prog/1stPartyLibs/vecmath/dag_vecMath_common.h b/prog/1stPartyLibs/vecmath/dag_vecMath_common.h index f7ae64cd1..0d38f2149 100644 --- a/prog/1stPartyLibs/vecmath/dag_vecMath_common.h +++ b/prog/1stPartyLibs/vecmath/dag_vecMath_common.h @@ -1215,7 +1215,7 @@ VECTORCALL VECMATH_FINLINE vec3f v_quat_mul_vec3(quat4f q, vec3f v) return v_add(v, v_madd(v_splat_w(q), t, v_cross3(q, t)));//v + q.w * t + v_cross3(q.xyz, t); } -#if _TARGET_SIMD_VMX|_TARGET_SIMD_SPU|_TARGET_SIMD_SSE +#if _TARGET_SIMD_SSE VECTORCALL VECMATH_FINLINE quat4f v_un_quat_from_mat(vec3f col0, vec3f col1, vec3f col2) { vec4f xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff; @@ -1226,15 +1226,9 @@ VECTORCALL VECMATH_FINLINE quat4f v_un_quat_from_mat(vec3f col0, vec3f col1, vec quat4f res; xx_yy = v_perm_xbzw(col0, col1); -#if _TARGET_SIMD_VMX|_TARGET_SIMD_SPU - xx_yy_zz_xx = v_perm_xycx(xx_yy, col2); - yy_zz_xx_yy = v_perm_ycxy(xx_yy, col2); - zz_xx_yy_zz = v_perm_cxyc(xx_yy, col2); -#elif _TARGET_SIMD_SSE xx_yy_zz_xx = v_perm_xycw(_mm_shuffle_ps(xx_yy, xx_yy, _MM_SHUFFLE(0,0,1,0)), col2); yy_zz_xx_yy = _mm_shuffle_ps(xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(1,0,2,1)); zz_xx_yy_zz = _mm_shuffle_ps(xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(2,1,0,2)); -#endif diagSum = v_add(v_add(xx_yy_zz_xx, yy_zz_xx_yy), zz_xx_yy_zz ); diagDiff = v_sub(v_sub(xx_yy_zz_xx, yy_zz_xx_yy), zz_xx_yy_zz ); @@ -1268,7 +1262,7 @@ VECTORCALL VECMATH_FINLINE quat4f v_un_quat_from_mat(vec3f col0, vec3f col1, vec zz = v_splat_z(col2); res = v_sel(res0, res1, v_cmp_gt(yy, xx)); res = v_sel(res, res2, v_and(v_cmp_gt(zz, xx), v_cmp_gt(zz, yy))); - return v_sel(res, res3, v_cmp_gt(v_splat_x(diagSum), v_zero())); + return v_sel(res, res3, v_cmp_ge(v_splat_x(diagSum), v_zero())); } #endif VECTORCALL VECMATH_FINLINE quat4f v_un_quat_from_mat3(mat33f_cref m) @@ -1524,10 +1518,11 @@ VECTORCALL VECMATH_FINLINE void v_mat33_decompose(mat33f_cref tm, quat4f &rot, v if (v_test_vec_x_lt_0(v_mat33_det(tm))) scl = v_perm_xycw(scl, v_neg(scl)); + vec3f invScl = v_rcp_safe(scl); rot = v_un_quat_from_mat( - v_div(tm.col0, v_splat_x(scl)), - v_div(tm.col1, v_splat_y(scl)), - v_div(tm.col2, v_splat_z(scl))); + v_mul(tm.col0, v_splat_x(invScl)), + v_mul(tm.col1, v_splat_y(invScl)), + v_mul(tm.col2, v_splat_z(invScl))); rot = v_norm4(rot); } @@ -1541,10 +1536,11 @@ VECTORCALL VECMATH_FINLINE void v_mat4_decompose(mat44f_cref tm, vec3f &pos, qua if (v_test_vec_x_lt_0(v_mat44_det43(tm))) scl = v_perm_xycw(scl, v_neg(scl)); + vec3f invScl = v_rcp_safe(scl); rot = v_un_quat_from_mat( - v_div(tm.col0, v_splat_x(scl)), - v_div(tm.col1, v_splat_y(scl)), - v_div(tm.col2, v_splat_z(scl))); + v_mul(tm.col0, v_splat_x(invScl)), + v_mul(tm.col1, v_splat_y(invScl)), + v_mul(tm.col2, v_splat_z(invScl))); rot = v_norm4(rot); } diff --git a/prog/1stPartyLibs/vecmath/dag_vecMath_neon.h b/prog/1stPartyLibs/vecmath/dag_vecMath_neon.h index 8ecdcdfa5..5c8d1287e 100644 --- a/prog/1stPartyLibs/vecmath/dag_vecMath_neon.h +++ b/prog/1stPartyLibs/vecmath/dag_vecMath_neon.h @@ -896,7 +896,7 @@ VECTORCALL VECMATH_FINLINE void v_mat44_inverse(mat44f &dest, mat44f_cref m) vec4f detA2 = v_splat_z(det1); vec4f detB0 = v_sub(detA0, detA1); vec4f det = v_sub(detB0, detA2); - vec4f invdet = v_rcp(det); + vec4f invdet = v_rcp_safe(det); /* Multiply the cofactors by the reciprocal of the determinant. */ dest.col0 = v_mul(out1, invdet); @@ -911,7 +911,7 @@ VECTORCALL VECMATH_FINLINE void v_mat33_inverse(mat33f &dest, mat33f_cref m) tmp0 = v_cross3(m.col1, m.col2); tmp1 = v_cross3(m.col2, m.col0); dot = v_dot3(tmp2, m.col2); - invdet = v_rcp(dot); + invdet = v_rcp_safe(dot); inv0 = v_transpose3x(tmp0, tmp1, tmp2); inv1 = v_transpose3y(tmp0, tmp1, tmp2); inv2 = v_transpose3z(tmp0, tmp1, tmp2); @@ -1008,7 +1008,7 @@ VECTORCALL VECMATH_FINLINE quat4f v_un_quat_from_mat(vec3f col0, vec3f col1, vec vec4f q = v_sel(res0, res1, v_cmp_gt(yy, xx)); q = v_sel(q, res2, v_and(v_cmp_gt(zz, xx), v_cmp_gt(zz, yy))); - return v_sel(q, res3, v_cmp_gt(v_splat_x(diagSum), v_zero())); + return v_sel(q, res3, v_cmp_ge(v_splat_x(diagSum), v_zero())); } VECTORCALL VECMATH_FINLINE short v_extract_xi16(vec4i v) { return vgetq_lane_s16(vreinterpretq_s16_s32(v), 0); } diff --git a/prog/1stPartyLibs/vecmath/dag_vecMath_pc_sse.h b/prog/1stPartyLibs/vecmath/dag_vecMath_pc_sse.h index 9a4fbbb7b..99dd46ca8 100644 --- a/prog/1stPartyLibs/vecmath/dag_vecMath_pc_sse.h +++ b/prog/1stPartyLibs/vecmath/dag_vecMath_pc_sse.h @@ -1059,7 +1059,7 @@ VECTORCALL VECMATH_FINLINE void v_mat44_inverse(mat44f &dest, mat44f_cref m) det = _mm_mul_ps(row0, minor0); det = _mm_add_ps(V_SHUFFLE(det, 0x4E), det); det = _mm_add_ss(V_SHUFFLE(det, 0xB1), det); - tmp1 = _mm_rcp_ss(det); + tmp1 = v_rcp_safe(det); det = _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1))); det = v_splat_x(det); dest.col0 = _mm_mul_ps(det, minor0); @@ -1076,7 +1076,7 @@ VECTORCALL VECMATH_FINLINE void v_mat33_inverse(mat33f &dest, mat33f_cref m) tmp0 = v_cross3(m.col1, m.col2); tmp1 = v_cross3(m.col2, m.col0); dot = v_dot3(tmp2, m.col2); - invdet = v_rcp(dot); + invdet = v_rcp_safe(dot); tmp3 = _mm_shuffle_ps(tmp0, tmp1, _MM_SHUFFLE(0,2,0,2)); tmp4 = _mm_shuffle_ps(tmp0, tmp1, _MM_SHUFFLE(1,3,1,3)); diff --git a/prog/3rdPartyLibs/convert/nvtt-2.0.7/jamfile b/prog/3rdPartyLibs/convert/nvtt-2.0.7/jamfile index f495bd0e5..61de7b6b4 100644 --- a/prog/3rdPartyLibs/convert/nvtt-2.0.7/jamfile +++ b/prog/3rdPartyLibs/convert/nvtt-2.0.7/jamfile @@ -63,5 +63,6 @@ CPPopt = -DNVTT_EXPORTS -D__SSE2__ -D__SSE__ -D__MMX__ ; if $(Platform) in win32 win64 { CPPopt += -DWIN32 -D_WINDOWS -D_USRDLL ; } +if $(Platform) in macosx { CPPopt += -DSQUISH_USE_ALTIVEC=0 ; } include $(Root)/prog/_jBuild/build.jam ; diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/AABBTree/AABBTreeBuilder.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/AABBTree/AABBTreeBuilder.cpp index fb8236a78..7e4f0622a 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/AABBTree/AABBTreeBuilder.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/AABBTree/AABBTreeBuilder.cpp @@ -192,7 +192,7 @@ AABBTreeBuilder::Node *AABBTreeBuilder::BuildInternal(const TriangleSplitter::Ra TriangleSplitter::Range left, right; if (!mTriangleSplitter.Split(inTriangles, left, right)) { - JPH_IF_DEBUG(Trace("AABBTreeBuilder: Doing random split for %d triangles (max per node: %d)!", (int)inTriangles.Count(), mMaxTrianglesPerLeaf);) + JPH_IF_DEBUG(Trace("AABBTreeBuilder: Doing random split for %d triangles (max per node: %u)!", (int)inTriangles.Count(), mMaxTrianglesPerLeaf);) int half = inTriangles.Count() / 2; JPH_ASSERT(half > 0); left = TriangleSplitter::Range(inTriangles.mBegin, inTriangles.mBegin + half); diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Color.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Color.h index 19e6560fb..f7e7b586b 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Color.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Color.h @@ -12,7 +12,7 @@ class Color; using ColorArg = Color; /// Class that holds an RGBA color with 8-bits per component -class [[nodiscard]] JPH_EXPORT Color +class [[nodiscard]] JPH_EXPORT_GCC_BUG_WORKAROUND Color { public: /// Constructors diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Core.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Core.h index d55180432..9b8463403 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Core.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Core.h @@ -192,6 +192,10 @@ #define JPH_EXPORT __declspec(dllexport) #else #define JPH_EXPORT __attribute__ ((visibility ("default"))) + #if defined(JPH_COMPILER_GCC) + // Prevents an issue with GCC attribute parsing (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69585) + #define JPH_EXPORT_GCC_BUG_WORKAROUND [[gnu::visibility("default")]] + #endif #endif #else // When linking against Jolt, we must import these symbols @@ -199,6 +203,10 @@ #define JPH_EXPORT __declspec(dllimport) #else #define JPH_EXPORT __attribute__ ((visibility ("default"))) + #if defined(JPH_COMPILER_GCC) + // Prevents an issue with GCC attribute parsing (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69585) + #define JPH_EXPORT_GCC_BUG_WORKAROUND [[gnu::visibility("default")]] + #endif #endif #endif #else @@ -206,6 +214,10 @@ #define JPH_EXPORT #endif +#ifndef JPH_EXPORT_GCC_BUG_WORKAROUND + #define JPH_EXPORT_GCC_BUG_WORKAROUND JPH_EXPORT +#endif + // Macro used by the RTTI macros to not export a function #define JPH_NO_EXPORT @@ -360,6 +372,9 @@ JPH_SUPPRESS_WARNING_POP // Standard C++ includes +#include +#include +#include JPH_SUPPRESS_WARNINGS_STD_BEGIN #include #include @@ -369,9 +384,6 @@ JPH_SUPPRESS_WARNINGS_STD_BEGIN #include #include JPH_SUPPRESS_WARNINGS_STD_END -#include -#include -#include #if defined(JPH_USE_SSE) #include #elif defined(JPH_USE_NEON) @@ -500,7 +512,7 @@ static_assert(sizeof(void *) == (JPH_CPU_ADDRESS_BITS == 64? 8 : 4), "Invalid si #elif defined(JPH_COMPILER_CLANG) // We compile without -ffast-math because pragma float_control(precise, on) doesn't seem to actually negate all of the -ffast-math effects and causes the unit tests to fail (even if the pragma is added to all files) // On clang 14 and later we can turn off float contraction through a pragma (before it was buggy), so if FMA is on we can disable it through this macro - #if (defined(JPH_CPU_ARM) && __clang_major__ >= 16) || (defined(JPH_CPU_X86) && __clang_major__ >= 14) + #if (defined(JPH_CPU_ARM) && !defined(JPH_PLATFORM_ANDROID) && __clang_major__ >= 16) || (defined(JPH_CPU_X86) && __clang_major__ >= 14) #define JPH_PRECISE_MATH_ON \ _Pragma("float_control(precise, on, push)") \ _Pragma("clang fp contract(off)") diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/LockFreeHashMap.inl b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/LockFreeHashMap.inl index 960b3c73b..593b5bd33 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/LockFreeHashMap.inl +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/LockFreeHashMap.inl @@ -339,7 +339,7 @@ void LockFreeHashMap::TraceStats() const histogram[min(objects_in_bucket, cMaxPerBucket - 1)]++; } - Trace("max_objects_per_bucket = %d, num_buckets = %d, num_objects = %d", max_objects_per_bucket, mNumBuckets, num_objects); + Trace("max_objects_per_bucket = %d, num_buckets = %u, num_objects = %d", max_objects_per_bucket, mNumBuckets, num_objects); for (int i = 0; i < cMaxPerBucket; ++i) if (histogram[i] != 0) diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Memory.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Memory.cpp index 867801591..8eb1d686d 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Memory.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Memory.cpp @@ -32,13 +32,15 @@ JPH_ALLOC_SCOPE void JPH_ALLOC_FN(Free)(void *inBlock) JPH_ALLOC_SCOPE void *JPH_ALLOC_FN(AlignedAllocate)(size_t inSize, size_t inAlignment) { #if defined(JPH_PLATFORM_WINDOWS) - // Microsoft doesn't implement C++17 std::aligned_alloc + // Microsoft doesn't implement posix_memalign return _aligned_malloc(inSize, inAlignment); -#elif defined(JPH_PLATFORM_ANDROID) - return memalign(inAlignment, AlignUp(inSize, inAlignment)); #else - // Using aligned_alloc instead of std::aligned_alloc because the latter is not available on some macOS versions - return aligned_alloc(inAlignment, AlignUp(inSize, inAlignment)); + void *block = nullptr; + JPH_SUPPRESS_WARNING_PUSH + JPH_GCC_SUPPRESS_WARNING("-Wunused-result") + posix_memalign(&block, inAlignment, inSize); + JPH_SUPPRESS_WARNING_POP + return block; #endif } @@ -46,8 +48,6 @@ JPH_ALLOC_SCOPE void JPH_ALLOC_FN(AlignedFree)(void *inBlock) { #if defined(JPH_PLATFORM_WINDOWS) _aligned_free(inBlock); -#elif defined(JPH_PLATFORM_ANDROID) - free(inBlock); #else free(inBlock); #endif diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Profiler.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Profiler.cpp index 91950eb9e..5678ba771 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Profiler.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Profiler.cpp @@ -106,7 +106,6 @@ void Profiler::sAggregate(int inDepth, uint32 inColor, ProfileSample *&ioSample, // Start accumulating totals uint64 cycles_this_with_children = ioSample->mEndCycle - ioSample->mStartCycle; - uint64 cycles_in_children = 0; // Loop over following samples until we find a sample that starts on or after our end ProfileSample *sample; @@ -116,9 +115,6 @@ void Profiler::sAggregate(int inDepth, uint32 inColor, ProfileSample *&ioSample, JPH_ASSERT(sample->mStartCycle >= ioSample->mStartCycle); JPH_ASSERT(sample->mEndCycle <= ioSample->mEndCycle); - // This is a direct child of us, accumulate time - cycles_in_children += sample->mEndCycle - sample->mStartCycle; - // Recurse and skip over the children of this child sAggregate(inDepth + 1, inColor, sample, inEnd, ioAggregators, ioKeyToAggregator); } @@ -140,7 +136,7 @@ void Profiler::sAggregate(int inDepth, uint32 inColor, ProfileSample *&ioSample, } // Add the measurement to the aggregator - aggregator->AccumulateMeasurement(cycles_this_with_children, cycles_in_children); + aggregator->AccumulateMeasurement(cycles_this_with_children); // Update ioSample to the last child of ioSample JPH_ASSERT(sample[-1].mStartCycle <= ioSample->mEndCycle); @@ -193,9 +189,6 @@ void Profiler::DumpInternal() for (ProfileSample *s = t.mSamplesBegin, *end = t.mSamplesEnd; s < end; ++s) sAggregate(0, Color::sGetDistinctColor(0).GetUInt32(), s, end, aggregators, key_to_aggregators); - // Dump as list - DumpList(tag.c_str(), aggregators); - // Dump as chart DumpChart(tag.c_str(), threads, key_to_aggregators, aggregators); } @@ -208,86 +201,6 @@ static String sHTMLEncode(const char *inString) return str; } -void Profiler::DumpList(const char *inTag, const Aggregators &inAggregators) -{ - // Open file - std::ofstream f; - f.open(StringFormat("profile_list_%s.html", inTag).c_str(), std::ofstream::out | std::ofstream::trunc); - if (!f.is_open()) - return; - - // Write header - f << R"( - - - Profile List - - - - - - - - - - - - - - - - - - - - - -)"; - - // Get total time - uint64 total_time = 0; - for (const Aggregator &item : inAggregators) - total_time += item.mTotalCyclesInCallWithChildren - item.mTotalCyclesInChildren; - - // Get cycles per second - uint64 cycles_per_second = GetProcessorTicksPerSecond(); - - // Sort the list - Aggregators aggregators = inAggregators; - QuickSort(aggregators.begin(), aggregators.end()); - - // Write all aggregators - for (const Aggregator &item : aggregators) - { - uint64 cycles_in_call_no_children = item.mTotalCyclesInCallWithChildren - item.mTotalCyclesInChildren; - - char str[2048]; - snprintf(str, sizeof(str), R"( - - - - - - - - -)", - sHTMLEncode(item.mName).c_str(), // Description - 100.0 * item.mTotalCyclesInCallWithChildren / total_time, // Total time with children - 100.0 * cycles_in_call_no_children / total_time, // Total time no children - item.mCallCounter, // Calls - 1000000.0 * item.mTotalCyclesInCallWithChildren / cycles_per_second / item.mCallCounter, // us / call with children - 1000000.0 * cycles_in_call_no_children / cycles_per_second / item.mCallCounter, // us / call no children - 1000000.0 * item.mMinCyclesInCallWithChildren / cycles_per_second, // Min. us / call with children - 1000000.0 * item.mMaxCyclesInCallWithChildren / cycles_per_second); // Max. us / call with children - - f << str; - } - - // End table - f << R"(
DescriptionTotal time with children (%)Total time (%)Callsµs / call with childrenµs / callMin. µs / callMax. µs / call
%s%.1f%.1f%u%.2f%.2f%.2f%.2f
)"; -} - void Profiler::DumpChart(const char *inTag, const Threads &inThreads, const KeyToAggregator &inKeyToAggregators, const Aggregators &inAggregators) { // Open file diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Profiler.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Profiler.h index 04758c5fa..4254c5622 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Profiler.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/Profiler.h @@ -116,11 +116,10 @@ class JPH_EXPORT Profiler : public NonCopyable Aggregator(const char *inName) : mName(inName) { } /// Accumulate results for a measurement - void AccumulateMeasurement(uint64 inCyclesInCallWithChildren, uint64 inCyclesInChildren) + void AccumulateMeasurement(uint64 inCyclesInCallWithChildren) { mCallCounter++; mTotalCyclesInCallWithChildren += inCyclesInCallWithChildren; - mTotalCyclesInChildren += inCyclesInChildren; mMinCyclesInCallWithChildren = min(inCyclesInCallWithChildren, mMinCyclesInCallWithChildren); mMaxCyclesInCallWithChildren = max(inCyclesInCallWithChildren, mMaxCyclesInCallWithChildren); } @@ -137,7 +136,6 @@ class JPH_EXPORT Profiler : public NonCopyable /// Statistics uint32 mCallCounter = 0; ///< Number of times AccumulateMeasurement was called uint64 mTotalCyclesInCallWithChildren = 0; ///< Total amount of cycles spent in this scope - uint64 mTotalCyclesInChildren = 0; ///< Total amount of cycles spent in children of this scope uint64 mMinCyclesInCallWithChildren = 0xffffffffffffffffUL; ///< Minimum amount of cycles spent per call uint64 mMaxCyclesInCallWithChildren = 0; ///< Maximum amount of cycles spent per call }; @@ -157,7 +155,6 @@ class JPH_EXPORT Profiler : public NonCopyable /// Dump profiling statistics void DumpInternal(); - void DumpList(const char *inTag, const Aggregators &inAggregators); void DumpChart(const char *inTag, const Threads &inThreads, const KeyToAggregator &inKeyToAggregators, const Aggregators &inAggregators); std::mutex mLock; ///< Lock that protects mThreads @@ -169,7 +166,7 @@ class JPH_EXPORT Profiler : public NonCopyable }; // Class that contains the information of a single scoped measurement -class alignas(16) JPH_EXPORT ProfileSample : public NonCopyable +class alignas(16) JPH_EXPORT_GCC_BUG_WORKAROUND ProfileSample : public NonCopyable { public: JPH_OVERRIDE_NEW_DELETE diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StaticArray.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StaticArray.h index 94af9983a..70e8cb9a8 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StaticArray.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StaticArray.h @@ -156,6 +156,19 @@ class [[nodiscard]] StaticArray return reinterpret_cast(mElements[inIdx]); } + /// Access element + T & at(size_type inIdx) + { + JPH_ASSERT(inIdx < mSize); + return reinterpret_cast(mElements[inIdx]); + } + + const T & at(size_type inIdx) const + { + JPH_ASSERT(inIdx < mSize); + return reinterpret_cast(mElements[inIdx]); + } + /// First element in the array const T & front() const { diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StreamIn.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StreamIn.h index a3c03357a..927d936b5 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StreamIn.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StreamIn.h @@ -4,10 +4,12 @@ #pragma once +#include + JPH_NAMESPACE_BEGIN /// Simple binary input stream -class JPH_EXPORT StreamIn +class JPH_EXPORT StreamIn : public NonCopyable { public: /// Virtual destructor diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StreamOut.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StreamOut.h index c2d0b53f6..219e1cf77 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StreamOut.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Core/StreamOut.h @@ -4,10 +4,12 @@ #pragma once +#include + JPH_NAMESPACE_BEGIN /// Simple binary output stream -class JPH_EXPORT StreamOut +class JPH_EXPORT StreamOut : public NonCopyable { public: /// Virtual destructor diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/ClosestPoint.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/ClosestPoint.h index e0f339471..8c646bc32 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/ClosestPoint.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/ClosestPoint.h @@ -184,6 +184,7 @@ namespace ClosestPoint float best_dist_sq = inC.LengthSq(); // If the closest point must include C then A or B cannot be closest + // Note that we test vertices first because we want to prefer a closest vertex over a closest edge (this results in an outSet with fewer bits set) if constexpr (!MustIncludeC) { // Try vertex A @@ -203,21 +204,6 @@ namespace ClosestPoint closest_point = inB; best_dist_sq = b_len_sq; } - - // Edge AB - float ab_len_sq = ab.LengthSq(); - if (ab_len_sq > Square(FLT_EPSILON)) - { - float v = Clamp(-a.Dot(ab) / ab_len_sq, 0.0f, 1.0f); - Vec3 q = a + v * ab; - float dist_sq = q.LengthSq(); - if (dist_sq < best_dist_sq) - { - closest_set = swap_ac.GetX()? 0b0110 : 0b0011; - closest_point = q; - best_dist_sq = dist_sq; - } - } } // Edge AC @@ -236,7 +222,7 @@ namespace ClosestPoint } // Edge BC - Vec3 bc = c - inB; + Vec3 bc = inC - inB; float bc_len_sq = bc.LengthSq(); if (bc_len_sq > Square(FLT_EPSILON)) { @@ -245,12 +231,32 @@ namespace ClosestPoint float dist_sq = q.LengthSq(); if (dist_sq < best_dist_sq) { - closest_set = swap_ac.GetX()? 0b0011 : 0b0110; + closest_set = 0b0110; closest_point = q; best_dist_sq = dist_sq; } } + // If the closest point must include C then AB cannot be closest + if constexpr (!MustIncludeC) + { + // Edge AB + ab = inB - inA; + float ab_len_sq = ab.LengthSq(); + if (ab_len_sq > Square(FLT_EPSILON)) + { + float v = Clamp(-inA.Dot(ab) / ab_len_sq, 0.0f, 1.0f); + Vec3 q = inA + v * ab; + float dist_sq = q.LengthSq(); + if (dist_sq < best_dist_sq) + { + closest_set = 0b0011; + closest_point = q; + best_dist_sq = dist_sq; + } + } + } + outSet = closest_set; return closest_point; } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/ConvexHullBuilder.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/ConvexHullBuilder.cpp index 2e293307f..298eada94 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/ConvexHullBuilder.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/ConvexHullBuilder.cpp @@ -408,7 +408,7 @@ ConvexHullBuilder::EResult ConvexHullBuilder::Initialize(int inMaxVertices, floa Array positions_2d; positions_2d.reserve(mPositions.size()); for (Vec3 v : mPositions) - positions_2d.push_back(Vec3(base1.Dot(v), base2.Dot(v), 0)); + positions_2d.emplace_back(base1.Dot(v), base2.Dot(v), 0.0f); // Build hull Array edges_2d; @@ -1290,7 +1290,7 @@ void ConvexHullBuilder::GetCenterOfMassAndVolume(Vec3 &outCenterOfMass, float &o // Update v2 for next triangle v2 = v3; - } while (e != f->mFirstEdge); + } } // Calculate center of mass, fall back to average point in case there is no volume (everything is on a plane in this case) diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/EPAConvexHullBuilder.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/EPAConvexHullBuilder.h index ee0a35e77..885df0419 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/EPAConvexHullBuilder.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/EPAConvexHullBuilder.h @@ -209,7 +209,7 @@ class EPAConvexHullBuilder : public NonCopyable /// Get next closest triangle Triangle * PopClosest() { - // Move largest to end + // Move closest to end std::pop_heap(begin(), end(), sTriangleSorter); // Remove last triangle diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/EPAPenetrationDepth.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/EPAPenetrationDepth.h index 85faa83ab..eff1522d1 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/EPAPenetrationDepth.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/EPAPenetrationDepth.h @@ -201,7 +201,7 @@ class EPAPenetrationDepth hull.DrawLabel("Build initial hull"); #endif #ifdef JPH_EPA_PENETRATION_DEPTH_DEBUG - Trace("Init: num_points = %d", support_points.mY.size()); + Trace("Init: num_points = %u", (uint)support_points.mY.size()); #endif hull.Initialize(0, 1, 2); for (typename Points::size_type i = 3; i < support_points.mY.size(); ++i) @@ -284,9 +284,9 @@ class EPAPenetrationDepth if (!t->IsFacing(w) || !hull.AddPoint(t, new_index, FLT_MAX, new_triangles)) return false; - // If the triangle was removed we can free it now - if (t->mRemoved) - hull.FreeTriangle(t); + // The triangle is facing the support point "w" and can now be safely removed + JPH_ASSERT(t->mRemoved); + hull.FreeTriangle(t); // If we run out of triangles or points, we couldn't include the origin in the hull so there must be very little penetration and we report no collision. if (!hull.HasNextTriangle() || support_points.mY.size() >= cMaxPointsToIncludeOriginInHull) diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/GJKClosestPoint.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/GJKClosestPoint.h index 1dc9cb10b..802dff75b 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/GJKClosestPoint.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/GJKClosestPoint.h @@ -598,7 +598,6 @@ class GJKClosestPoint : public NonCopyable mY[i] = x - mP[i]; // Determine the new closest point from Y to origin - bool needs_restart = false; uint32 set; // Set of points that form the new simplex if (!GetClosest(v_len_sq, v, v_len_sq, set)) { @@ -606,26 +605,6 @@ class GJKClosestPoint : public NonCopyable Trace("Failed to converge"); #endif - // We failed to converge, restart - needs_restart = true; - } - else if (set == 0xf) - { -#ifdef JPH_GJK_DEBUG - Trace("Full simplex"); -#endif - - // If there are 4 points, x is inside the tetrahedron and we've found a hit - // Double check if this is indeed the case - if (v_len_sq <= tolerance_sq) - break; - - // We failed to converge, restart - needs_restart = true; - } - - if (needs_restart) - { // Only allow 1 restart, if we still can't get a closest point // we're so close that we return this as a hit if (!allow_restart) @@ -642,6 +621,16 @@ class GJKClosestPoint : public NonCopyable v_len_sq = FLT_MAX; continue; } + else if (set == 0xf) + { +#ifdef JPH_GJK_DEBUG + Trace("Full simplex"); +#endif + + // We're inside the tetrahedron, we have a hit (verify that length of v is 0) + JPH_ASSERT(v_len_sq == 0.0f); + break; + } // Update the points P to form the new simplex // Note: We're not updating Y as Y will shift with x so we have to calculate it every iteration @@ -807,7 +796,6 @@ class GJKClosestPoint : public NonCopyable mY[i] = x - (mQ[i] - mP[i]); // Determine the new closest point from Y to origin - bool needs_restart = false; uint32 set; // Set of points that form the new simplex if (!GetClosest(v_len_sq, v, v_len_sq, set)) { @@ -815,26 +803,6 @@ class GJKClosestPoint : public NonCopyable Trace("Failed to converge"); #endif - // We failed to converge, restart - needs_restart = true; - } - else if (set == 0xf) - { -#ifdef JPH_GJK_DEBUG - Trace("Full simplex"); -#endif - - // If there are 4 points, x is inside the tetrahedron and we've found a hit - // Double check that A and B are indeed touching according to our tolerance - if (v_len_sq <= tolerance_sq) - break; - - // We failed to converge, restart - needs_restart = true; - } - - if (needs_restart) - { // Only allow 1 restart, if we still can't get a closest point // we're so close that we return this as a hit if (!allow_restart) @@ -852,6 +820,16 @@ class GJKClosestPoint : public NonCopyable v_len_sq = FLT_MAX; continue; } + else if (set == 0xf) + { +#ifdef JPH_GJK_DEBUG + Trace("Full simplex"); +#endif + + // We're inside the tetrahedron, we have a hit (verify that length of v is 0) + JPH_ASSERT(v_len_sq == 0.0f); + break; + } // Update the points P and Q to form the new simplex // Note: We're not updating Y as Y will shift with x so we have to calculate it every iteration diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/Indexify.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/Indexify.cpp index d76cea437..77143cbfb 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/Indexify.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/Indexify.cpp @@ -4,58 +4,186 @@ #include -#include #include +#include JPH_NAMESPACE_BEGIN -void Indexify(const TriangleList &inTriangles, VertexList &outVertices, IndexedTriangleList &outTriangles, float inVertexWeldDistance) +static JPH_INLINE const Float3 &sIndexifyGetFloat3(const TriangleList &inTriangles, uint32 inVertexIndex) +{ + return inTriangles[inVertexIndex / 3].mV[inVertexIndex % 3]; +} + +static JPH_INLINE Vec3 sIndexifyGetVec3(const TriangleList &inTriangles, uint32 inVertexIndex) +{ + return Vec3::sLoadFloat3Unsafe(sIndexifyGetFloat3(inTriangles, inVertexIndex)); +} + +static void sIndexifyVerticesBruteForce(const TriangleList &inTriangles, const uint32 *inVertexIndices, const uint32 *inVertexIndicesEnd, Array &ioWeldedVertices, float inVertexWeldDistance) { float weld_dist_sq = Square(inVertexWeldDistance); - // Ensure that output vertices are empty before we begin - outVertices.clear(); + // Compare every vertex + for (const uint32 *v1_idx = inVertexIndices; v1_idx < inVertexIndicesEnd; ++v1_idx) + { + Vec3 v1 = sIndexifyGetVec3(inTriangles, *v1_idx); - // Find unique vertices - UnorderedMap vertex_map; - for (const Triangle &t : inTriangles) - for (const Float3 &v : t.mV) + // with every other vertex... + for (const uint32 *v2_idx = v1_idx + 1; v2_idx < inVertexIndicesEnd; ++v2_idx) { - // Try to insert element - auto insert = vertex_map.insert(pair(v, 0)); - if (insert.second) + Vec3 v2 = sIndexifyGetVec3(inTriangles, *v2_idx); + + // If they're weldable + if ((v2 - v1).LengthSq() <= weld_dist_sq) { - // Newly inserted, see if we can share - bool found = false; - for (size_t i = 0; i < outVertices.size(); ++i) - { - const Float3 &other = outVertices[i]; - if (Square(other.x - v.x) + Square(other.y - v.y) + Square(other.z - v.z) <= weld_dist_sq) - { - insert.first->second = (uint32)i; - found = true; - break; - } - } + // Order the vertices + uint32 lowest = min(*v1_idx, *v2_idx); + uint32 highest = max(*v1_idx, *v2_idx); - if (!found) + // Find the lowest vertex + uint32 new_lowest = ioWeldedVertices[lowest]; + while (new_lowest < lowest) { - // Can't share, add vertex - insert.first->second = (uint32)outVertices.size(); - outVertices.push_back(v); + ioWeldedVertices[lowest] = new_lowest; + lowest = new_lowest; + new_lowest = ioWeldedVertices[lowest]; } + + // Link highest to lowest + ioWeldedVertices[highest] = lowest; } } + } +} + +static void sIndexifyVerticesRecursively(const TriangleList &inTriangles, uint32 *ioVertexIndices, uint inNumVertices, uint32 *ioScratch, Array &ioWeldedVertices, float inVertexWeldDistance, uint inMaxRecursion) +{ + // Check if we have few enough vertices to do a brute force search + // Or if we've recursed too deep (this means we chipped off a few vertices each iteration because all points are very close) + if (inNumVertices <= 8 || inMaxRecursion == 0) + { + sIndexifyVerticesBruteForce(inTriangles, ioVertexIndices, ioVertexIndices + inNumVertices, ioWeldedVertices, inVertexWeldDistance); + return; + } + + // Calculate bounds + AABox bounds; + for (const uint32 *v = ioVertexIndices, *v_end = ioVertexIndices + inNumVertices; v < v_end; ++v) + bounds.Encapsulate(sIndexifyGetVec3(inTriangles, *v)); + + // Determine split plane + int split_axis = bounds.GetExtent().GetHighestComponentIndex(); + float split_value = bounds.GetCenter()[split_axis]; + + // Partition vertices + uint32 *v_read = ioVertexIndices, *v_write = ioVertexIndices, *v_end = ioVertexIndices + inNumVertices; + uint32 *scratch = ioScratch; + while (v_read < v_end) + { + // Calculate distance to plane + float distance_to_split_plane = sIndexifyGetFloat3(inTriangles, *v_read)[split_axis] - split_value; + if (distance_to_split_plane < -inVertexWeldDistance) + { + // Vertex is on the right side + *v_write = *v_read; + ++v_read; + ++v_write; + } + else if (distance_to_split_plane > inVertexWeldDistance) + { + // Vertex is on the wrong side, swap with the last vertex + --v_end; + swap(*v_read, *v_end); + } + else + { + // Vertex is too close to the split plane, it goes on both sides + *scratch++ = *v_read++; + } + } + + // Check if we made any progress + uint num_vertices_on_both_sides = (uint)(scratch - ioScratch); + if (num_vertices_on_both_sides == inNumVertices) + { + sIndexifyVerticesBruteForce(inTriangles, ioVertexIndices, ioVertexIndices + inNumVertices, ioWeldedVertices, inVertexWeldDistance); + return; + } + + // Calculate how we classified the vertices + uint num_vertices_left = (uint)(v_write - ioVertexIndices); + uint num_vertices_right = (uint)(ioVertexIndices + inNumVertices - v_end); + JPH_ASSERT(num_vertices_left + num_vertices_right + num_vertices_on_both_sides == inNumVertices); + memcpy(v_write, ioScratch, num_vertices_on_both_sides * sizeof(uint32)); + + // Recurse + uint max_recursion = inMaxRecursion - 1; + sIndexifyVerticesRecursively(inTriangles, ioVertexIndices, num_vertices_left + num_vertices_on_both_sides, ioScratch, ioWeldedVertices, inVertexWeldDistance, max_recursion); + sIndexifyVerticesRecursively(inTriangles, ioVertexIndices + num_vertices_left, num_vertices_right + num_vertices_on_both_sides, ioScratch, ioWeldedVertices, inVertexWeldDistance, max_recursion); +} + +void Indexify(const TriangleList &inTriangles, VertexList &outVertices, IndexedTriangleList &outTriangles, float inVertexWeldDistance) +{ + uint num_triangles = (uint)inTriangles.size(); + uint num_vertices = num_triangles * 3; + + // Create a list of all vertex indices + Array vertex_indices; + vertex_indices.resize(num_vertices); + for (uint i = 0; i < num_vertices; ++i) + vertex_indices[i] = i; + + // Link each vertex to itself + Array welded_vertices; + welded_vertices.resize(num_vertices); + for (uint i = 0; i < num_vertices; ++i) + welded_vertices[i] = i; + + // A scope to free memory used by the scratch array + { + // Some scratch memory, used for the vertices that fall in both partitions + Array scratch; + scratch.resize(num_vertices); + + // Recursively split the vertices + sIndexifyVerticesRecursively(inTriangles, vertex_indices.data(), num_vertices, scratch.data(), welded_vertices, inVertexWeldDistance, 32); + } + + // Do a pass to complete the welding, linking each vertex to the vertex it is welded to + // (and since we're going from 0 to N we can be sure that the vertex we're linking to is already linked to the lowest vertex) + uint num_resulting_vertices = 0; + for (uint i = 0; i < num_vertices; ++i) + { + welded_vertices[i] = welded_vertices[welded_vertices[i]]; + if (welded_vertices[i] == i) + ++num_resulting_vertices; + } + + // Collect the vertices + outVertices.clear(); + outVertices.reserve(num_resulting_vertices); + for (uint i = 0; i < num_vertices; ++i) + if (welded_vertices[i] == i) + { + // New vertex + welded_vertices[i] = (uint32)outVertices.size(); + outVertices.push_back(sIndexifyGetFloat3(inTriangles, i)); + } + else + { + // Reused vertex, remap index + welded_vertices[i] = welded_vertices[welded_vertices[i]]; + } // Create indexed triangles outTriangles.clear(); - outTriangles.reserve(inTriangles.size()); - for (const Triangle &t : inTriangles) + outTriangles.reserve(num_triangles); + for (uint t = 0; t < num_triangles; ++t) { IndexedTriangle it; - it.mMaterialIndex = t.mMaterialIndex; - for (int j = 0; j < 3; ++j) - it.mIdx[j] = vertex_map[t.mV[j]]; + it.mMaterialIndex = inTriangles[t].mMaterialIndex; + for (int v = 0; v < 3; ++v) + it.mIdx[v] = welded_vertices[t * 3 + v]; if (!it.IsDegenerate(outVertices)) outTriangles.push_back(it); } @@ -65,8 +193,11 @@ void Deindexify(const VertexList &inVertices, const IndexedTriangleList &inTrian { outTriangles.resize(inTriangles.size()); for (size_t t = 0; t < inTriangles.size(); ++t) + { + outTriangles[t].mMaterialIndex = inTriangles[t].mMaterialIndex; for (int v = 0; v < 3; ++v) outTriangles[t].mV[v] = inVertices[inTriangles[t].mIdx[v]]; + } } JPH_NAMESPACE_END diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/OrientedBox.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/OrientedBox.h index 6a5289f14..1e3174fb8 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/OrientedBox.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Geometry/OrientedBox.h @@ -14,7 +14,7 @@ JPH_NAMESPACE_BEGIN class AABox; /// Oriented box -class [[nodiscard]] JPH_EXPORT OrientedBox +class [[nodiscard]] JPH_EXPORT_GCC_BUG_WORKAROUND OrientedBox { public: JPH_OVERRIDE_NEW_DELETE diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/DVec3.inl b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/DVec3.inl index 6bac4cfa8..fb575f345 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/DVec3.inl +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/DVec3.inl @@ -65,7 +65,7 @@ DVec3::DVec3(const Double3 &inV) Type xy = _mm256_unpacklo_pd(x, y); mValue = _mm256_blend_pd(xy, z, 0b1100); // Assure Z and W are the same #elif defined(JPH_USE_SSE) - mValue.mLow = _mm_load_pd(&inV.x); + mValue.mLow = _mm_loadu_pd(&inV.x); mValue.mHigh = _mm_set_pd1(inV.z); #elif defined(JPH_USE_NEON) mValue.val[0] = vld1q_f64(&inV.x); diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Quat.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Quat.h index 80d6ece2d..10564cab1 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Quat.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Quat.h @@ -83,6 +83,15 @@ class [[nodiscard]] alignas(JPH_VECTOR_ALIGNMENT) Quat /// Get the quaternion as a Vec4 JPH_INLINE Vec4 GetXYZW() const { return mValue; } + /// Set individual components + JPH_INLINE void SetX(float inX) { mValue.SetX(inX); } + JPH_INLINE void SetY(float inY) { mValue.SetY(inY); } + JPH_INLINE void SetZ(float inZ) { mValue.SetZ(inZ); } + JPH_INLINE void SetW(float inW) { mValue.SetW(inW); } + + /// Set all components + JPH_INLINE void Set(float inX, float inY, float inZ, float inW) { mValue.Set(inX, inY, inZ, inW); } + ///@} ///@name Default quaternions ///@{ diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vec3.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vec3.h index 7267d6e0a..5ca718965 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vec3.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vec3.h @@ -130,6 +130,9 @@ class [[nodiscard]] alignas(JPH_VECTOR_ALIGNMENT) Vec3 JPH_INLINE void SetY(float inY) { mF32[1] = inY; } JPH_INLINE void SetZ(float inZ) { mF32[2] = mF32[3] = inZ; } // Assure Z and W are the same + /// Set all components + JPH_INLINE void Set(float inX, float inY, float inZ) { *this = Vec3(inX, inY, inZ); } + /// Get float component by index JPH_INLINE float operator [] (uint inCoordinate) const { JPH_ASSERT(inCoordinate < 3); return mF32[inCoordinate]; } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vec4.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vec4.h index bd0c55173..7cf4389ef 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vec4.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vec4.h @@ -122,6 +122,9 @@ class [[nodiscard]] alignas(JPH_VECTOR_ALIGNMENT) Vec4 JPH_INLINE void SetZ(float inZ) { mF32[2] = inZ; } JPH_INLINE void SetW(float inW) { mF32[3] = inW; } + /// Set all components + JPH_INLINE void Set(float inX, float inY, float inZ, float inW) { *this = Vec4(inX, inY, inZ, inW); } + /// Get float component by index JPH_INLINE float operator [] (uint inCoordinate) const { JPH_ASSERT(inCoordinate < 4); return mF32[inCoordinate]; } JPH_INLINE float & operator [] (uint inCoordinate) { JPH_ASSERT(inCoordinate < 4); return mF32[inCoordinate]; } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vector.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vector.h index 7adcd861c..5880a2c87 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vector.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Math/Vector.h @@ -119,6 +119,13 @@ class [[nodiscard]] Vector return v; } + inline Vector & operator /= (float inV2) + { + for (uint r = 0; r < Rows; ++r) + mF32[r] /= inV2; + return *this; + } + /// Add two float vectors (component wise) inline Vector operator + (const Vector &inV2) const { diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/ObjectStream.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/ObjectStream.h index de0419b1d..e539cce83 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/ObjectStream.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/ObjectStream.h @@ -6,13 +6,14 @@ #include #include -#include #include +#include +#include JPH_NAMESPACE_BEGIN /// Base class for object stream input and output streams. -class JPH_EXPORT ObjectStream +class JPH_EXPORT ObjectStream : public NonCopyable { public: /// Stream type @@ -23,7 +24,7 @@ class JPH_EXPORT ObjectStream }; protected: - /// Constructor + /// Destructor virtual ~ObjectStream() = default; /// Identifier for objects diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/ObjectStreamIn.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/ObjectStreamIn.cpp index 82a2f2940..45ea2857b 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/ObjectStreamIn.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/ObjectStreamIn.cpp @@ -413,11 +413,11 @@ bool ObjectStreamIn::ReadPointerData(const RTTI *inRTTI, void **inPointer, int i else { // Put pointer on the list to be resolved later on - mUnresolvedLinks.emplace_back(); - mUnresolvedLinks.back().mPointer = inPointer; - mUnresolvedLinks.back().mRefCountOffset = inRefCountOffset; - mUnresolvedLinks.back().mIdentifier = identifier; - mUnresolvedLinks.back().mRTTI = inRTTI; + Link &link = mUnresolvedLinks.emplace_back(); + link.mPointer = inPointer; + link.mRefCountOffset = inRefCountOffset; + link.mIdentifier = identifier; + link.mRTTI = inRTTI; } return true; diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/SerializableObject.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/SerializableObject.h index 9656fe46d..5ff3f7496 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/SerializableObject.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/ObjectStream/SerializableObject.h @@ -143,7 +143,7 @@ public: \ /// Classes must be derived from SerializableObject if you want to be able to save pointers or /// reference counting pointers to objects of this or derived classes. The type will automatically /// be determined during serialization and upon deserialization it will be restored correctly. -class JPH_EXPORT SerializableObject +class JPH_EXPORT SerializableObject : public NonCopyable { JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE(JPH_EXPORT, SerializableObject) diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/Body.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/Body.h index 228eb32d9..40e52047c 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/Body.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/Body.h @@ -31,7 +31,7 @@ class SoftBodyCreationSettings; /// The functions that get/set the position of the body all indicate if they are relative to the center of mass or to the original position in which the shape was created. /// /// The linear velocity is also velocity of the center of mass, to correct for this: \f$VelocityCOM = Velocity - AngularVelocity \times ShapeCOM\f$. -class alignas(JPH_RVECTOR_ALIGNMENT) JPH_EXPORT Body : public NonCopyable +class alignas(JPH_RVECTOR_ALIGNMENT) JPH_EXPORT_GCC_BUG_WORKAROUND Body : public NonCopyable { public: JPH_OVERRIDE_NEW_DELETE diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/BodyInterface.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/BodyInterface.cpp index 345fd2ac5..b870ea6c9 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/BodyInterface.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/BodyInterface.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -218,6 +219,13 @@ void BodyInterface::ActivateBodies(const BodyID *inBodyIDs, int inNumber) mBodyManager->ActivateBodies(inBodyIDs, inNumber); } +void BodyInterface::ActivateBodiesInAABox(const AABox &inBox, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter) +{ + AllHitCollisionCollector collector; + mBroadPhase->CollideAABox(inBox, collector, inBroadPhaseLayerFilter, inObjectLayerFilter); + ActivateBodies(collector.mHits.data(), (int)collector.mHits.size()); +} + void BodyInterface::DeactivateBody(const BodyID &inBodyID) { BodyLockWrite lock(*mBodyLockInterface, inBodyID); diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/BodyInterface.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/BodyInterface.h index 966a8847f..434cae975 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/BodyInterface.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Body/BodyInterface.h @@ -26,6 +26,8 @@ class SubShapeID; class Shape; class TwoBodyConstraintSettings; class TwoBodyConstraint; +class BroadPhaseLayerFilter; +class AABox; /// Class that provides operations on bodies using a body ID. Note that if you need to do multiple operations on a single body, it is more efficient to lock the body once and combine the operations. /// All quantities are in world space unless otherwise specified. @@ -123,6 +125,7 @@ class JPH_EXPORT BodyInterface : public NonCopyable ///@{ void ActivateBody(const BodyID &inBodyID); void ActivateBodies(const BodyID *inBodyIDs, int inNumber); + void ActivateBodiesInAABox(const AABox &inBox, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter); void DeactivateBody(const BodyID &inBodyID); void DeactivateBodies(const BodyID *inBodyIDs, int inNumber); bool IsActive(const BodyID &inBodyID) const; diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Character/CharacterBase.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Character/CharacterBase.h index 14904c20f..2603352d4 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Character/CharacterBase.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Character/CharacterBase.h @@ -22,6 +22,11 @@ class JPH_EXPORT CharacterBaseSettings : public RefTarget public: JPH_OVERRIDE_NEW_DELETE + /// Constructor + CharacterBaseSettings() = default; + CharacterBaseSettings(const CharacterBaseSettings &inSettings) = default; + CharacterBaseSettings & operator = (const CharacterBaseSettings &inSettings) = default; + /// Virtual destructor virtual ~CharacterBaseSettings() = default; diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/ConvexHullShape.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/ConvexHullShape.cpp index f6f4bd52b..ac837bbf8 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/ConvexHullShape.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/ConvexHullShape.cpp @@ -129,6 +129,7 @@ ConvexHullShape::ConvexHullShape(const ConvexHullShapeSettings &inSettings, Shap for (BuilderFace *builder_face : builder_faces) { // Determine where the vertices go + JPH_ASSERT(mVertexIdx.size() <= 0xFFFF); uint16 first_vertex = (uint16)mVertexIdx.size(); uint16 num_vertices = 0; @@ -180,7 +181,7 @@ ConvexHullShape::ConvexHullShape(const ConvexHullShapeSettings &inSettings, Shap // Test if GetSupportFunction can support this many points if (mPoints.size() > cMaxPointsInHull) { - outResult.SetError(StringFormat("Internal error: Too many points in hull (%d), max allowed %d", mPoints.size(), cMaxPointsInHull)); + outResult.SetError(StringFormat("Internal error: Too many points in hull (%u), max allowed %d", (uint)mPoints.size(), cMaxPointsInHull)); return; } @@ -205,61 +206,58 @@ ConvexHullShape::ConvexHullShape(const ConvexHullShapeSettings &inSettings, Shap return; } - if (faces.size() > 1) + // Find the 3 normals that form the largest tetrahedron + // The largest tetrahedron we can get is ((1, 0, 0) x (0, 1, 0)) . (0, 0, 1) = 1, if the volume is only 5% of that, + // the three vectors are too coplanar and we fall back to using only 2 plane normals + float biggest_volume = 0.05f; + int best3[3] = { -1, -1, -1 }; + + // When using 2 normals, we get the two with the biggest angle between them with a minimal difference of 1 degree + // otherwise we fall back to just using 1 plane normal + float smallest_dot = Cos(DegreesToRadians(1.0f)); + int best2[2] = { -1, -1 }; + + for (int face1 = 0; face1 < (int)faces.size(); ++face1) { - // Find the 3 normals that form the largest tetrahedron - // The largest tetrahedron we can get is ((1, 0, 0) x (0, 1, 0)) . (0, 0, 1) = 1, if the volume is only 5% of that, - // the three vectors are too coplanar and we fall back to using only 2 plane normals - float biggest_volume = 0.05f; - int best3[3] = { -1, -1, -1 }; - - // When using 2 normals, we get the two with the biggest angle between them with a minimal difference of 1 degree - // otherwise we fall back to just using 1 plane normal - float smallest_dot = Cos(DegreesToRadians(1.0f)); - int best2[2] = { -1, -1 }; - - for (int face1 = 0; face1 < (int)faces.size(); ++face1) + Vec3 normal1 = mPlanes[faces[face1]].GetNormal(); + for (int face2 = face1 + 1; face2 < (int)faces.size(); ++face2) { - Vec3 normal1 = mPlanes[faces[face1]].GetNormal(); - for (int face2 = face1 + 1; face2 < (int)faces.size(); ++face2) - { - Vec3 normal2 = mPlanes[faces[face2]].GetNormal(); - Vec3 cross = normal1.Cross(normal2); + Vec3 normal2 = mPlanes[faces[face2]].GetNormal(); + Vec3 cross = normal1.Cross(normal2); - // Determine the 2 face normals that are most apart - float dot = normal1.Dot(normal2); - if (dot < smallest_dot) - { - smallest_dot = dot; - best2[0] = faces[face1]; - best2[1] = faces[face2]; - } + // Determine the 2 face normals that are most apart + float dot = normal1.Dot(normal2); + if (dot < smallest_dot) + { + smallest_dot = dot; + best2[0] = faces[face1]; + best2[1] = faces[face2]; + } - // Determine the 3 face normals that form the largest tetrahedron - for (int face3 = face2 + 1; face3 < (int)faces.size(); ++face3) + // Determine the 3 face normals that form the largest tetrahedron + for (int face3 = face2 + 1; face3 < (int)faces.size(); ++face3) + { + Vec3 normal3 = mPlanes[faces[face3]].GetNormal(); + float volume = abs(cross.Dot(normal3)); + if (volume > biggest_volume) { - Vec3 normal3 = mPlanes[faces[face3]].GetNormal(); - float volume = abs(cross.Dot(normal3)); - if (volume > biggest_volume) - { - biggest_volume = volume; - best3[0] = faces[face1]; - best3[1] = faces[face2]; - best3[2] = faces[face3]; - } + biggest_volume = volume; + best3[0] = faces[face1]; + best3[1] = faces[face2]; + best3[2] = faces[face3]; } } } - - // If we didn't find 3 planes, use 2, if we didn't find 2 use 1 - if (best3[0] != -1) - faces = { best3[0], best3[1], best3[2] }; - else if (best2[0] != -1) - faces = { best2[0], best2[1] }; - else - faces = { faces[0] }; } + // If we didn't find 3 planes, use 2, if we didn't find 2 use 1 + if (best3[0] != -1) + faces = { best3[0], best3[1], best3[2] }; + else if (best2[0] != -1) + faces = { best2[0], best2[1] }; + else + faces = { faces[0] }; + // Copy the faces to the points buffer Point &point = mPoints[p]; point.mNumFaces = (int)faces.size(); diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/CylinderShape.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/CylinderShape.cpp index 2d723edf1..587dfaf0f 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/CylinderShape.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/CylinderShape.cpp @@ -59,12 +59,12 @@ static const std::vector sUnitCylinderTriangles = []() { Vec3 b2 = cTopFace[(i + 1) % num_verts] + bottom_offset; // Top - verts.push_back(Vec3(0.0f, 1.0f, 0.0f)); + verts.emplace_back(0.0f, 1.0f, 0.0f); verts.push_back(t1); verts.push_back(t2); // Bottom - verts.push_back(Vec3(0.0f, -1.0f, 0.0f)); + verts.emplace_back(0.0f, -1.0f, 0.0f); verts.push_back(b2); verts.push_back(b1); diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.cpp index 8b9e85c52..dd983718a 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,8 @@ JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL(HeightFieldShapeSettings) JPH_ADD_ATTRIBUTE(HeightFieldShapeSettings, mHeightSamples) JPH_ADD_ATTRIBUTE(HeightFieldShapeSettings, mOffset) JPH_ADD_ATTRIBUTE(HeightFieldShapeSettings, mScale) + JPH_ADD_ATTRIBUTE(HeightFieldShapeSettings, mMinHeightValue) + JPH_ADD_ATTRIBUTE(HeightFieldShapeSettings, mMaxHeightValue) JPH_ADD_ATTRIBUTE(HeightFieldShapeSettings, mSampleCount) JPH_ADD_ATTRIBUTE(HeightFieldShapeSettings, mBlockSize) JPH_ADD_ATTRIBUTE(HeightFieldShapeSettings, mBitsPerSample) @@ -106,8 +109,8 @@ ShapeSettings::ShapeResult HeightFieldShapeSettings::Create() const void HeightFieldShapeSettings::DetermineMinAndMaxSample(float &outMinValue, float &outMaxValue, float &outQuantizationScale) const { // Determine min and max value - outMinValue = FLT_MAX; - outMaxValue = -FLT_MAX; + outMinValue = mMinHeightValue; + outMaxValue = mMaxHeightValue; for (float h : mHeightSamples) if (h != cNoCollisionValue) { @@ -195,80 +198,155 @@ uint32 HeightFieldShapeSettings::CalculateBitsPerSampleForError(float inMaxError return bits_per_sample; } -void HeightFieldShape::CalculateActiveEdges(const HeightFieldShapeSettings &inSettings) +void HeightFieldShape::CalculateActiveEdges(uint inX, uint inY, uint inSizeX, uint inSizeY, const float *inHeights, uint inHeightsStartX, uint inHeightsStartY, uint inHeightsStride, float inHeightsScale, float inActiveEdgeCosThresholdAngle, TempAllocator &inAllocator) { - // Store active edges. The triangles are organized like this: - // + + - // | \ T1B | \ T2B - // e0 e2 | \ - // | T1A \ | T2A \ - // +--e1---+-------+ - // | \ T3B | \ T4B - // | \ | \ - // | T3A \ | T4A \ - // +-------+-------+ - // We store active edges e0 .. e2 as bits 0 .. 2. - // We store triangles horizontally then vertically (order T1A, T2A, T3A and T4A). - // The top edge and right edge of the heightfield are always active so we do not need to store them, - // therefore we only need to store (mSampleCount - 1)^2 * 3-bit - // The triangles T1B, T2B, T3B and T4B do not need to be stored, their active edges can be constructed from adjacent triangles. - // Add 1 byte padding so we can always read 1 uint16 to get the bits that cross an 8 bit boundary - uint count_min_1 = mSampleCount - 1; - uint count_min_1_sq = Square(count_min_1); - mActiveEdges.resize((count_min_1_sq * 3 + 7) / 8 + 1); - memset(&mActiveEdges[0], 0, mActiveEdges.size()); + // Allocate temporary buffer for normals + uint normals_size = 2 * inSizeX * inSizeY * sizeof(Vec3); + Vec3 *normals = (Vec3 *)inAllocator.Allocate(normals_size); // Calculate triangle normals and make normals zero for triangles that are missing - Array normals; - normals.resize(2 * count_min_1_sq); - memset(&normals[0], 0, normals.size() * sizeof(Vec3)); - for (uint y = 0; y < count_min_1; ++y) - for (uint x = 0; x < count_min_1; ++x) - if (!IsNoCollision(x, y) && !IsNoCollision(x + 1, y + 1)) + Vec3 *out_normal = normals; + for (uint y = 0; y < inSizeY; ++y) + for (uint x = 0; x < inSizeX; ++x) + { + // Get height on diagonal + const float *height_samples = inHeights + (inY - inHeightsStartY + y) * inHeightsStride + (inX - inHeightsStartX + x); + float x1y1_h = height_samples[0]; + float x2y2_h = height_samples[inHeightsStride + 1]; + if (x1y1_h != cNoCollisionValue && x2y2_h != cNoCollisionValue) { - Vec3 x1y1 = GetPosition(x, y); - Vec3 x2y2 = GetPosition(x + 1, y + 1); - - uint offset = 2 * (count_min_1 * y + x); - - if (!IsNoCollision(x, y + 1)) + // Calculate normal for lower left triangle (e.g. T1A) + float x1y2_h = height_samples[inHeightsStride]; + if (x1y2_h != cNoCollisionValue) { - Vec3 x1y2 = GetPosition(x, y + 1); - normals[offset] = (x2y2 - x1y2).Cross(x1y1 - x1y2).Normalized(); + Vec3 x2y2_minus_x1y2(mScale.GetX(), inHeightsScale * (x2y2_h - x1y2_h), 0); + Vec3 x1y1_minus_x1y2(0, inHeightsScale * (x1y1_h - x1y2_h), -mScale.GetZ()); + out_normal[0] = x2y2_minus_x1y2.Cross(x1y1_minus_x1y2).Normalized(); } + else + out_normal[0] = Vec3::sZero(); - if (!IsNoCollision(x + 1, y)) + // Calculate normal for upper right triangle (e.g. T1B) + float x2y1_h = height_samples[1]; + if (x2y1_h != cNoCollisionValue) { - Vec3 x2y1 = GetPosition(x + 1, y); - normals[offset + 1] = (x1y1 - x2y1).Cross(x2y2 - x2y1).Normalized(); + Vec3 x1y1_minus_x2y1(-mScale.GetX(), inHeightsScale * (x1y1_h - x2y1_h), 0); + Vec3 x2y2_minus_x2y1(0, inHeightsScale * (x2y2_h - x2y1_h), mScale.GetZ()); + out_normal[1] = x1y1_minus_x2y1.Cross(x2y2_minus_x2y1).Normalized(); } + else + out_normal[1] = Vec3::sZero(); + } + else + { + out_normal[0] = Vec3::sZero(); + out_normal[1] = Vec3::sZero(); } + out_normal += 2; + } + // Calculate active edges - for (uint y = 0; y < count_min_1; ++y) - for (uint x = 0; x < count_min_1; ++x) + const Vec3 *in_normal = normals; + uint global_bit_pos = 3 * (inY * (mSampleCount - 1) + inX); + for (uint y = 0; y < inSizeY; ++y) + { + for (uint x = 0; x < inSizeX; ++x) { - // Calculate vertex positions. - // We don't check 'no colliding' since those normals will be zero and sIsEdgeActive will return true - Vec3 x1y1 = GetPosition(x, y); - Vec3 x1y2 = GetPosition(x, y + 1); - Vec3 x2y2 = GetPosition(x + 1, y + 1); + // Get vertex heights + const float *height_samples = inHeights + (inY - inHeightsStartY + y) * inHeightsStride + (inX - inHeightsStartX + x); + float x1y1_h = height_samples[0]; + float x1y2_h = height_samples[inHeightsStride]; + float x2y2_h = height_samples[inHeightsStride + 1]; + bool x1y1_valid = x1y1_h != cNoCollisionValue; + bool x1y2_valid = x1y2_h != cNoCollisionValue; + bool x2y2_valid = x2y2_h != cNoCollisionValue; // Calculate the edge flags (3 bits) - uint offset = 2 * (count_min_1 * y + x); - bool edge0_active = x == 0 || ActiveEdges::IsEdgeActive(normals[offset], normals[offset - 1], x1y2 - x1y1, inSettings.mActiveEdgeCosThresholdAngle); - bool edge1_active = y == count_min_1 - 1 || ActiveEdges::IsEdgeActive(normals[offset], normals[offset + 2 * count_min_1 + 1], x2y2 - x1y2, inSettings.mActiveEdgeCosThresholdAngle); - bool edge2_active = ActiveEdges::IsEdgeActive(normals[offset], normals[offset + 1], x1y1 - x2y2, inSettings.mActiveEdgeCosThresholdAngle); - uint16 edge_flags = (edge0_active? 0b001 : 0) | (edge1_active? 0b010 : 0) | (edge2_active? 0b100 : 0); + // See diagram in the next function for the edge numbering + uint16 edge_mask = 0b111; + uint16 edge_flags = 0; + + // Edge 0 + if (x == 0) + edge_mask &= 0b110; // We need normal x - 1 which we didn't calculate, don't update this edge + else if (x1y1_valid && x1y2_valid) + { + Vec3 edge0_direction(0, inHeightsScale * (x1y2_h - x1y1_h), mScale.GetZ()); + if (ActiveEdges::IsEdgeActive(in_normal[0], in_normal[-1], edge0_direction, inActiveEdgeCosThresholdAngle)) + edge_flags |= 0b001; + } + + // Edge 1 + if (y == inSizeY - 1) + edge_mask &= 0b101; // We need normal y + 1 which we didn't calculate, don't update this edge + else if (x1y2_valid && x2y2_valid) + { + Vec3 edge1_direction(mScale.GetX(), inHeightsScale * (x2y2_h - x1y2_h), 0); + if (ActiveEdges::IsEdgeActive(in_normal[0], in_normal[2 * inSizeX + 1], edge1_direction, inActiveEdgeCosThresholdAngle)) + edge_flags |= 0b010; + } + + // Edge 2 + if (x1y1_valid && x2y2_valid) + { + Vec3 edge2_direction(-mScale.GetX(), inHeightsScale * (x1y1_h - x2y2_h), -mScale.GetZ()); + if (ActiveEdges::IsEdgeActive(in_normal[0], in_normal[1], edge2_direction, inActiveEdgeCosThresholdAngle)) + edge_flags |= 0b100; + } // Store the edge flags in the array - uint bit_pos = 3 * (y * count_min_1 + x); - uint byte_pos = bit_pos >> 3; - bit_pos &= 0b111; - edge_flags <<= bit_pos; - mActiveEdges[byte_pos] |= uint8(edge_flags); - mActiveEdges[byte_pos + 1] |= uint8(edge_flags >> 8); + uint byte_pos = global_bit_pos >> 3; + uint bit_pos = global_bit_pos & 0b111; + uint8 *edge_flags_ptr = &mActiveEdges[byte_pos]; + uint16 combined_edge_flags = uint16(edge_flags_ptr[0]) | uint16(uint16(edge_flags_ptr[1]) << 8); + combined_edge_flags &= ~(edge_mask << bit_pos); + combined_edge_flags |= edge_flags << bit_pos; + edge_flags_ptr[0] = uint8(combined_edge_flags); + edge_flags_ptr[1] = uint8(combined_edge_flags >> 8); + + in_normal += 2; + global_bit_pos += 3; } + + global_bit_pos += 3 * (mSampleCount - 1 - inSizeX); + } + + // Free temporary buffer for normals + inAllocator.Free(normals, normals_size); +} + +void HeightFieldShape::CalculateActiveEdges(const HeightFieldShapeSettings &inSettings) +{ + /* + Store active edges. The triangles are organized like this: + x ---> + + y + + + | \ T1B | \ T2B + | e0 e2 | \ + | | T1A \ | T2A \ + V +--e1---+-------+ + | \ T3B | \ T4B + | \ | \ + | T3A \ | T4A \ + +-------+-------+ + We store active edges e0 .. e2 as bits 0 .. 2. + We store triangles horizontally then vertically (order T1A, T2A, T3A and T4A). + The top edge and right edge of the heightfield are always active so we do not need to store them, + therefore we only need to store (mSampleCount - 1)^2 * 3-bit + The triangles T1B, T2B, T3B and T4B do not need to be stored, their active edges can be constructed from adjacent triangles. + Add 1 byte padding so we can always read 1 uint16 to get the bits that cross an 8 bit boundary + */ + mActiveEdges.resize((Square(mSampleCount - 1) * 3 + 7) / 8 + 1); + + // Make all edges active (if mSampleCount is bigger than inSettings.mSampleCount we need to fill up the padding, + // also edges at x = 0 and y = inSettings.mSampleCount - 1 are not updated) + memset(mActiveEdges.data(), 0xff, mActiveEdges.size()); + + // Now clear the edges that are not active + TempAllocatorMalloc allocator; + CalculateActiveEdges(0, 0, inSettings.mSampleCount - 1, inSettings.mSampleCount - 1, inSettings.mHeightSamples.data(), 0, 0, inSettings.mSampleCount, inSettings.mScale.GetY(), inSettings.mActiveEdgeCosThresholdAngle, allocator); } void HeightFieldShape::StoreMaterialIndices(const HeightFieldShapeSettings &inSettings) @@ -615,6 +693,18 @@ inline void HeightFieldShape::sGetRangeBlockOffsetAndStride(uint inNumBlocks, ui outRangeBlockStride = (inNumBlocks + 1) >> 1; } +inline void HeightFieldShape::GetRangeBlock(uint inBlockX, uint inBlockY, uint inRangeBlockOffset, uint inRangeBlockStride, RangeBlock *&outBlock, uint &outIndexInBlock) +{ + JPH_ASSERT(inBlockX < GetNumBlocks() && inBlockY < GetNumBlocks()); + + // Convert to location of range block + uint rbx = inBlockX >> 1; + uint rby = inBlockY >> 1; + outIndexInBlock = ((inBlockY & 1) << 1) + (inBlockX & 1); + + outBlock = &mRangeBlocks[inRangeBlockOffset + rby * inRangeBlockStride + rbx]; +} + inline void HeightFieldShape::GetBlockOffsetAndScale(uint inBlockX, uint inBlockY, uint inRangeBlockOffset, uint inRangeBlockStride, float &outBlockOffset, float &outBlockScale) const { JPH_ASSERT(inBlockX < GetNumBlocks() && inBlockY < GetNumBlocks()); @@ -743,6 +833,301 @@ bool HeightFieldShape::ProjectOntoSurface(Vec3Arg inLocalPosition, Vec3 &outSurf } } +void HeightFieldShape::GetHeights(uint inX, uint inY, uint inSizeX, uint inSizeY, float *outHeights, uint inHeightsStride) const +{ + if (inSizeX == 0 || inSizeY == 0) + return; + + JPH_ASSERT(inX % mBlockSize == 0 && inY % mBlockSize == 0); + JPH_ASSERT(inX < mSampleCount && inY < mSampleCount); + JPH_ASSERT(inX + inSizeX <= mSampleCount && inY + inSizeY <= mSampleCount); + + // Test if there are any samples + if (mHeightSamples.empty()) + { + // No samples, return the offset + float offset = mOffset.GetY(); + for (uint y = 0; y < inSizeY; ++y, outHeights += inHeightsStride) + for (uint x = 0; x < inSizeX; ++x) + outHeights[x] = offset; + } + else + { + // Calculate offset and stride + uint num_blocks = GetNumBlocks(); + uint range_block_offset, range_block_stride; + sGetRangeBlockOffsetAndStride(num_blocks, sGetMaxLevel(num_blocks), range_block_offset, range_block_stride); + + // Loop over blocks + uint block_start_x = inX / mBlockSize; + uint block_start_y = inY / mBlockSize; + uint num_blocks_x = inSizeX / mBlockSize; + uint num_blocks_y = inSizeY / mBlockSize; + for (uint block_y = 0; block_y < num_blocks_y; ++block_y) + for (uint block_x = 0; block_x < num_blocks_x; ++block_x) + { + // Get offset and scale for block + float offset, scale; + GetBlockOffsetAndScale(block_start_x + block_x, block_start_y + block_y, range_block_offset, range_block_stride, offset, scale); + + // Adjust by global offset and scale + // Note: This is the math applied in GetPosition() written out to reduce calculations in the inner loop + scale *= mScale.GetY(); + offset = mOffset.GetY() + mScale.GetY() * offset + 0.5f * scale; + + // Loop over samples in block + for (uint sample_y = 0; sample_y < mBlockSize; ++sample_y) + for (uint sample_x = 0; sample_x < mBlockSize; ++sample_x) + { + // Calculate output coordinate + uint output_x = block_x * mBlockSize + sample_x; + uint output_y = block_y * mBlockSize + sample_y; + + // Get quantized value + uint8 height_sample = GetHeightSample(inX + output_x, inY + output_y); + + // Dequantize + float h = height_sample != mSampleMask? offset + height_sample * scale : cNoCollisionValue; + outHeights[output_y * inHeightsStride + output_x] = h; + } + } + } +} + +void HeightFieldShape::SetHeights(uint inX, uint inY, uint inSizeX, uint inSizeY, const float *inHeights, uint inHeightsStride, TempAllocator &inAllocator, float inActiveEdgeCosThresholdAngle) +{ + if (inSizeX == 0 || inSizeY == 0) + return; + + JPH_ASSERT(!mHeightSamples.empty()); + JPH_ASSERT(inX % mBlockSize == 0 && inY % mBlockSize == 0); + JPH_ASSERT(inX < mSampleCount && inY < mSampleCount); + JPH_ASSERT(inX + inSizeX <= mSampleCount && inY + inSizeY <= mSampleCount); + + // If we have a block in negative x/y direction, we will affect its range so we need to take it into account + bool need_temp_heights = false; + uint affected_x = inX; + uint affected_y = inY; + uint affected_size_x = inSizeX; + uint affected_size_y = inSizeY; + if (inX > 0) { affected_x -= mBlockSize; affected_size_x += mBlockSize; need_temp_heights = true; } + if (inY > 0) { affected_y -= mBlockSize; affected_size_y += mBlockSize; need_temp_heights = true; } + + // If we have a block in positive x/y direction, our ranges are affected by it so we need to take it into account + uint heights_size_x = affected_size_x; + uint heights_size_y = affected_size_y; + if (inX + inSizeX < mSampleCount) { heights_size_x += mBlockSize; need_temp_heights = true; } + if (inY + inSizeY < mSampleCount) { heights_size_y += mBlockSize; need_temp_heights = true; } + + // Get heights for affected area + const float *heights; + float *temp_heights; + if (need_temp_heights) + { + // Fetch the surrounding height data (note we're forced to recompress this data with a potentially different range so there will be some precision loss here) + temp_heights = (float *)inAllocator.Allocate(heights_size_x * heights_size_y * sizeof(float)); + heights = temp_heights; + + // We need to fill in the following areas: + // + // +-----------------+ + // | 2 | + // |---+---------+---| + // | | | | + // | 3 | 1 | 4 | + // | | | | + // |---+---------+---| + // | 5 | + // +-----------------+ + // + // 1. The area that is affected by the new heights (we just copy these) + // 2-5. These areas are either needed to calculate the range of the affected blocks or they need to be recompressed with a different range + uint offset_x = inX - affected_x; + uint offset_y = inY - affected_y; + + // Area 2 + GetHeights(affected_x, affected_y, heights_size_x, offset_y, temp_heights, heights_size_x); + float *area3_start = temp_heights + offset_y * heights_size_x; + + // Area 3 + GetHeights(affected_x, inY, offset_x, inSizeY, area3_start, heights_size_x); + + // Area 1 + float *area1_start = area3_start + offset_x; + for (uint y = 0; y < inSizeY; ++y, area1_start += heights_size_x, inHeights += inHeightsStride) + memcpy(area1_start, inHeights, inSizeX * sizeof(float)); + + // Area 4 + uint area4_x = inX + inSizeX; + GetHeights(area4_x, inY, affected_x + heights_size_x - area4_x, inSizeY, area3_start + area4_x - affected_x, heights_size_x); + + // Area 5 + uint area5_y = inY + inSizeY; + float *area5_start = temp_heights + (area5_y - affected_y) * heights_size_x; + GetHeights(affected_x, area5_y, heights_size_x, affected_y + heights_size_y - area5_y, area5_start, heights_size_x); + } + else + { + // We can directly use the input buffer because there are no extra edges to take into account + heights = inHeights; + heights_size_x = inHeightsStride; + temp_heights = nullptr; + } + + // Calculate offset and stride + uint num_blocks = GetNumBlocks(); + uint range_block_offset, range_block_stride; + uint max_level = sGetMaxLevel(num_blocks); + sGetRangeBlockOffsetAndStride(num_blocks, max_level, range_block_offset, range_block_stride); + + // Loop over blocks + uint block_start_x = affected_x / mBlockSize; + uint block_start_y = affected_y / mBlockSize; + uint num_blocks_x = affected_size_x / mBlockSize; + uint num_blocks_y = affected_size_y / mBlockSize; + for (uint block_y = 0, sample_start_y = 0; block_y < num_blocks_y; ++block_y, sample_start_y += mBlockSize) + for (uint block_x = 0, sample_start_x = 0; block_x < num_blocks_x; ++block_x, sample_start_x += mBlockSize) + { + // Determine quantized min and max value for block + // Note that we need to include 1 extra row in the positive x/y direction to account for connecting triangles + int min_value = 0xffff; + int max_value = 0; + uint sample_x_end = min(sample_start_x + mBlockSize + 1, mSampleCount - affected_x); + uint sample_y_end = min(sample_start_y + mBlockSize + 1, mSampleCount - affected_y); + for (uint sample_y = sample_start_y; sample_y < sample_y_end; ++sample_y) + for (uint sample_x = sample_start_x; sample_x < sample_x_end; ++sample_x) + { + float h = heights[sample_y * heights_size_x + sample_x]; + if (h != cNoCollisionValue) + { + int quantized_height = Clamp((int)floor((h - mOffset.GetY()) / mScale.GetY()), 0, int(cMaxHeightValue16 - 1)); + min_value = min(min_value, quantized_height); + max_value = max(max_value, quantized_height + 1); + } + } + if (min_value > max_value) + min_value = max_value = cNoCollisionValue16; + + // Update range for block + RangeBlock *range_block; + uint index_in_block; + GetRangeBlock(block_start_x + block_x, block_start_y + block_y, range_block_offset, range_block_stride, range_block, index_in_block); + range_block->mMin[index_in_block] = uint16(min_value); + range_block->mMax[index_in_block] = uint16(max_value); + + // Get offset and scale for block + float offset_block = float(min_value); + float scale_block = float(max_value - min_value) / float(mSampleMask); + + // Calculate scale and offset using the formula used in GetPosition() solved for the quantized height (excluding 0.5 because we round down while quantizing) + float scale = scale_block * mScale.GetY(); + float offset = mOffset.GetY() + offset_block * mScale.GetY(); + + // Loop over samples in block + sample_x_end = sample_start_x + mBlockSize; + sample_y_end = sample_start_y + mBlockSize; + for (uint sample_y = sample_start_y; sample_y < sample_y_end; ++sample_y) + for (uint sample_x = sample_start_x; sample_x < sample_x_end; ++sample_x) + { + // Quantize height + float h = heights[sample_y * heights_size_x + sample_x]; + uint8 quantized_height = h != cNoCollisionValue? uint8(Clamp((int)floor((h - offset) / scale), 0, int(mSampleMask) - 1)) : mSampleMask; + + // Determine bit position of sample + uint sample = ((affected_y + sample_y) * mSampleCount + affected_x + sample_x) * uint(mBitsPerSample); + uint byte_pos = sample >> 3; + uint bit_pos = sample & 0b111; + + // Update the height value sample + JPH_ASSERT(byte_pos + 1 < mHeightSamples.size()); + uint8 *height_samples = mHeightSamples.data() + byte_pos; + uint16 height_sample = uint16(height_samples[0]) | uint16(uint16(height_samples[1]) << 8); + height_sample &= ~(uint16(mSampleMask) << bit_pos); + height_sample |= uint16(quantized_height) << bit_pos; + height_samples[0] = uint8(height_sample); + height_samples[1] = uint8(height_sample >> 8); + } + } + + // Update active edges + // Note that we must take an extra row on all sides to account for connecting triangles + uint ae_x = inX > 1? inX - 2 : 0; + uint ae_y = inY > 1? inY - 2 : 0; + uint ae_sx = min(inX + inSizeX + 1, mSampleCount - 1) - ae_x; + uint ae_sy = min(inY + inSizeY + 1, mSampleCount - 1) - ae_y; + CalculateActiveEdges(ae_x, ae_y, ae_sx, ae_sy, heights, affected_x, affected_y, heights_size_x, 1.0f, inActiveEdgeCosThresholdAngle, inAllocator); + + // Free temporary buffer + if (temp_heights != nullptr) + inAllocator.Free(temp_heights, heights_size_x * heights_size_y * sizeof(float)); + + // Update hierarchy of range blocks + while (max_level > 1) + { + // Get offset and stride for destination blocks + uint dst_range_block_offset, dst_range_block_stride; + sGetRangeBlockOffsetAndStride(num_blocks >> 1, max_level - 1, dst_range_block_offset, dst_range_block_stride); + + // If we're starting halfway through a 2x2 block, we need to process one extra block since we take steps of 2 blocks below + uint block_x_end = (block_start_x & 1) && block_start_x + num_blocks_x < num_blocks? num_blocks_x + 1 : num_blocks_x; + uint block_y_end = (block_start_y & 1) && block_start_y + num_blocks_y < num_blocks? num_blocks_y + 1 : num_blocks_y; + + // Loop over all affected blocks + for (uint block_y = 0; block_y < block_y_end; block_y += 2) + for (uint block_x = 0; block_x < block_x_end; block_x += 2) + { + // Get source range block + RangeBlock *src_range_block; + uint index_in_src_block; + GetRangeBlock(block_start_x + block_x, block_start_y + block_y, range_block_offset, range_block_stride, src_range_block, index_in_src_block); + + // Determine quantized min and max value for the entire 2x2 block + uint16 min_value = 0xffff; + uint16 max_value = 0; + for (uint i = 0; i < 4; ++i) + if (src_range_block->mMin[i] != cNoCollisionValue16) + { + min_value = min(min_value, src_range_block->mMin[i]); + max_value = max(max_value, src_range_block->mMax[i]); + } + + // Write to destination block + RangeBlock *dst_range_block; + uint index_in_dst_block; + GetRangeBlock((block_start_x + block_x) >> 1, (block_start_y + block_y) >> 1, dst_range_block_offset, dst_range_block_stride, dst_range_block, index_in_dst_block); + dst_range_block->mMin[index_in_dst_block] = uint16(min_value); + dst_range_block->mMax[index_in_dst_block] = uint16(max_value); + } + + // Go up one level + --max_level; + num_blocks >>= 1; + block_start_x >>= 1; + block_start_y >>= 1; + num_blocks_x = min((num_blocks_x + 1) >> 1, num_blocks); + num_blocks_y = min((num_blocks_y + 1) >> 1, num_blocks); + + // Update stride and offset for source to old destination + range_block_offset = dst_range_block_offset; + range_block_stride = dst_range_block_stride; + } + + // Calculate new min and max sample for the entire height field + mMinSample = 0xffff; + mMaxSample = 0; + for (uint i = 0; i < 4; ++i) + if (mRangeBlocks[0].mMin[i] != cNoCollisionValue16) + { + mMinSample = min(mMinSample, mRangeBlocks[0].mMin[i]); + mMaxSample = max(mMaxSample, mRangeBlocks[0].mMax[i]); + } + +#ifdef JPH_DEBUG_RENDERER + // Invalidate temporary rendering data + mGeometry.clear(); +#endif +} + MassProperties HeightFieldShape::GetMassProperties() const { // Object should always be static, return default mass properties @@ -872,6 +1257,8 @@ void HeightFieldShape::GetSupportingFace(const SubShapeID &inSubShapeID, Vec3Arg inline uint8 HeightFieldShape::GetEdgeFlags(uint inX, uint inY, uint inTriangle) const { + JPH_ASSERT(inX < mSampleCount - 1 && inY < mSampleCount - 1); + if (inTriangle == 0) { // The edge flags for this triangle are directly stored, find the right 3 bits @@ -887,7 +1274,7 @@ inline uint8 HeightFieldShape::GetEdgeFlags(uint inX, uint inY, uint inTriangle) { // We don't store this triangle directly, we need to look at our three neighbours to construct the edge flags uint8 edge0 = (GetEdgeFlags(inX, inY, 0) & 0b100) != 0? 0b001 : 0; // Diagonal edge - uint8 edge1 = inX == mSampleCount - 1 || (GetEdgeFlags(inX + 1, inY, 0) & 0b001) != 0? 0b010 : 0; // Vertical edge + uint8 edge1 = inX == mSampleCount - 2 || (GetEdgeFlags(inX + 1, inY, 0) & 0b001) != 0? 0b010 : 0; // Vertical edge uint8 edge2 = inY == 0 || (GetEdgeFlags(inX, inY - 1, 0) & 0b010) != 0? 0b100 : 0; // Horizontal edge return edge0 | edge1 | edge2; } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.h index 1fb87e122..122c66a3c 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.h @@ -14,24 +14,25 @@ JPH_NAMESPACE_BEGIN class ConvexShape; class CollideShapeSettings; +class TempAllocator; /// Constants for HeightFieldShape, this was moved out of the HeightFieldShape because of a linker bug namespace HeightFieldShapeConstants { /// Value used to create gaps in the height field - constexpr float cNoCollisionValue = FLT_MAX; + constexpr float cNoCollisionValue = FLT_MAX; /// Stack size to use during WalkHeightField - constexpr int cStackSize = 128; + constexpr int cStackSize = 128; /// A position in the hierarchical grid is defined by a level (which grid), x and y position. We encode this in a single uint32 as: level << 28 | y << 14 | x - constexpr uint cNumBitsXY = 14; - constexpr uint cMaskBitsXY = (1 << cNumBitsXY) - 1; - constexpr uint cLevelShift = 2 * cNumBitsXY; + constexpr uint cNumBitsXY = 14; + constexpr uint cMaskBitsXY = (1 << cNumBitsXY) - 1; + constexpr uint cLevelShift = 2 * cNumBitsXY; /// When height samples are converted to 16 bit: - constexpr uint16 cNoCollisionValue16 = 0xffff; ///< This is the magic value for 'no collision' - constexpr uint16 cMaxHeightValue16 = 0xfffe; ///< This is the maximum allowed height value + constexpr uint16 cNoCollisionValue16 = 0xffff; ///< This is the magic value for 'no collision' + constexpr uint16 cMaxHeightValue16 = 0xfffe; ///< This is the maximum allowed height value }; /// Class that constructs a HeightFieldShape @@ -71,6 +72,12 @@ class JPH_EXPORT HeightFieldShapeSettings final : public ShapeSettings Vec3 mScale = Vec3::sReplicate(1.0f); uint32 mSampleCount = 0; + /// Artifical minimal value of mHeightSamples, used for compression and can be used to update the terrain after creating with lower height values. If there are any lower values in mHeightSamples, this value will be ignored. + float mMinHeightValue = FLT_MAX; + + /// Artifical maximum value of mHeightSamples, used for compression and can be used to update the terrain after creating with higher height values. If there are any higher values in mHeightSamples, this value will be ignored. + float mMaxHeightValue = -FLT_MAX; + /// The heightfield is divided in blocks of mBlockSize * mBlockSize * 2 triangles and the acceleration structure culls blocks only, /// bigger block sizes reduce memory consumption but also reduce query performance. Sensible values are [2, 8], does not need to be /// a power of 2. Note that at run-time we'll perform one more grid subdivision, so the effective block size is half of what is provided here. @@ -81,7 +88,10 @@ class JPH_EXPORT HeightFieldShapeSettings final : public ShapeSettings /// Also note that increasing mBlockSize saves more memory than reducing the amount of bits per sample. uint32 mBitsPerSample = 8; + /// An array of mSampleCount^2 height samples. Samples are stored in row major order, so the sample at (x, y) is at index y * mSampleCount + x. Array mHeightSamples; + + /// An array of (mSampleCount - 1)^2 material indices. Array mMaterialIndices; /// The materials of square at (x, y) is: mMaterials[mMaterialIndices[x + y * (mSampleCount - 1)]] @@ -90,7 +100,7 @@ class JPH_EXPORT HeightFieldShapeSettings final : public ShapeSettings /// Cosine of the threshold angle (if the angle between the two triangles is bigger than this, the edge is active, note that a concave edge is always inactive). /// Setting this value too small can cause ghost collisions with edges, setting it too big can cause depenetration artifacts (objects not depenetrating quickly). /// Valid ranges are between cos(0 degrees) and cos(90 degrees). The default value is cos(5 degrees). - float mActiveEdgeCosThresholdAngle = 0.996195f; // cos(5 degrees) + float mActiveEdgeCosThresholdAngle = 0.996195f; // cos(5 degrees) }; /// A height field shape. Cannot be used as a dynamic object. @@ -104,16 +114,22 @@ class JPH_EXPORT HeightFieldShape final : public Shape HeightFieldShape(const HeightFieldShapeSettings &inSettings, ShapeResult &outResult); // See Shape::MustBeStatic - virtual bool MustBeStatic() const override { return true; } + virtual bool MustBeStatic() const override { return true; } + + /// Get the size of the height field. Note that this will always be rounded up to the nearest multiple of GetBlockSize(). + inline uint GetSampleCount() const { return mSampleCount; } + + /// Get the size of a block + inline uint GetBlockSize() const { return mBlockSize; } // See Shape::GetLocalBounds virtual AABox GetLocalBounds() const override; // See Shape::GetSubShapeIDBitsRecursive - virtual uint GetSubShapeIDBitsRecursive() const override { return GetSubShapeIDBits(); } + virtual uint GetSubShapeIDBitsRecursive() const override { return GetSubShapeIDBits(); } // See Shape::GetInnerRadius - virtual float GetInnerRadius() const override { return 0.0f; } + virtual float GetInnerRadius() const override { return 0.0f; } // See Shape::GetMassProperties virtual MassProperties GetMassProperties() const override; @@ -165,6 +181,28 @@ class JPH_EXPORT HeightFieldShape final : public Shape /// When there is no surface position (because of a hole or because the point is outside the heightfield) the function will return false. bool ProjectOntoSurface(Vec3Arg inLocalPosition, Vec3 &outSurfacePosition, SubShapeID &outSubShapeID) const; + /// Get the height values of a block of data. + /// Note that the height values are decompressed so will be slightly different from what the shape was originally created with. + /// @param inX Start X position, must be a multiple of mBlockSize and in the range [0, mSampleCount - 1] + /// @param inY Start Y position, must be a multiple of mBlockSize and in the range [0, mSampleCount - 1] + /// @param inSizeX Number of samples in X direction, must be a multiple of mBlockSize and in the range [0, mSampleCount - inX] + /// @param inSizeY Number of samples in Y direction, must be a multiple of mBlockSize and in the range [0, mSampleCount - inX] + /// @param outHeights Returned height values, must be at least inSizeX * inSizeY floats. Values are returned in x-major order and can be cNoCollisionValue. + /// @param inHeightsStride Stride in floats between two consecutive rows of outHeights. + void GetHeights(uint inX, uint inY, uint inSizeX, uint inSizeY, float *outHeights, uint inHeightsStride) const; + + /// Set the height values of a block of data. + /// Note that this requires decompressing and recompressing a border of size mBlockSize in the negative x/y direction so will cause some precision loss. + /// @param inX Start X position, must be a multiple of mBlockSize and in the range [0, mSampleCount - 1] + /// @param inY Start Y position, must be a multiple of mBlockSize and in the range [0, mSampleCount - 1] + /// @param inSizeX Number of samples in X direction, must be a multiple of mBlockSize and in the range [0, mSampleCount - inX] + /// @param inSizeY Number of samples in Y direction, must be a multiple of mBlockSize and in the range [0, mSampleCount - inX] + /// @param inHeights The new height values to set, must be an array of inSizeX * inSizeY floats, can be cNoCollisionValue. + /// @param inHeightsStride Stride in floats between two consecutive rows of outHeights. + /// @param inAllocator Allocator to use for temporary memory + /// @param inActiveEdgeCosThresholdAngle Cosine of the threshold angle (if the angle between the two triangles is bigger than this, the edge is active, note that a concave edge is always inactive). + void SetHeights(uint inX, uint inY, uint inSizeX, uint inSizeY, const float *inHeights, uint inHeightsStride, TempAllocator &inAllocator, float inActiveEdgeCosThresholdAngle = 0.996195f); + // See Shape virtual void SaveBinaryState(StreamOut &inStream) const override; virtual void SaveMaterialState(PhysicsMaterialList &outMaterials) const override; @@ -174,7 +212,7 @@ class JPH_EXPORT HeightFieldShape final : public Shape virtual Stats GetStats() const override; // See Shape::GetVolume - virtual float GetVolume() const override { return 0; } + virtual float GetVolume() const override { return 0; } #ifdef JPH_DEBUG_RENDERER // Settings @@ -189,12 +227,15 @@ class JPH_EXPORT HeightFieldShape final : public Shape virtual void RestoreBinaryState(StreamIn &inStream) override; private: - class DecodingContext; ///< Context class for walking through all nodes of a heightfield - struct HSGetTrianglesContext; ///< Context class for GetTrianglesStart/Next + class DecodingContext; ///< Context class for walking through all nodes of a heightfield + struct HSGetTrianglesContext; ///< Context class for GetTrianglesStart/Next /// Calculate commonly used values and store them in the shape void CacheValues(); + /// Calculate bit mask for all active edges in the heightfield for a specific region + void CalculateActiveEdges(uint inX, uint inY, uint inSizeX, uint inSizeY, const float *inHeights, uint inHeightsStartX, uint inHeightsStartY, uint inHeightsStride, float inHeightsScale, float inActiveEdgeCosThresholdAngle, TempAllocator &inAllocator); + /// Calculate bit mask for all active edges in the heightfield void CalculateActiveEdges(const HeightFieldShapeSettings &inSettings); @@ -202,10 +243,10 @@ class JPH_EXPORT HeightFieldShape final : public Shape void StoreMaterialIndices(const HeightFieldShapeSettings &inSettings); /// Get the amount of horizontal/vertical blocks - inline uint GetNumBlocks() const { return mSampleCount / mBlockSize; } + inline uint GetNumBlocks() const { return mSampleCount / mBlockSize; } /// Get the maximum level (amount of grids) of the tree - static inline uint sGetMaxLevel(uint inNumBlocks) { return 32 - CountLeadingZeros(inNumBlocks - 1); } + static inline uint sGetMaxLevel(uint inNumBlocks) { return 32 - CountLeadingZeros(inNumBlocks - 1); } /// Get the range block offset and stride for GetBlockOffsetAndScale static inline void sGetRangeBlockOffsetAndStride(uint inNumBlocks, uint inMaxLevel, uint &outRangeBlockOffset, uint &outRangeBlockStride); @@ -246,6 +287,9 @@ class JPH_EXPORT HeightFieldShape final : public Shape uint16 mMax[4]; }; + /// For block (inBlockX, inBlockY) get get the range block and the entry in the range block + inline void GetRangeBlock(uint inBlockX, uint inBlockY, uint inRangeBlockOffset, uint inRangeBlockStride, RangeBlock *&outBlock, uint &outIndexInBlock); + /// Offset of first RangedBlock in grid per level static const uint sGridOffsets[]; @@ -255,25 +299,25 @@ class JPH_EXPORT HeightFieldShape final : public Shape Vec3 mScale = Vec3::sReplicate(1.0f); /// Height data - uint32 mSampleCount = 0; ///< See HeightFieldShapeSettings::mSampleCount - uint32 mBlockSize = 2; ///< See HeightFieldShapeSettings::mBlockSize - uint8 mBitsPerSample = 8; ///< See HeightFieldShapeSettings::mBitsPerSample - uint8 mSampleMask = 0xff; ///< All bits set for a sample: (1 << mBitsPerSample) - 1, used to indicate that there's no collision - uint16 mMinSample = HeightFieldShapeConstants::cNoCollisionValue16; ///< Min and max value in mHeightSamples quantized to 16 bit, for calculating bounding box + uint32 mSampleCount = 0; ///< See HeightFieldShapeSettings::mSampleCount + uint32 mBlockSize = 2; ///< See HeightFieldShapeSettings::mBlockSize + uint8 mBitsPerSample = 8; ///< See HeightFieldShapeSettings::mBitsPerSample + uint8 mSampleMask = 0xff; ///< All bits set for a sample: (1 << mBitsPerSample) - 1, used to indicate that there's no collision + uint16 mMinSample = HeightFieldShapeConstants::cNoCollisionValue16; ///< Min and max value in mHeightSamples quantized to 16 bit, for calculating bounding box uint16 mMaxSample = HeightFieldShapeConstants::cNoCollisionValue16; - Array mRangeBlocks; ///< Hierarchical grid of range data describing the height variations within 1 block. The grid for level starts at offset sGridOffsets[] - Array mHeightSamples; ///< mBitsPerSample-bit height samples. Value [0, mMaxHeightValue] maps to highest detail grid in mRangeBlocks [mMin, mMax]. mNoCollisionValue is reserved to indicate no collision. - Array mActiveEdges; ///< (mSampleCount - 1)^2 * 3-bit active edge flags. + Array mRangeBlocks; ///< Hierarchical grid of range data describing the height variations within 1 block. The grid for level starts at offset sGridOffsets[] + Array mHeightSamples; ///< mBitsPerSample-bit height samples. Value [0, mMaxHeightValue] maps to highest detail grid in mRangeBlocks [mMin, mMax]. mNoCollisionValue is reserved to indicate no collision. + Array mActiveEdges; ///< (mSampleCount - 1)^2 * 3-bit active edge flags. /// Materials - PhysicsMaterialList mMaterials; ///< The materials of square at (x, y) is: mMaterials[mMaterialIndices[x + y * (mSampleCount - 1)]] - Array mMaterialIndices; ///< Compressed to the minimum amount of bits per material index (mSampleCount - 1) * (mSampleCount - 1) * mNumBitsPerMaterialIndex bits of data - uint32 mNumBitsPerMaterialIndex = 0; ///< Number of bits per material index + PhysicsMaterialList mMaterials; ///< The materials of square at (x, y) is: mMaterials[mMaterialIndices[x + y * (mSampleCount - 1)]] + Array mMaterialIndices; ///< Compressed to the minimum amount of bits per material index (mSampleCount - 1) * (mSampleCount - 1) * mNumBitsPerMaterialIndex bits of data + uint32 mNumBitsPerMaterialIndex = 0; ///< Number of bits per material index #ifdef JPH_DEBUG_RENDERER /// Temporary rendering data mutable Array mGeometry; - mutable bool mCachedUseMaterialColors = false; ///< This is used to regenerate the triangle batch if the drawing settings change + mutable bool mCachedUseMaterialColors = false; ///< This is used to regenerate the triangle batch if the drawing settings change #endif // JPH_DEBUG_RENDERER }; diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/MeshShape.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/MeshShape.cpp index 645fbd7da..09a70dc45 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/MeshShape.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/MeshShape.cpp @@ -234,6 +234,7 @@ void MeshShape::sFindActiveEdges(const MeshShapeSettings &inSettings, IndexedTri } JPH_ASSERT(false); + JPH_CRASH; return ~uint(0); } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/Shape.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/Shape.h index 2e142c72f..9ae1e6a19 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/Shape.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Collision/Shape/Shape.h @@ -352,7 +352,8 @@ class JPH_EXPORT Shape : public RefTarget, public NonCopyable ///@name Binary serialization of the shape. Note that this saves the 'cooked' shape in a format which will not be backwards compatible for newer library versions. /// In this case you need to recreate the shape from the ShapeSettings object and save it again. The user is expected to call SaveBinaryState followed by SaveMaterialState and SaveSubShapeState. /// The stream should be stored as is and the material and shape list should be saved using the applications own serialization system (e.g. by assigning an ID to each pointer). - /// When restoring data, call sRestoreFromBinararyState to get the shape and then call RestoreMaterialState and RestoreSubShapeState to restore the pointers to the external objects. + /// When restoring data, call sRestoreFromBinaryState to get the shape and then call RestoreMaterialState and RestoreSubShapeState to restore the pointers to the external objects. + /// Alternatively you can use SaveWithChildren and sRestoreWithChildren to save and restore the shape and all its child shapes and materials in a single stream. ///@{ /// Saves the contents of the shape in binary form to inStream. diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/AxisConstraintPart.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/AxisConstraintPart.h index 78ba091f2..e95b5d98b 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/AxisConstraintPart.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/AxisConstraintPart.h @@ -43,7 +43,7 @@ class AxisConstraintPart { /// Internal helper function to update velocities of bodies after Lagrange multiplier is calculated template - JPH_INLINE bool ApplyVelocityStep(MotionProperties *ioMotionProperties1, MotionProperties *ioMotionProperties2, Vec3Arg inWorldSpaceAxis, float inLambda) const + JPH_INLINE bool ApplyVelocityStep(MotionProperties *ioMotionProperties1, float inInvMass1, MotionProperties *ioMotionProperties2, float inInvMass2, Vec3Arg inWorldSpaceAxis, float inLambda) const { // Apply impulse if delta is not zero if (inLambda != 0.0f) @@ -57,12 +57,12 @@ class AxisConstraintPart // v' = v + M^-1 P if constexpr (Type1 == EMotionType::Dynamic) { - ioMotionProperties1->SubLinearVelocityStep((inLambda * mInverseMass1) * inWorldSpaceAxis); + ioMotionProperties1->SubLinearVelocityStep((inLambda * inInvMass1) * inWorldSpaceAxis); ioMotionProperties1->SubAngularVelocityStep(inLambda * Vec3::sLoadFloat3Unsafe(mInvI1_R1PlusUxAxis)); } if constexpr (Type2 == EMotionType::Dynamic) { - ioMotionProperties2->AddLinearVelocityStep((inLambda * mInverseMass2) * inWorldSpaceAxis); + ioMotionProperties2->AddLinearVelocityStep((inLambda * inInvMass2) * inWorldSpaceAxis); ioMotionProperties2->AddAngularVelocityStep(inLambda * Vec3::sLoadFloat3Unsafe(mInvI2_R2xAxis)); } return true; @@ -81,7 +81,6 @@ class AxisConstraintPart Vec3 r1_plus_u_x_axis; if constexpr (Type1 != EMotionType::Static) { - mInverseMass1 = inInvMass1; r1_plus_u_x_axis = inR1PlusU.Cross(inWorldSpaceAxis); r1_plus_u_x_axis.StoreFloat3(&mR1PlusUxAxis); } @@ -89,14 +88,12 @@ class AxisConstraintPart { #ifdef _DEBUG Vec3::sNaN().StoreFloat3(&mR1PlusUxAxis); - mInverseMass1 = numeric_limits::quiet_NaN(); #endif } Vec3 r2_x_axis; if constexpr (Type2 != EMotionType::Static) { - mInverseMass2 = inInvMass2; r2_x_axis = inR2.Cross(inWorldSpaceAxis); r2_x_axis.StoreFloat3(&mR2xAxis); } @@ -104,7 +101,6 @@ class AxisConstraintPart { #ifdef _DEBUG Vec3::sNaN().StoreFloat3(&mR2xAxis); - mInverseMass2 = numeric_limits::quiet_NaN(); #endif } @@ -115,7 +111,7 @@ class AxisConstraintPart { Vec3 invi1_r1_plus_u_x_axis = inInvI1.Multiply3x3(r1_plus_u_x_axis); invi1_r1_plus_u_x_axis.StoreFloat3(&mInvI1_R1PlusUxAxis); - inv_effective_mass = mInverseMass1 + invi1_r1_plus_u_x_axis.Dot(r1_plus_u_x_axis); + inv_effective_mass = inInvMass1 + invi1_r1_plus_u_x_axis.Dot(r1_plus_u_x_axis); } else { @@ -128,7 +124,7 @@ class AxisConstraintPart { Vec3 invi2_r2_x_axis = inInvI2.Multiply3x3(r2_x_axis); invi2_r2_x_axis.StoreFloat3(&mInvI2_R2xAxis); - inv_effective_mass += mInverseMass2 + invi2_r2_x_axis.Dot(r2_x_axis); + inv_effective_mass += inInvMass2 + invi2_r2_x_axis.Dot(r2_x_axis); } else { @@ -148,17 +144,18 @@ class AxisConstraintPart case EMotionType::Dynamic: { const MotionProperties *mp1 = inBody1.GetMotionPropertiesUnchecked(); - Mat44 invi1 = inBody1.GetInverseInertia(); + float inv_m1 = mp1->GetInverseMass(); + Mat44 inv_i1 = inBody1.GetInverseInertia(); switch (inBody2.GetMotionType()) { case EMotionType::Dynamic: - return TemplatedCalculateInverseEffectiveMass(mp1->GetInverseMass(), invi1, inR1PlusU, inBody2.GetMotionPropertiesUnchecked()->GetInverseMass(), inBody2.GetInverseInertia(), inR2, inWorldSpaceAxis); + return TemplatedCalculateInverseEffectiveMass(inv_m1, inv_i1, inR1PlusU, inBody2.GetMotionPropertiesUnchecked()->GetInverseMass(), inBody2.GetInverseInertia(), inR2, inWorldSpaceAxis); case EMotionType::Kinematic: - return TemplatedCalculateInverseEffectiveMass(mp1->GetInverseMass(), invi1, inR1PlusU, 0 /* Will not be used */, Mat44() /* Will not be used */, inR2, inWorldSpaceAxis); + return TemplatedCalculateInverseEffectiveMass(inv_m1, inv_i1, inR1PlusU, 0 /* Will not be used */, Mat44() /* Will not be used */, inR2, inWorldSpaceAxis); case EMotionType::Static: - return TemplatedCalculateInverseEffectiveMass(mp1->GetInverseMass(), invi1, inR1PlusU, 0 /* Will not be used */, Mat44() /* Will not be used */, inR2, inWorldSpaceAxis); + return TemplatedCalculateInverseEffectiveMass(inv_m1, inv_i1, inR1PlusU, 0 /* Will not be used */, Mat44() /* Will not be used */, inR2, inWorldSpaceAxis); default: break; @@ -182,6 +179,48 @@ class AxisConstraintPart return 0.0f; } + /// Internal helper function to calculate the inverse effective mass, version that supports mass scaling + JPH_INLINE float CalculateInverseEffectiveMassWithMassOverride(const Body &inBody1, float inInvMass1, float inInvInertiaScale1, Vec3Arg inR1PlusU, const Body &inBody2, float inInvMass2, float inInvInertiaScale2, Vec3Arg inR2, Vec3Arg inWorldSpaceAxis) + { + // Dispatch to the correct templated form + switch (inBody1.GetMotionType()) + { + case EMotionType::Dynamic: + { + Mat44 inv_i1 = inInvInertiaScale1 * inBody1.GetInverseInertia(); + switch (inBody2.GetMotionType()) + { + case EMotionType::Dynamic: + return TemplatedCalculateInverseEffectiveMass(inInvMass1, inv_i1, inR1PlusU, inInvMass2, inInvInertiaScale2 * inBody2.GetInverseInertia(), inR2, inWorldSpaceAxis); + + case EMotionType::Kinematic: + return TemplatedCalculateInverseEffectiveMass(inInvMass1, inv_i1, inR1PlusU, 0 /* Will not be used */, Mat44() /* Will not be used */, inR2, inWorldSpaceAxis); + + case EMotionType::Static: + return TemplatedCalculateInverseEffectiveMass(inInvMass1, inv_i1, inR1PlusU, 0 /* Will not be used */, Mat44() /* Will not be used */, inR2, inWorldSpaceAxis); + + default: + break; + } + break; + } + + case EMotionType::Kinematic: + JPH_ASSERT(inBody2.IsDynamic()); + return TemplatedCalculateInverseEffectiveMass(0 /* Will not be used */, Mat44() /* Will not be used */, inR1PlusU, inInvMass2, inInvInertiaScale2 * inBody2.GetInverseInertia(), inR2, inWorldSpaceAxis); + + case EMotionType::Static: + JPH_ASSERT(inBody2.IsDynamic()); + return TemplatedCalculateInverseEffectiveMass(0 /* Will not be used */, Mat44() /* Will not be used */, inR1PlusU, inInvMass2, inInvInertiaScale2 * inBody2.GetInverseInertia(), inR2, inWorldSpaceAxis); + + default: + break; + } + + JPH_ASSERT(false); + return 0.0f; + } + public: /// Templated form of CalculateConstraintProperties with the motion types baked in template @@ -214,6 +253,30 @@ class AxisConstraintPart } } + /// Calculate properties used during the functions below, version that supports mass scaling + /// @param inBody1 The first body that this constraint is attached to + /// @param inBody2 The second body that this constraint is attached to + /// @param inInvMass1 The inverse mass of body 1 (only used when body 1 is dynamic) + /// @param inInvMass2 The inverse mass of body 2 (only used when body 2 is dynamic) + /// @param inInvInertiaScale1 Scale factor for the inverse inertia of body 1 + /// @param inInvInertiaScale2 Scale factor for the inverse inertia of body 2 + /// @param inR1PlusU See equations above (r1 + u) + /// @param inR2 See equations above (r2) + /// @param inWorldSpaceAxis Axis along which the constraint acts (normalized, pointing from body 1 to 2) + /// @param inBias Bias term (b) for the constraint impulse: lambda = J v + b + inline void CalculateConstraintPropertiesWithMassOverride(const Body &inBody1, float inInvMass1, float inInvInertiaScale1, Vec3Arg inR1PlusU, const Body &inBody2, float inInvMass2, float inInvInertiaScale2, Vec3Arg inR2, Vec3Arg inWorldSpaceAxis, float inBias = 0.0f) + { + float inv_effective_mass = CalculateInverseEffectiveMassWithMassOverride(inBody1, inInvMass1, inInvInertiaScale1, inR1PlusU, inBody2, inInvMass2, inInvInertiaScale2, inR2, inWorldSpaceAxis); + + if (inv_effective_mass == 0.0f) + Deactivate(); + else + { + mEffectiveMass = 1.0f / inv_effective_mass; + mSpringPart.CalculateSpringPropertiesWithBias(inBias); + } + } + /// Calculate properties used during the functions below /// @param inDeltaTime Time step /// @param inBody1 The first body that this constraint is attached to @@ -284,11 +347,11 @@ class AxisConstraintPart /// Templated form of WarmStart with the motion types baked in template - inline void TemplatedWarmStart(MotionProperties *ioMotionProperties1, MotionProperties *ioMotionProperties2, Vec3Arg inWorldSpaceAxis, float inWarmStartImpulseRatio) + inline void TemplatedWarmStart(MotionProperties *ioMotionProperties1, float inInvMass1, MotionProperties *ioMotionProperties2, float inInvMass2, Vec3Arg inWorldSpaceAxis, float inWarmStartImpulseRatio) { mTotalLambda *= inWarmStartImpulseRatio; - ApplyVelocityStep(ioMotionProperties1, ioMotionProperties2, inWorldSpaceAxis, mTotalLambda); + ApplyVelocityStep(ioMotionProperties1, inInvMass1, ioMotionProperties2, inInvMass2, inWorldSpaceAxis, mTotalLambda); } /// Must be called from the WarmStartVelocityConstraint call to apply the previous frame's impulses @@ -309,14 +372,14 @@ class AxisConstraintPart if (motion_type1 == EMotionType::Dynamic) { if (motion_type2 == EMotionType::Dynamic) - TemplatedWarmStart(motion_properties1, motion_properties2, inWorldSpaceAxis, inWarmStartImpulseRatio); + TemplatedWarmStart(motion_properties1, motion_properties1->GetInverseMass(), motion_properties2, motion_properties2->GetInverseMass(), inWorldSpaceAxis, inWarmStartImpulseRatio); else - TemplatedWarmStart(motion_properties1, motion_properties2, inWorldSpaceAxis, inWarmStartImpulseRatio); + TemplatedWarmStart(motion_properties1, motion_properties1->GetInverseMass(), motion_properties2, 0.0f /* Unused */, inWorldSpaceAxis, inWarmStartImpulseRatio); } else { JPH_ASSERT(motion_type2 == EMotionType::Dynamic); - TemplatedWarmStart(motion_properties1, motion_properties2, inWorldSpaceAxis, inWarmStartImpulseRatio); + TemplatedWarmStart(motion_properties1, 0.0f /* Unused */, motion_properties2, motion_properties2->GetInverseMass(), inWorldSpaceAxis, inWarmStartImpulseRatio); } } @@ -352,24 +415,24 @@ class AxisConstraintPart /// Templated form of SolveVelocityConstraint with the motion types baked in, part 2: apply new lambda template - JPH_INLINE bool TemplatedSolveVelocityConstraintApplyLambda(MotionProperties *ioMotionProperties1, MotionProperties *ioMotionProperties2, Vec3Arg inWorldSpaceAxis, float inTotalLambda) + JPH_INLINE bool TemplatedSolveVelocityConstraintApplyLambda(MotionProperties *ioMotionProperties1, float inInvMass1, MotionProperties *ioMotionProperties2, float inInvMass2, Vec3Arg inWorldSpaceAxis, float inTotalLambda) { float delta_lambda = inTotalLambda - mTotalLambda; // Calculate change in lambda mTotalLambda = inTotalLambda; // Store accumulated impulse - return ApplyVelocityStep(ioMotionProperties1, ioMotionProperties2, inWorldSpaceAxis, delta_lambda); + return ApplyVelocityStep(ioMotionProperties1, inInvMass1, ioMotionProperties2, inInvMass2, inWorldSpaceAxis, delta_lambda); } /// Templated form of SolveVelocityConstraint with the motion types baked in template - inline bool TemplatedSolveVelocityConstraint(MotionProperties *ioMotionProperties1, MotionProperties *ioMotionProperties2, Vec3Arg inWorldSpaceAxis, float inMinLambda, float inMaxLambda) + inline bool TemplatedSolveVelocityConstraint(MotionProperties *ioMotionProperties1, float inInvMass1, MotionProperties *ioMotionProperties2, float inInvMass2, Vec3Arg inWorldSpaceAxis, float inMinLambda, float inMaxLambda) { float total_lambda = TemplatedSolveVelocityConstraintGetTotalLambda(ioMotionProperties1, ioMotionProperties2, inWorldSpaceAxis); // Clamp impulse to specified range total_lambda = Clamp(total_lambda, inMinLambda, inMaxLambda); - return TemplatedSolveVelocityConstraintApplyLambda(ioMotionProperties1, ioMotionProperties2, inWorldSpaceAxis, total_lambda); + return TemplatedSolveVelocityConstraintApplyLambda(ioMotionProperties1, inInvMass1, ioMotionProperties2, inInvMass2, inWorldSpaceAxis, total_lambda); } /// Iteratively update the velocity constraint. Makes sure d/dt C(...) = 0, where C is the constraint equation. @@ -393,13 +456,66 @@ class AxisConstraintPart switch (motion_type2) { case EMotionType::Dynamic: - return TemplatedSolveVelocityConstraint(motion_properties1, motion_properties2, inWorldSpaceAxis, inMinLambda, inMaxLambda); + return TemplatedSolveVelocityConstraint(motion_properties1, motion_properties1->GetInverseMass(), motion_properties2, motion_properties2->GetInverseMass(), inWorldSpaceAxis, inMinLambda, inMaxLambda); + + case EMotionType::Kinematic: + return TemplatedSolveVelocityConstraint(motion_properties1, motion_properties1->GetInverseMass(), motion_properties2, 0.0f /* Unused */, inWorldSpaceAxis, inMinLambda, inMaxLambda); + + case EMotionType::Static: + return TemplatedSolveVelocityConstraint(motion_properties1, motion_properties1->GetInverseMass(), motion_properties2, 0.0f /* Unused */, inWorldSpaceAxis, inMinLambda, inMaxLambda); + + default: + JPH_ASSERT(false); + break; + } + break; + + case EMotionType::Kinematic: + JPH_ASSERT(motion_type2 == EMotionType::Dynamic); + return TemplatedSolveVelocityConstraint(motion_properties1, 0.0f /* Unused */, motion_properties2, motion_properties2->GetInverseMass(), inWorldSpaceAxis, inMinLambda, inMaxLambda); + + case EMotionType::Static: + JPH_ASSERT(motion_type2 == EMotionType::Dynamic); + return TemplatedSolveVelocityConstraint(motion_properties1, 0.0f /* Unused */, motion_properties2, motion_properties2->GetInverseMass(), inWorldSpaceAxis, inMinLambda, inMaxLambda); + + default: + JPH_ASSERT(false); + break; + } + + return false; + } + + /// Iteratively update the velocity constraint. Makes sure d/dt C(...) = 0, where C is the constraint equation. + /// @param ioBody1 The first body that this constraint is attached to + /// @param ioBody2 The second body that this constraint is attached to + /// @param inInvMass1 The inverse mass of body 1 (only used when body 1 is dynamic) + /// @param inInvMass2 The inverse mass of body 2 (only used when body 2 is dynamic) + /// @param inWorldSpaceAxis Axis along which the constraint acts (normalized) + /// @param inMinLambda Minimum value of constraint impulse to apply (N s) + /// @param inMaxLambda Maximum value of constraint impulse to apply (N s) + inline bool SolveVelocityConstraintWithMassOverride(Body &ioBody1, float inInvMass1, Body &ioBody2, float inInvMass2, Vec3Arg inWorldSpaceAxis, float inMinLambda, float inMaxLambda) + { + EMotionType motion_type1 = ioBody1.GetMotionType(); + MotionProperties *motion_properties1 = ioBody1.GetMotionPropertiesUnchecked(); + + EMotionType motion_type2 = ioBody2.GetMotionType(); + MotionProperties *motion_properties2 = ioBody2.GetMotionPropertiesUnchecked(); + + // Dispatch to the correct templated form + switch (motion_type1) + { + case EMotionType::Dynamic: + switch (motion_type2) + { + case EMotionType::Dynamic: + return TemplatedSolveVelocityConstraint(motion_properties1, inInvMass1, motion_properties2, inInvMass2, inWorldSpaceAxis, inMinLambda, inMaxLambda); case EMotionType::Kinematic: - return TemplatedSolveVelocityConstraint(motion_properties1, motion_properties2, inWorldSpaceAxis, inMinLambda, inMaxLambda); + return TemplatedSolveVelocityConstraint(motion_properties1, inInvMass1, motion_properties2, 0.0f /* Unused */, inWorldSpaceAxis, inMinLambda, inMaxLambda); case EMotionType::Static: - return TemplatedSolveVelocityConstraint(motion_properties1, motion_properties2, inWorldSpaceAxis, inMinLambda, inMaxLambda); + return TemplatedSolveVelocityConstraint(motion_properties1, inInvMass1, motion_properties2, 0.0f /* Unused */, inWorldSpaceAxis, inMinLambda, inMaxLambda); default: JPH_ASSERT(false); @@ -409,11 +525,11 @@ class AxisConstraintPart case EMotionType::Kinematic: JPH_ASSERT(motion_type2 == EMotionType::Dynamic); - return TemplatedSolveVelocityConstraint(motion_properties1, motion_properties2, inWorldSpaceAxis, inMinLambda, inMaxLambda); + return TemplatedSolveVelocityConstraint(motion_properties1, 0.0f /* Unused */, motion_properties2, inInvMass2, inWorldSpaceAxis, inMinLambda, inMaxLambda); case EMotionType::Static: JPH_ASSERT(motion_type2 == EMotionType::Dynamic); - return TemplatedSolveVelocityConstraint(motion_properties1, motion_properties2, inWorldSpaceAxis, inMinLambda, inMaxLambda); + return TemplatedSolveVelocityConstraint(motion_properties1, 0.0f /* Unused */, motion_properties2, inInvMass2, inWorldSpaceAxis, inMinLambda, inMaxLambda); default: JPH_ASSERT(false); @@ -458,12 +574,63 @@ class AxisConstraintPart // integrate + a position integrate and then discard the velocity change. if (ioBody1.IsDynamic()) { - ioBody1.SubPositionStep((lambda * mInverseMass1) * inWorldSpaceAxis); + ioBody1.SubPositionStep((lambda * ioBody1.GetMotionProperties()->GetInverseMass()) * inWorldSpaceAxis); + ioBody1.SubRotationStep(lambda * Vec3::sLoadFloat3Unsafe(mInvI1_R1PlusUxAxis)); + } + if (ioBody2.IsDynamic()) + { + ioBody2.AddPositionStep((lambda * ioBody2.GetMotionProperties()->GetInverseMass()) * inWorldSpaceAxis); + ioBody2.AddRotationStep(lambda * Vec3::sLoadFloat3Unsafe(mInvI2_R2xAxis)); + } + return true; + } + + return false; + } + + /// Iteratively update the position constraint. Makes sure C(...) = 0. + /// @param ioBody1 The first body that this constraint is attached to + /// @param ioBody2 The second body that this constraint is attached to + /// @param inInvMass1 The inverse mass of body 1 (only used when body 1 is dynamic) + /// @param inInvMass2 The inverse mass of body 2 (only used when body 2 is dynamic) + /// @param inWorldSpaceAxis Axis along which the constraint acts (normalized) + /// @param inC Value of the constraint equation (C) + /// @param inBaumgarte Baumgarte constant (fraction of the error to correct) + inline bool SolvePositionConstraintWithMassOverride(Body &ioBody1, float inInvMass1, Body &ioBody2, float inInvMass2, Vec3Arg inWorldSpaceAxis, float inC, float inBaumgarte) const + { + // Only apply position constraint when the constraint is hard, otherwise the velocity bias will fix the constraint + if (inC != 0.0f && !mSpringPart.IsActive()) + { + // Calculate lagrange multiplier (lambda) for Baumgarte stabilization: + // + // lambda = -K^-1 * beta / dt * C + // + // We should divide by inDeltaTime, but we should multiply by inDeltaTime in the Euler step below so they're cancelled out + float lambda = -mEffectiveMass * inBaumgarte * inC; + + // Directly integrate velocity change for one time step + // + // Euler velocity integration: + // dv = M^-1 P + // + // Impulse: + // P = J^T lambda + // + // Euler position integration: + // x' = x + dv * dt + // + // Note we don't accumulate velocities for the stabilization. This is using the approach described in 'Modeling and + // Solving Constraints' by Erin Catto presented at GDC 2007. On slide 78 it is suggested to split up the Baumgarte + // stabilization for positional drift so that it does not actually add to the momentum. We combine an Euler velocity + // integrate + a position integrate and then discard the velocity change. + if (ioBody1.IsDynamic()) + { + ioBody1.SubPositionStep((lambda * inInvMass1) * inWorldSpaceAxis); ioBody1.SubRotationStep(lambda * Vec3::sLoadFloat3Unsafe(mInvI1_R1PlusUxAxis)); } if (ioBody2.IsDynamic()) { - ioBody2.AddPositionStep((lambda * mInverseMass2) * inWorldSpaceAxis); + ioBody2.AddPositionStep((lambda * inInvMass2) * inWorldSpaceAxis); ioBody2.AddRotationStep(lambda * Vec3::sLoadFloat3Unsafe(mInvI2_R2xAxis)); } return true; @@ -501,8 +668,6 @@ class AxisConstraintPart Float3 mR2xAxis; Float3 mInvI1_R1PlusUxAxis; Float3 mInvI2_R2xAxis; - float mInverseMass1; - float mInverseMass2; float mEffectiveMass = 0.0f; SpringPart mSpringPart; float mTotalLambda = 0.0f; diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/DualAxisConstraintPart.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/DualAxisConstraintPart.h index 71260ab28..20d0b02fa 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/DualAxisConstraintPart.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/DualAxisConstraintPart.h @@ -11,37 +11,39 @@ JPH_NAMESPACE_BEGIN -/// Constrains movement on 2 axis -/// -/// @see "Constraints Derivation for Rigid Body Simulation in 3D" - Daniel Chappuis, section 2.3.1 -/// -/// Constraint equation (eq 51): -/// -/// \f[C = \begin{bmatrix} (p_2 - p_1) \cdot n_1 \\ (p_2 - p_1) \cdot n_2\end{bmatrix}\f] -/// -/// Jacobian (transposed) (eq 55): -/// -/// \f[J^T = \begin{bmatrix} -/// -n_1 & -n_2 \\ -/// -(r_1 + u) \times n_1 & -(r_1 + u) \times n_2 \\ -/// n_1 & n_2 \\ -/// r_2 \times n_1 & r_2 \times n_2 -/// \end{bmatrix}\f] -/// -/// Used terms (here and below, everything in world space):\n -/// n1, n2 = constraint axis (normalized).\n -/// p1, p2 = constraint points.\n -/// r1 = p1 - x1.\n -/// r2 = p2 - x2.\n -/// u = x2 + r2 - x1 - r1 = p2 - p1.\n -/// x1, x2 = center of mass for the bodies.\n -/// v = [v1, w1, v2, w2].\n -/// v1, v2 = linear velocity of body 1 and 2.\n -/// w1, w2 = angular velocity of body 1 and 2.\n -/// M = mass matrix, a diagonal matrix of the mass and inertia with diagonal [m1, I1, m2, I2].\n -/// \f$K^{-1} = \left( J M^{-1} J^T \right)^{-1}\f$ = effective mass.\n -/// b = velocity bias.\n -/// \f$\beta\f$ = baumgarte constant. +/** + Constrains movement on 2 axis + + @see "Constraints Derivation for Rigid Body Simulation in 3D" - Daniel Chappuis, section 2.3.1 + + Constraint equation (eq 51): + + \f[C = \begin{bmatrix} (p_2 - p_1) \cdot n_1 \\ (p_2 - p_1) \cdot n_2\end{bmatrix}\f] + + Jacobian (transposed) (eq 55): + + \f[J^T = \begin{bmatrix} + -n_1 & -n_2 \\ + -(r_1 + u) \times n_1 & -(r_1 + u) \times n_2 \\ + n_1 & n_2 \\ + r_2 \times n_1 & r_2 \times n_2 + \end{bmatrix}\f] + + Used terms (here and below, everything in world space):\n + n1, n2 = constraint axis (normalized).\n + p1, p2 = constraint points.\n + r1 = p1 - x1.\n + r2 = p2 - x2.\n + u = x2 + r2 - x1 - r1 = p2 - p1.\n + x1, x2 = center of mass for the bodies.\n + v = [v1, w1, v2, w2].\n + v1, v2 = linear velocity of body 1 and 2.\n + w1, w2 = angular velocity of body 1 and 2.\n + M = mass matrix, a diagonal matrix of the mass and inertia with diagonal [m1, I1, m2, I2].\n + \f$K^{-1} = \left( J M^{-1} J^T \right)^{-1}\f$ = effective mass.\n + b = velocity bias.\n + \f$\beta\f$ = baumgarte constant. +**/ class DualAxisConstraintPart { public: diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/HingeRotationConstraintPart.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/HingeRotationConstraintPart.h index 70459ad63..5f566f701 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/HingeRotationConstraintPart.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/HingeRotationConstraintPart.h @@ -11,33 +11,35 @@ JPH_NAMESPACE_BEGIN -/// Constrains rotation around 2 axis so that it only allows rotation around 1 axis -/// -/// Based on: "Constraints Derivation for Rigid Body Simulation in 3D" - Daniel Chappuis, section 2.4.1 -/// -/// Constraint equation (eq 87): -/// -/// \f[C = \begin{bmatrix}a_1 \cdot b_2 \\ a_1 \cdot c_2\end{bmatrix}\f] -/// -/// Jacobian (eq 90): -/// -/// \f[J = \begin{bmatrix} -/// 0 & -b_2 \times a_1 & 0 & b_2 \times a_1 \\ -/// 0 & -c_2 \times a_1 & 0 & c2 \times a_1 -/// \end{bmatrix}\f] -/// -/// Used terms (here and below, everything in world space):\n -/// a1 = hinge axis on body 1.\n -/// b2, c2 = axis perpendicular to hinge axis on body 2.\n -/// x1, x2 = center of mass for the bodies.\n -/// v = [v1, w1, v2, w2].\n -/// v1, v2 = linear velocity of body 1 and 2.\n -/// w1, w2 = angular velocity of body 1 and 2.\n -/// M = mass matrix, a diagonal matrix of the mass and inertia with diagonal [m1, I1, m2, I2].\n -/// \f$K^{-1} = \left( J M^{-1} J^T \right)^{-1}\f$ = effective mass.\n -/// b = velocity bias.\n -/// \f$\beta\f$ = baumgarte constant.\n -/// E = identity matrix. +/** + Constrains rotation around 2 axis so that it only allows rotation around 1 axis + + Based on: "Constraints Derivation for Rigid Body Simulation in 3D" - Daniel Chappuis, section 2.4.1 + + Constraint equation (eq 87): + + \f[C = \begin{bmatrix}a_1 \cdot b_2 \\ a_1 \cdot c_2\end{bmatrix}\f] + + Jacobian (eq 90): + + \f[J = \begin{bmatrix} + 0 & -b_2 \times a_1 & 0 & b_2 \times a_1 \\ + 0 & -c_2 \times a_1 & 0 & c2 \times a_1 + \end{bmatrix}\f] + + Used terms (here and below, everything in world space):\n + a1 = hinge axis on body 1.\n + b2, c2 = axis perpendicular to hinge axis on body 2.\n + x1, x2 = center of mass for the bodies.\n + v = [v1, w1, v2, w2].\n + v1, v2 = linear velocity of body 1 and 2.\n + w1, w2 = angular velocity of body 1 and 2.\n + M = mass matrix, a diagonal matrix of the mass and inertia with diagonal [m1, I1, m2, I2].\n + \f$K^{-1} = \left( J M^{-1} J^T \right)^{-1}\f$ = effective mass.\n + b = velocity bias.\n + \f$\beta\f$ = baumgarte constant.\n + E = identity matrix. +**/ class HingeRotationConstraintPart { public: diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/PointConstraintPart.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/PointConstraintPart.h index 9cd361f04..62f663f9e 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/PointConstraintPart.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/PointConstraintPart.h @@ -90,12 +90,12 @@ class PointConstraintPart if (inBody1.IsDynamic()) { const MotionProperties *mp1 = inBody1.GetMotionProperties(); - Mat44 invi1 = mp1->GetInverseInertiaForRotation(inRotation1); + Mat44 inv_i1 = mp1->GetInverseInertiaForRotation(inRotation1); summed_inv_mass = mp1->GetInverseMass(); Mat44 r1x = Mat44::sCrossProduct(mR1); - mInvI1_R1X = invi1.Multiply3x3(r1x); - inv_effective_mass = r1x.Multiply3x3(invi1).Multiply3x3RightTransposed(r1x); + mInvI1_R1X = inv_i1.Multiply3x3(r1x); + inv_effective_mass = r1x.Multiply3x3(inv_i1).Multiply3x3RightTransposed(r1x); } else { @@ -108,12 +108,12 @@ class PointConstraintPart if (inBody2.IsDynamic()) { const MotionProperties *mp2 = inBody2.GetMotionProperties(); - Mat44 invi2 = mp2->GetInverseInertiaForRotation(inRotation2); + Mat44 inv_i2 = mp2->GetInverseInertiaForRotation(inRotation2); summed_inv_mass += mp2->GetInverseMass(); Mat44 r2x = Mat44::sCrossProduct(mR2); - mInvI2_R2X = invi2.Multiply3x3(r2x); - inv_effective_mass += r2x.Multiply3x3(invi2).Multiply3x3RightTransposed(r2x); + mInvI2_R2X = inv_i2.Multiply3x3(r2x); + inv_effective_mass += r2x.Multiply3x3(inv_i2).Multiply3x3RightTransposed(r2x); } else { diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/RotationQuatConstraintPart.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/RotationQuatConstraintPart.h index 27ef9aa68..3a52aba4b 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/RotationQuatConstraintPart.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ConstraintPart/RotationQuatConstraintPart.h @@ -132,15 +132,15 @@ class RotationQuatConstraintPart Mat44 jp = (Mat44::sQuatLeftMultiply(0.5f * inBody1.GetRotation().Conjugated()) * Mat44::sQuatRightMultiply(inBody2.GetRotation() * inInvInitialOrientation)).GetRotationSafe(); // Calculate properties used during constraint solving - Mat44 invi1 = inBody1.IsDynamic()? inBody1.GetMotionProperties()->GetInverseInertiaForRotation(inRotation1) : Mat44::sZero(); - Mat44 invi2 = inBody2.IsDynamic()? inBody2.GetMotionProperties()->GetInverseInertiaForRotation(inRotation2) : Mat44::sZero(); - mInvI1_JPT = invi1.Multiply3x3RightTransposed(jp); - mInvI2_JPT = invi2.Multiply3x3RightTransposed(jp); + Mat44 inv_i1 = inBody1.IsDynamic()? inBody1.GetMotionProperties()->GetInverseInertiaForRotation(inRotation1) : Mat44::sZero(); + Mat44 inv_i2 = inBody2.IsDynamic()? inBody2.GetMotionProperties()->GetInverseInertiaForRotation(inRotation2) : Mat44::sZero(); + mInvI1_JPT = inv_i1.Multiply3x3RightTransposed(jp); + mInvI2_JPT = inv_i2.Multiply3x3RightTransposed(jp); // Calculate effective mass: K^-1 = (J M^-1 J^T)^-1 // = (JP * I1^-1 * JP^T + JP * I2^-1 * JP^T)^-1 // = (JP * (I1^-1 + I2^-1) * JP^T)^-1 - if (!mEffectiveMass.SetInversed3x3(jp.Multiply3x3(invi1 + invi2).Multiply3x3RightTransposed(jp))) + if (!mEffectiveMass.SetInversed3x3(jp.Multiply3x3(inv_i1 + inv_i2).Multiply3x3RightTransposed(jp))) Deactivate(); else mEffectiveMass_JP = mEffectiveMass.Multiply3x3(jp); diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.cpp index 73508f060..d5db4b0d3 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.cpp @@ -33,14 +33,14 @@ bool ContactConstraintManager::sDrawContactManifolds = false; // ContactConstraintManager::WorldContactPoint //////////////////////////////////////////////////////////////////////////////////////////////////////// -void ContactConstraintManager::WorldContactPoint::CalculateNonPenetrationConstraintProperties(const Body &inBody1, const Body &inBody2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal) +void ContactConstraintManager::WorldContactPoint::CalculateNonPenetrationConstraintProperties(const Body &inBody1, float inInvMass1, float inInvInertiaScale1, const Body &inBody2, float inInvMass2, float inInvInertiaScale2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal) { // Calculate collision points relative to body RVec3 p = 0.5_r * (inWorldSpacePosition1 + inWorldSpacePosition2); Vec3 r1 = Vec3(p - inBody1.GetCenterOfMassPosition()); Vec3 r2 = Vec3(p - inBody2.GetCenterOfMassPosition()); - mNonPenetrationConstraint.CalculateConstraintProperties(inBody1, r1, inBody2, r2, inWorldSpaceNormal); + mNonPenetrationConstraint.CalculateConstraintPropertiesWithMassOverride(inBody1, inInvMass1, inInvInertiaScale1, r1, inBody2, inInvMass2, inInvInertiaScale2, r2, inWorldSpaceNormal); } template @@ -649,31 +649,25 @@ template JPH_INLINE void ContactConstraintManager::TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2) { // Calculate scaled mass and inertia - float inv_m1; Mat44 inv_i1; if constexpr (Type1 == EMotionType::Dynamic) { const MotionProperties *mp1 = inBody1.GetMotionPropertiesUnchecked(); - inv_m1 = inSettings.mInvMassScale1 * mp1->GetInverseMass(); inv_i1 = inSettings.mInvInertiaScale1 * mp1->GetInverseInertiaForRotation(inTransformBody1.GetRotation()); } else { - inv_m1 = 0.0f; inv_i1 = Mat44::sZero(); } - float inv_m2; Mat44 inv_i2; if constexpr (Type2 == EMotionType::Dynamic) { const MotionProperties *mp2 = inBody2.GetMotionPropertiesUnchecked(); - inv_m2 = inSettings.mInvMassScale2 * mp2->GetInverseMass(); inv_i2 = inSettings.mInvInertiaScale2 * mp2->GetInverseInertiaForRotation(inTransformBody2.GetRotation()); } else { - inv_m2 = 0.0f; inv_i2 = Mat44::sZero(); } @@ -689,7 +683,7 @@ JPH_INLINE void ContactConstraintManager::TemplatedCalculateFrictionAndNonPenetr { RVec3 p1 = inTransformBody1 * Vec3::sLoadFloat3Unsafe(wcp.mContactPoint->mPosition1); RVec3 p2 = inTransformBody2 * Vec3::sLoadFloat3Unsafe(wcp.mContactPoint->mPosition2); - wcp.TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(inDeltaTime, inBody1, inBody2, inv_m1, inv_m2, inv_i1, inv_i2, p1, p2, ws_normal, t1, t2, inSettings, min_velocity_for_restitution); + wcp.TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(inDeltaTime, inBody1, inBody2, ioConstraint.mInvMass1, ioConstraint.mInvMass2, inv_i1, inv_i2, p1, p2, ws_normal, t1, t2, inSettings, min_velocity_for_restitution); } } @@ -894,6 +888,10 @@ void ContactConstraintManager::GetContactsFromCache(ContactAllocator &ioContactA constraint.mSortKey = input_hash; world_space_normal.StoreFloat3(&constraint.mWorldSpaceNormal); constraint.mCombinedFriction = settings.mCombinedFriction; + constraint.mInvMass1 = body1->GetMotionPropertiesUnchecked() != nullptr? settings.mInvMassScale1 * body1->GetMotionPropertiesUnchecked()->GetInverseMassUnchecked() : 0.0f; + constraint.mInvInertiaScale1 = settings.mInvInertiaScale1; + constraint.mInvMass2 = body2->GetMotionPropertiesUnchecked() != nullptr? settings.mInvMassScale2 * body2->GetMotionPropertiesUnchecked()->GetInverseMassUnchecked() : 0.0f; + constraint.mInvInertiaScale2 = settings.mInvInertiaScale2; constraint.mContactPoints.resize(output_cm->mNumContactPoints); for (uint32 i = 0; i < output_cm->mNumContactPoints; ++i) { @@ -1085,6 +1083,10 @@ bool ContactConstraintManager::TemplatedAddContactConstraint(ContactAllocator &i constraint.mSortKey = key_hash; inManifold.mWorldSpaceNormal.StoreFloat3(&constraint.mWorldSpaceNormal); constraint.mCombinedFriction = settings.mCombinedFriction; + constraint.mInvMass1 = inBody1.GetMotionPropertiesUnchecked() != nullptr? settings.mInvMassScale1 * inBody1.GetMotionPropertiesUnchecked()->GetInverseMassUnchecked() : 0.0f; + constraint.mInvInertiaScale1 = settings.mInvInertiaScale1; + constraint.mInvMass2 = inBody2.GetMotionPropertiesUnchecked() != nullptr? settings.mInvMassScale2 * inBody2.GetMotionPropertiesUnchecked()->GetInverseMassUnchecked() : 0.0f; + constraint.mInvInertiaScale2 = settings.mInvInertiaScale2; JPH_DET_LOG("TemplatedAddContactConstraint: id1: " << constraint.mBody1->GetID() << " id2: " << constraint.mBody2->GetID() << " key: " << constraint.mSortKey); @@ -1350,6 +1352,14 @@ void ContactConstraintManager::OnCCDContactAdded(ContactAllocator &ioContactAllo // Note that we can trigger OnContactPersisted multiple times per physics update, but otherwise we have no way of obtaining the settings mContactListener->OnContactPersisted(*body1, *body2, *manifold, outSettings); } + + // If we swapped body1 and body2 we need to swap the mass scales back + if (manifold == &temp) + { + swap(outSettings.mInvMassScale1, outSettings.mInvMassScale2); + swap(outSettings.mInvInertiaScale1, outSettings.mInvInertiaScale2); + // Note we do not need to negate the relative surface velocity as it is not applied by the CCD collision constraint + } } JPH_ASSERT(outSettings.mIsSensor || !(inBody1.IsSensor() || inBody2.IsSensor()), "Sensors cannot be converted into regular bodies by a contact callback!"); @@ -1440,10 +1450,10 @@ JPH_INLINE void ContactConstraintManager::sWarmStartConstraint(ContactConstraint if (wcp.mFrictionConstraint1.IsActive()) { JPH_ASSERT(wcp.mFrictionConstraint2.IsActive()); - wcp.mFrictionConstraint1.TemplatedWarmStart(ioMotionProperties1, ioMotionProperties2, t1, inWarmStartImpulseRatio); - wcp.mFrictionConstraint2.TemplatedWarmStart(ioMotionProperties1, ioMotionProperties2, t2, inWarmStartImpulseRatio); + wcp.mFrictionConstraint1.TemplatedWarmStart(ioMotionProperties1, ioConstraint.mInvMass1, ioMotionProperties2, ioConstraint.mInvMass2, t1, inWarmStartImpulseRatio); + wcp.mFrictionConstraint2.TemplatedWarmStart(ioMotionProperties1, ioConstraint.mInvMass1, ioMotionProperties2, ioConstraint.mInvMass2, t2, inWarmStartImpulseRatio); } - wcp.mNonPenetrationConstraint.TemplatedWarmStart(ioMotionProperties1, ioMotionProperties2, ws_normal, inWarmStartImpulseRatio); + wcp.mNonPenetrationConstraint.TemplatedWarmStart(ioMotionProperties1, ioConstraint.mInvMass1, ioMotionProperties2, ioConstraint.mInvMass2, ws_normal, inWarmStartImpulseRatio); } } @@ -1517,9 +1527,9 @@ JPH_INLINE bool ContactConstraintManager::sSolveVelocityConstraint(ContactConstr } // Apply the friction impulse - if (wcp.mFrictionConstraint1.TemplatedSolveVelocityConstraintApplyLambda(ioMotionProperties1, ioMotionProperties2, t1, lambda1)) + if (wcp.mFrictionConstraint1.TemplatedSolveVelocityConstraintApplyLambda(ioMotionProperties1, ioConstraint.mInvMass1, ioMotionProperties2, ioConstraint.mInvMass2, t1, lambda1)) any_impulse_applied = true; - if (wcp.mFrictionConstraint2.TemplatedSolveVelocityConstraintApplyLambda(ioMotionProperties1, ioMotionProperties2, t2, lambda2)) + if (wcp.mFrictionConstraint2.TemplatedSolveVelocityConstraintApplyLambda(ioMotionProperties1, ioConstraint.mInvMass1, ioMotionProperties2, ioConstraint.mInvMass2, t2, lambda2)) any_impulse_applied = true; } } @@ -1530,7 +1540,7 @@ JPH_INLINE bool ContactConstraintManager::sSolveVelocityConstraint(ContactConstr for (WorldContactPoint &wcp : ioConstraint.mContactPoints) { // Solve non penetration velocities - if (wcp.mNonPenetrationConstraint.TemplatedSolveVelocityConstraint(ioMotionProperties1, ioMotionProperties2, ws_normal, 0.0f, FLT_MAX)) + if (wcp.mNonPenetrationConstraint.TemplatedSolveVelocityConstraint(ioMotionProperties1, ioConstraint.mInvMass1, ioMotionProperties2, ioConstraint.mInvMass2, ws_normal, 0.0f, FLT_MAX)) any_impulse_applied = true; } @@ -1650,10 +1660,10 @@ bool ContactConstraintManager::SolvePositionConstraints(const uint32 *inConstrai if (separation < 0.0f) { // Update constraint properties (bodies may have moved) - wcp.CalculateNonPenetrationConstraintProperties(body1, body2, p1, p2, ws_normal); + wcp.CalculateNonPenetrationConstraintProperties(body1, constraint.mInvMass1, constraint.mInvInertiaScale1, body2, constraint.mInvMass2, constraint.mInvInertiaScale2, p1, p2, ws_normal); // Solve position errors - if (wcp.mNonPenetrationConstraint.SolvePositionConstraint(body1, body2, ws_normal, separation, mPhysicsSettings.mBaumgarte)) + if (wcp.mNonPenetrationConstraint.SolvePositionConstraintWithMassOverride(body1, constraint.mInvMass1, body2, constraint.mInvMass2, ws_normal, separation, mPhysicsSettings.mBaumgarte)) any_impulse_applied = true; } } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.h index 18679d162..7af22d1ec 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.h @@ -420,7 +420,7 @@ class JPH_EXPORT ContactConstraintManager : public NonCopyable { public: /// Calculate constraint properties below - void CalculateNonPenetrationConstraintProperties(const Body &inBody1, const Body &inBody2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal); + void CalculateNonPenetrationConstraintProperties(const Body &inBody1, float inInvMass1, float inInvInertiaScale1, const Body &inBody2, float inInvMass2, float inInvInertiaScale2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal); template JPH_INLINE void TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(float inDeltaTime, const Body &inBody1, const Body &inBody2, float inInvM1, float inInvM2, Mat44Arg inInvI1, Mat44Arg inInvI2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal, Vec3Arg inWorldSpaceTangent1, Vec3Arg inWorldSpaceTangent2, const ContactSettings &inSettings, float inMinVelocityForRestitution); @@ -464,6 +464,10 @@ class JPH_EXPORT ContactConstraintManager : public NonCopyable uint64 mSortKey; Float3 mWorldSpaceNormal; float mCombinedFriction; + float mInvMass1; + float mInvInertiaScale1; + float mInvMass2; + float mInvInertiaScale2; WorldContactPoints mContactPoints; }; diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/HingeConstraint.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/HingeConstraint.cpp index 31e77270e..6bf64c906 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/HingeConstraint.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/HingeConstraint.cpp @@ -199,7 +199,10 @@ void HingeConstraint::CalculateMotorConstraintProperties(float inDeltaTime) break; case EMotorState::Position: - mMotorConstraintPart.CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, *mBody2, mA1, 0.0f, CenterAngleAroundZero(mTheta - mTargetAngle), mMotorSettings.mSpringSettings); + if (mMotorSettings.mSpringSettings.HasStiffness()) + mMotorConstraintPart.CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, *mBody2, mA1, 0.0f, CenterAngleAroundZero(mTheta - mTargetAngle), mMotorSettings.mSpringSettings); + else + mMotorConstraintPart.Deactivate(); break; } } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/PathConstraint.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/PathConstraint.cpp index 102ce8fbd..f463ad751 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/PathConstraint.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/PathConstraint.cpp @@ -196,6 +196,7 @@ void PathConstraint::CalculateConstraintProperties(float inDeltaTime) break; case EMotorState::Position: + if (mPositionMotorSettings.mSpringSettings.HasStiffness()) { // Calculate constraint value to drive to float c; @@ -212,8 +213,10 @@ void PathConstraint::CalculateConstraintProperties(float inDeltaTime) else c = mPathFraction - mTargetPathFraction; mPositionMotorConstraintPart.CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, mR1 + mU, *mBody2, mR2, mPathTangent, 0.0f, c, mPositionMotorSettings.mSpringSettings); - break; } + else + mPositionMotorConstraintPart.Deactivate(); + break; } } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.cpp index dc5f9fa15..d6c2e95a4 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.cpp @@ -379,8 +379,14 @@ void SixDOFConstraint::SetupVelocityConstraint(float inDeltaTime) break; case EMotorState::Position: - mMotorTranslationConstraintPart[i].CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, r1_plus_u, *mBody2, r2, translation_axis, 0.0f, translation_axis.Dot(u) - mTargetPosition[i], mMotorSettings[i].mSpringSettings); - break; + { + const SpringSettings &spring_settings = mMotorSettings[i].mSpringSettings; + if (spring_settings.HasStiffness()) + mMotorTranslationConstraintPart[i].CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, r1_plus_u, *mBody2, r2, translation_axis, 0.0f, translation_axis.Dot(u) - mTargetPosition[i], spring_settings); + else + mMotorTranslationConstraintPart[i].Deactivate(); + break; + } } } } @@ -504,8 +510,14 @@ void SixDOFConstraint::SetupVelocityConstraint(float inDeltaTime) break; case EMotorState::Position: - mMotorRotationConstraintPart[i].CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, *mBody2, rotation_axis, 0.0f, rotation_error[i], mMotorSettings[axis].mSpringSettings); - break; + { + const SpringSettings &spring_settings = mMotorSettings[axis].mSpringSettings; + if (spring_settings.HasStiffness()) + mMotorRotationConstraintPart[i].CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, *mBody2, rotation_axis, 0.0f, rotation_error[i], spring_settings); + else + mMotorRotationConstraintPart[i].Deactivate(); + break; + } } } } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.h index faa3e1f16..81d19bf62 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.h @@ -145,7 +145,7 @@ class JPH_EXPORT SixDOFConstraint final : public TwoBodyConstraint float GetMaxFriction(EAxis inAxis) const { return mMaxFriction[inAxis]; } /// Get rotation of constraint in constraint space - inline Quat GetRotationInConstraintSpace() const; + Quat GetRotationInConstraintSpace() const; /// Motor settings MotorSettings & GetMotorSettings(EAxis inAxis) { return mMotorSettings[inAxis]; } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SliderConstraint.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SliderConstraint.cpp index fa3711bf4..aca0462c1 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SliderConstraint.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SliderConstraint.cpp @@ -246,7 +246,10 @@ void SliderConstraint::CalculateMotorConstraintProperties(float inDeltaTime) break; case EMotorState::Position: - mMotorConstraintPart.CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, mR1 + mU, *mBody2, mR2, mWorldSpaceSliderAxis, 0.0f, mD - mTargetPosition, mMotorSettings.mSpringSettings); + if (mMotorSettings.mSpringSettings.HasStiffness()) + mMotorConstraintPart.CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, mR1 + mU, *mBody2, mR2, mWorldSpaceSliderAxis, 0.0f, mD - mTargetPosition, mMotorSettings.mSpringSettings); + else + mMotorConstraintPart.Deactivate(); break; } } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SpringSettings.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SpringSettings.h index 99cdf12db..9b230a2a5 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SpringSettings.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SpringSettings.h @@ -36,6 +36,9 @@ class JPH_EXPORT SpringSettings /// Restores contents from the binary stream inStream. void RestoreBinaryState(StreamIn &inStream); + /// Check if the spring has a valid frequency / stiffness, if not the spring will be hard + inline bool HasStiffness() const { return mFrequency > 0.0f; } + /// Selects the way in which the spring is defined /// If the mode is StiffnessAndDamping then mFrequency becomes the stiffness (k) and mDamping becomes the damping ratio (c) in the spring equation F = -k * x - c * v. Otherwise the properties are as documented. ESpringMode mMode = ESpringMode::FrequencyAndDamping; @@ -44,12 +47,12 @@ class JPH_EXPORT SpringSettings { /// Valid when mSpringMode = ESpringMode::FrequencyAndDamping. /// If mFrequency > 0 the constraint will be soft and mFrequency specifies the oscillation frequency in Hz. - /// If mFrequency <= 0, mDamping is ignored and the distance constraint will have hard limits (as hard as the time step / the number of velocity / position solver steps allows). + /// If mFrequency <= 0, mDamping is ignored and the constraint will have hard limits (as hard as the time step / the number of velocity / position solver steps allows). float mFrequency = 0.0f; /// Valid when mSpringMode = ESpringMode::StiffnessAndDamping. /// If mStiffness > 0 the constraint will be soft and mStiffness specifies the stiffness (k) in the spring equation F = -k * x - c * v for a linear or T = -k * theta - c * w for an angular spring. - /// If mStiffness <= 0, mDamping is ignored and the distance constraint will have hard limits (as hard as the time step / the number of velocity / position solver steps allows). + /// If mStiffness <= 0, mDamping is ignored and the constraint will have hard limits (as hard as the time step / the number of velocity / position solver steps allows). float mStiffness; }; diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.cpp index 3ff15e7a2..065ec4bd4 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.cpp @@ -272,8 +272,16 @@ void SwingTwistConstraint::SetupVelocityConstraint(float inDeltaTime) case EMotorState::Position: // Use motor to drive rotation error to zero - for (int i = 1; i < 3; ++i) - mMotorConstraintPart[i].CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, *mBody2, mWorldSpaceMotorAxis[i], 0.0f, rotation_error[i], mSwingMotorSettings.mSpringSettings); + if (mSwingMotorSettings.mSpringSettings.HasStiffness()) + { + for (int i = 1; i < 3; ++i) + mMotorConstraintPart[i].CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, *mBody2, mWorldSpaceMotorAxis[i], 0.0f, rotation_error[i], mSwingMotorSettings.mSpringSettings); + } + else + { + for (int i = 1; i < 3; ++i) + mMotorConstraintPart[i].Deactivate(); + } break; } @@ -300,7 +308,10 @@ void SwingTwistConstraint::SetupVelocityConstraint(float inDeltaTime) case EMotorState::Position: // Use motor to drive rotation error to zero - mMotorConstraintPart[0].CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, *mBody2, mWorldSpaceMotorAxis[0], 0.0f, rotation_error[0], mTwistMotorSettings.mSpringSettings); + if (mTwistMotorSettings.mSpringSettings.HasStiffness()) + mMotorConstraintPart[0].CalculateConstraintPropertiesWithSettings(inDeltaTime, *mBody1, *mBody2, mWorldSpaceMotorAxis[0], 0.0f, rotation_error[0], mTwistMotorSettings.mSpringSettings); + else + mMotorConstraintPart[0].Deactivate(); break; } } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.h index 41b86f343..693d097ac 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.h @@ -139,7 +139,7 @@ class JPH_EXPORT SwingTwistConstraint final : public TwoBodyConstraint /// Get current rotation of constraint in constraint space. /// Solve: R2 * ConstraintToBody2 = R1 * ConstraintToBody1 * q for q. - inline Quat GetRotationInConstraintSpace() const; + Quat GetRotationInConstraintSpace() const; ///@name Get Lagrange multiplier from last physics update (the linear/angular impulse applied to satisfy the constraint) inline Vec3 GetTotalLambdaPosition() const { return mPointConstraintPart.GetTotalLambda(); } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/IslandBuilder.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/IslandBuilder.cpp index b80ff2936..dda2093ac 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/IslandBuilder.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/IslandBuilder.cpp @@ -184,20 +184,20 @@ void IslandBuilder::ValidateIslands(uint32 inNumActiveBodies) const // If the bodies in this link ended up in different groups we have a problem if (mBodyLinks[mLinkValidation[i].mFirst].mIslandIndex != mBodyLinks[mLinkValidation[i].mSecond].mIslandIndex) { - Trace("Fail: %d, %d", mLinkValidation[i].mFirst, mLinkValidation[i].mSecond); - Trace("Num Active: %d", inNumActiveBodies); + Trace("Fail: %u, %u", mLinkValidation[i].mFirst, mLinkValidation[i].mSecond); + Trace("Num Active: %u", inNumActiveBodies); for (uint32 j = 0; j < mNumLinkValidation; ++j) - Trace("builder.Link(%d, %d);", mLinkValidation[j].mFirst, mLinkValidation[j].mSecond); + Trace("builder.Link(%u, %u);", mLinkValidation[j].mFirst, mLinkValidation[j].mSecond); IslandBuilder tmp; tmp.Init(inNumActiveBodies); for (uint32 j = 0; j < mNumLinkValidation; ++j) { - Trace("Link %d -> %d", mLinkValidation[j].mFirst, mLinkValidation[j].mSecond); + Trace("Link %u -> %u", mLinkValidation[j].mFirst, mLinkValidation[j].mSecond); tmp.LinkBodies(mLinkValidation[j].mFirst, mLinkValidation[j].mSecond); for (uint32 t = 0; t < inNumActiveBodies; ++t) - Trace("%d -> %d", t, (uint32)tmp.mBodyLinks[t].mLinkedTo); + Trace("%u -> %u", t, (uint32)tmp.mBodyLinks[t].mLinkedTo); } JPH_ASSERT(false, "IslandBuilder validation failed"); diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/PhysicsSystem.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/PhysicsSystem.cpp index 701313af7..75680d860 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/PhysicsSystem.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/PhysicsSystem.cpp @@ -1984,18 +1984,23 @@ void PhysicsSystem::JobResolveCCDContacts(PhysicsUpdateContext *ioContext, Physi // Calculate velocity bias due to restitution float normal_velocity_bias; - if (ccd_body->mContactSettings.mCombinedRestitution > 0.0f && normal_velocity < -mPhysicsSettings.mMinVelocityForRestitution) - normal_velocity_bias = ccd_body->mContactSettings.mCombinedRestitution * normal_velocity; + const ContactSettings &contact_settings = ccd_body->mContactSettings; + if (contact_settings.mCombinedRestitution > 0.0f && normal_velocity < -mPhysicsSettings.mMinVelocityForRestitution) + normal_velocity_bias = contact_settings.mCombinedRestitution * normal_velocity; else normal_velocity_bias = 0.0f; + // Get inverse masses + float inv_m1 = contact_settings.mInvMassScale1 * body_mp->GetInverseMass(); + float inv_m2 = body2.GetMotionPropertiesUnchecked() != nullptr? contact_settings.mInvMassScale2 * body2.GetMotionPropertiesUnchecked()->GetInverseMassUnchecked() : 0.0f; + // Solve contact constraint AxisConstraintPart contact_constraint; - contact_constraint.CalculateConstraintProperties(body1, r1_plus_u, body2, r2, ccd_body->mContactNormal, normal_velocity_bias); - contact_constraint.SolveVelocityConstraint(body1, body2, ccd_body->mContactNormal, -FLT_MAX, FLT_MAX); + contact_constraint.CalculateConstraintPropertiesWithMassOverride(body1, inv_m1, contact_settings.mInvInertiaScale1, r1_plus_u, body2, inv_m2, contact_settings.mInvInertiaScale2, r2, ccd_body->mContactNormal, normal_velocity_bias); + contact_constraint.SolveVelocityConstraintWithMassOverride(body1, inv_m1, body2, inv_m2, ccd_body->mContactNormal, -FLT_MAX, FLT_MAX); // Apply friction - if (ccd_body->mContactSettings.mCombinedFriction > 0.0f) + if (contact_settings.mCombinedFriction > 0.0f) { // Calculate friction direction by removing normal velocity from the relative velocity Vec3 friction_direction = relative_velocity - normal_velocity * ccd_body->mContactNormal; @@ -2006,11 +2011,11 @@ void PhysicsSystem::JobResolveCCDContacts(PhysicsUpdateContext *ioContext, Physi friction_direction /= sqrt(friction_direction_len_sq); // Calculate max friction impulse - float max_lambda_f = ccd_body->mContactSettings.mCombinedFriction * contact_constraint.GetTotalLambda(); + float max_lambda_f = contact_settings.mCombinedFriction * contact_constraint.GetTotalLambda(); AxisConstraintPart friction; - friction.CalculateConstraintProperties(body1, r1_plus_u, body2, r2, friction_direction); - friction.SolveVelocityConstraint(body1, body2, friction_direction, -max_lambda_f, max_lambda_f); + friction.CalculateConstraintPropertiesWithMassOverride(body1, inv_m1, contact_settings.mInvInertiaScale1, r1_plus_u, body2, inv_m2, contact_settings.mInvInertiaScale2, r2, friction_direction); + friction.SolveVelocityConstraintWithMassOverride(body1, inv_m1, body2, inv_m2, friction_direction, -max_lambda_f, max_lambda_f); } } @@ -2344,38 +2349,40 @@ void PhysicsSystem::JobSoftBodyPrepare(PhysicsUpdateContext *ioContext, PhysicsU { JPH_PROFILE_FUNCTION(); -#ifdef JPH_ENABLE_ASSERTS - // Reading soft body positions - BodyAccess::Grant grant(BodyAccess::EAccess::None, BodyAccess::EAccess::Read); -#endif + { + #ifdef JPH_ENABLE_ASSERTS + // Reading soft body positions + BodyAccess::Grant grant(BodyAccess::EAccess::None, BodyAccess::EAccess::Read); + #endif - // Get the active soft bodies - BodyIDVector active_bodies; - mBodyManager.GetActiveBodies(EBodyType::SoftBody, active_bodies); + // Get the active soft bodies + BodyIDVector active_bodies; + mBodyManager.GetActiveBodies(EBodyType::SoftBody, active_bodies); - // Quit if there are no active soft bodies - if (active_bodies.empty()) - { - // Kick the next step - if (ioStep->mStartNextStep.IsValid()) - ioStep->mStartNextStep.RemoveDependency(); - return; - } + // Quit if there are no active soft bodies + if (active_bodies.empty()) + { + // Kick the next step + if (ioStep->mStartNextStep.IsValid()) + ioStep->mStartNextStep.RemoveDependency(); + return; + } - // Sort to get a deterministic update order - QuickSort(active_bodies.begin(), active_bodies.end()); + // Sort to get a deterministic update order + QuickSort(active_bodies.begin(), active_bodies.end()); - // Allocate soft body contexts - ioContext->mNumSoftBodies = (uint)active_bodies.size(); - ioContext->mSoftBodyUpdateContexts = (SoftBodyUpdateContext *)ioContext->mTempAllocator->Allocate(ioContext->mNumSoftBodies * sizeof(SoftBodyUpdateContext)); + // Allocate soft body contexts + ioContext->mNumSoftBodies = (uint)active_bodies.size(); + ioContext->mSoftBodyUpdateContexts = (SoftBodyUpdateContext *)ioContext->mTempAllocator->Allocate(ioContext->mNumSoftBodies * sizeof(SoftBodyUpdateContext)); - // Initialize soft body contexts - for (SoftBodyUpdateContext *sb_ctx = ioContext->mSoftBodyUpdateContexts, *sb_ctx_end = ioContext->mSoftBodyUpdateContexts + ioContext->mNumSoftBodies; sb_ctx < sb_ctx_end; ++sb_ctx) - { - new (sb_ctx) SoftBodyUpdateContext; - Body &body = mBodyManager.GetBody(active_bodies[sb_ctx - ioContext->mSoftBodyUpdateContexts]); - SoftBodyMotionProperties *mp = static_cast(body.GetMotionProperties()); - mp->InitializeUpdateContext(ioContext->mStepDeltaTime, body, *this, *sb_ctx); + // Initialize soft body contexts + for (SoftBodyUpdateContext *sb_ctx = ioContext->mSoftBodyUpdateContexts, *sb_ctx_end = ioContext->mSoftBodyUpdateContexts + ioContext->mNumSoftBodies; sb_ctx < sb_ctx_end; ++sb_ctx) + { + new (sb_ctx) SoftBodyUpdateContext; + Body &body = mBodyManager.GetBody(active_bodies[sb_ctx - ioContext->mSoftBodyUpdateContexts]); + SoftBodyMotionProperties *mp = static_cast(body.GetMotionProperties()); + mp->InitializeUpdateContext(ioContext->mStepDeltaTime, body, *this, *sb_ctx); + } } // We're ready to collide the first soft body diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Ragdoll/Ragdoll.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Ragdoll/Ragdoll.cpp index ae694a0df..23b9d01b3 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Ragdoll/Ragdoll.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Ragdoll/Ragdoll.cpp @@ -449,7 +449,7 @@ void RagdollSettings::CalculateConstraintIndexToBodyIdxPair() if (p.mToParent != nullptr) { int parent_joint_idx = mSkeleton->GetJoint(joint_idx).mParentJointIndex; - mConstraintIndexToBodyIdxPair.push_back(BodyIdxPair(parent_joint_idx, joint_idx)); + mConstraintIndexToBodyIdxPair.emplace_back(parent_joint_idx, joint_idx); } ++joint_idx; @@ -457,7 +457,7 @@ void RagdollSettings::CalculateConstraintIndexToBodyIdxPair() // Add additional constraints for (const AdditionalConstraint &c : mAdditionalConstraints) - mConstraintIndexToBodyIdxPair.push_back(BodyIdxPair(c.mBodyIdx[0], c.mBodyIdx[1])); + mConstraintIndexToBodyIdxPair.emplace_back(c.mBodyIdx[0], c.mBodyIdx[1]); } Ragdoll::~Ragdoll() diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodyShape.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodyShape.cpp index 37db1d558..0e0a9896d 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodyShape.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodyShape.cpp @@ -218,7 +218,7 @@ int SoftBodyShape::GetTrianglesNext(GetTrianglesContext &ioContext, int inMaxTri Shape::Stats SoftBodyShape::GetStats() const { - return Stats(sizeof(this), (uint)mSoftBodyMotionProperties->GetFaces().size()); + return Stats(sizeof(*this), (uint)mSoftBodyMotionProperties->GetFaces().size()); } float SoftBodyShape::GetVolume() const diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodySharedSettings.cpp b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodySharedSettings.cpp index 573ca7ee3..c1c4e8a8b 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodySharedSettings.cpp +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodySharedSettings.cpp @@ -45,6 +45,7 @@ JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(SoftBodySharedSettings) JPH_ADD_ATTRIBUTE(SoftBodySharedSettings, mVertices) JPH_ADD_ATTRIBUTE(SoftBodySharedSettings, mFaces) JPH_ADD_ATTRIBUTE(SoftBodySharedSettings, mEdgeConstraints) + JPH_ADD_ATTRIBUTE(SoftBodySharedSettings, mEdgeGroupEndIndices) JPH_ADD_ATTRIBUTE(SoftBodySharedSettings, mVolumeConstraints) JPH_ADD_ATTRIBUTE(SoftBodySharedSettings, mMaterials) } @@ -139,6 +140,7 @@ void SoftBodySharedSettings::SaveBinaryState(StreamOut &inStream) const inStream.Write(mVertices); inStream.Write(mFaces); inStream.Write(mEdgeConstraints); + inStream.Write(mEdgeGroupEndIndices); inStream.Write(mVolumeConstraints); } @@ -147,6 +149,7 @@ void SoftBodySharedSettings::RestoreBinaryState(StreamIn &inStream) inStream.Read(mVertices); inStream.Read(mFaces); inStream.Read(mEdgeConstraints); + inStream.Read(mEdgeGroupEndIndices); inStream.Read(mVolumeConstraints); } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodySharedSettings.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodySharedSettings.h index 56f7140e9..b4f2240c4 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodySharedSettings.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/SoftBody/SoftBodySharedSettings.h @@ -33,6 +33,9 @@ class JPH_EXPORT SoftBodySharedSettings : public RefTarget(outData)[i]; @@ -73,7 +79,7 @@ bool StateRecorderImpl::IsEqual(StateRecorderImpl &inReference) fail = inReference.mStream.get() != mStream.get(); if (fail) { - Trace("Failed to properly recover state, different at offset %d!", i); + Trace("Failed to properly recover state, different at offset %d!", (int)i); return false; } } diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/StateRecorderImpl.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/StateRecorderImpl.h index 17358268e..b852679c0 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/StateRecorderImpl.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/StateRecorderImpl.h @@ -22,6 +22,9 @@ class JPH_EXPORT StateRecorderImpl final : public StateRecorder /// Rewind the stream for reading void Rewind(); + /// Clear the stream for reuse + void Clear(); + /// Read a string of bytes from the binary stream virtual void ReadBytes(void *outData, size_t inNumBytes) override; diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/VehicleCollisionTester.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/VehicleCollisionTester.h index 4a0a449a2..b89561096 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/VehicleCollisionTester.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/VehicleCollisionTester.h @@ -5,6 +5,7 @@ #pragma once #include +#include JPH_NAMESPACE_BEGIN @@ -15,7 +16,7 @@ class ObjectLayerFilter; class BodyFilter; /// Class that does collision detection between wheels and ground -class JPH_EXPORT VehicleCollisionTester : public RefTarget +class JPH_EXPORT VehicleCollisionTester : public RefTarget, public NonCopyable { public: JPH_OVERRIDE_NEW_DELETE diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/VehicleController.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/VehicleController.h index 20dcc0204..02bd3deeb 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/VehicleController.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/VehicleController.h @@ -37,7 +37,7 @@ class JPH_EXPORT VehicleControllerSettings : public SerializableObject, public R }; /// Runtime data for interface that controls acceleration / decelleration of the vehicle -class JPH_EXPORT VehicleController : public RefTarget +class JPH_EXPORT VehicleController : public RefTarget, public NonCopyable { public: JPH_OVERRIDE_NEW_DELETE diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/Wheel.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/Wheel.h index 887c34c02..c540b2e99 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/Wheel.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/Physics/Vehicle/Wheel.h @@ -15,7 +15,7 @@ JPH_NAMESPACE_BEGIN class VehicleConstraint; /// Base class for wheel settings, each VehicleController can implement a derived class of this -class JPH_EXPORT WheelSettings : public SerializableObject, public RefTarget, public NonCopyable +class JPH_EXPORT WheelSettings : public SerializableObject, public RefTarget { public: JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, WheelSettings) @@ -42,7 +42,7 @@ class JPH_EXPORT WheelSettings : public SerializableObject, public RefTarget +#include JPH_NAMESPACE_BEGIN /// A class that groups triangles in batches of N (according to closeness) -class JPH_EXPORT TriangleGrouper +class JPH_EXPORT TriangleGrouper : public NonCopyable { public: /// Virtual destructor diff --git a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/TriangleSplitter/TriangleSplitter.h b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/TriangleSplitter/TriangleSplitter.h index be7f2182d..a66672238 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/Jolt/TriangleSplitter/TriangleSplitter.h +++ b/prog/3rdPartyLibs/phys/joltPhysics/Jolt/TriangleSplitter/TriangleSplitter.h @@ -5,11 +5,12 @@ #pragma once #include +#include JPH_NAMESPACE_BEGIN /// A class that splits a triangle list into two parts for building a tree -class JPH_EXPORT TriangleSplitter +class JPH_EXPORT TriangleSplitter : public NonCopyable { public: /// Constructor diff --git a/prog/3rdPartyLibs/phys/joltPhysics/jamfile b/prog/3rdPartyLibs/phys/joltPhysics/jamfile index caded92ee..55bcff9fb 100644 --- a/prog/3rdPartyLibs/phys/joltPhysics/jamfile +++ b/prog/3rdPartyLibs/phys/joltPhysics/jamfile @@ -1,5 +1,5 @@ # https://github.com/jrouwe/JoltPhysics.git -# rev c8829c4f68286faefa8b63200f0eae079ad8b1e2 +# rev 6535d6ca60a47bed90153730b3fc3a409d48e274 Root ?= ../../../.. ; Location = prog/3rdPartyLibs/phys/joltPhysics ; if $(OS) = NT { Platform ?= win64 ; } diff --git a/prog/_jBuild/jCommonRules.jam b/prog/_jBuild/jCommonRules.jam index e2fd0edc8..fdb36d70e 100644 --- a/prog/_jBuild/jCommonRules.jam +++ b/prog/_jBuild/jCommonRules.jam @@ -3,6 +3,11 @@ if $(OS) = NT { PYTHON_EXE ?= $(_DEVTOOL)/python3/python3.exe ; PYTHON_EXE ?= $( else if $(OS) in MACOSX { PYTHON_EXE ?= python3 ; } else if $(OS) in LINUX { PYTHON_EXE ?= python3 ; } +if $(OS) in MACOSX && $(PYTHON_EXE) = python3 && ! [ GLOB /usr/bin : $(PYTHON_EXE) ] { + echo warning: $(PYTHON_EXE) not found, trying to use python ; + PYTHON_EXE = python ; +} + actions together quietly null_action { } diff --git a/prog/_jBuild/linux64/gcc-cpp.jam b/prog/_jBuild/linux64/gcc-cpp.jam index 657c66cce..bb06d1ff3 100644 --- a/prog/_jBuild/linux64/gcc-cpp.jam +++ b/prog/_jBuild/linux64/gcc-cpp.jam @@ -13,14 +13,15 @@ rule ProcessCompileTarget { } + local O3 = -O3 ; + if $(CheckOnly) = yes { O3 = -O0 ; } switch $(Config) { case dev : - _CONFIG_OPT = -DDAGOR_DBGLEVEL=1 ; - if $(CheckOnly) = yes { _CONFIG_OPT += -O0 ; } else { _CONFIG_OPT += -O3 ; } + _CONFIG_OPT = $(O3) -DDAGOR_DBGLEVEL=1 ; case rel : - _CONFIG_OPT = -DDAGOR_DBGLEVEL=0 -O3 -DNDEBUG=1 ; + _CONFIG_OPT = -DDAGOR_DBGLEVEL=0 $(O3) -DNDEBUG=1 ; case irel : - _CONFIG_OPT = -DDAGOR_DBGLEVEL=-1 -O3 -DNDEBUG=1 ; + _CONFIG_OPT = -DDAGOR_DBGLEVEL=-1 $(O3) -DNDEBUG=1 ; case dbg : _CONFIG_OPT = -DDAGOR_DBGLEVEL=2 ; case * : diff --git a/prog/_jBuild/macosx/setup-ver.jam b/prog/_jBuild/macosx/setup-ver.jam index 96fa927c0..1f651198e 100644 --- a/prog/_jBuild/macosx/setup-ver.jam +++ b/prog/_jBuild/macosx/setup-ver.jam @@ -1,7 +1,10 @@ if ! [ GLOB $(_DEVTOOL)/mac/SDKs/MacOSX.platform/MacOSX$(MacOSXVer).sdk : * ] && $(Platform) = macosx { local ver = 10.7 10.8 10.9 10.10 10.11 10.12 10.13 10.14 10.15 11.0 11.1 11.2 11.3 12.0 12.1 12.2 12.3 13.0 13.1 13.2 13.3 13.4 14.0 ; + local min_ver_passed = no ; for v in $(ver) { + if $(v) = $(MacOSXMinVer) { min_version_passed = yes ; } if [ GLOB $(_DEVTOOL)/mac/SDKs/MacOSX.platform/MacOSX$(v).sdk : * ] { + if $(min_version_passed) != yes { MacOSXMinVer = $(v) ; } echo MacOSX SDK $(MacOSXVer) not found, switching to $(v) with -mmacosx-version-min=$(MacOSXMinVer) ; MacOSXVer = $(v) ; break ; diff --git a/prog/_jBuild/win64/clang-cpp.jam b/prog/_jBuild/win64/clang-cpp.jam index 657126b41..6c2f7d611 100644 --- a/prog/_jBuild/win64/clang-cpp.jam +++ b/prog/_jBuild/win64/clang-cpp.jam @@ -8,20 +8,21 @@ rule ProcessCompileTarget local pre_opt = ; local post_opt = ; + local O3 = -Xclang -O3 /Gy /Gw ; + if $(CheckOnly) = yes { O3 = /Od ; } switch $(Config) { case dev : - if $(CheckOnly) != yes { _CONFIG_OPT = -Xclang -O3 /Gy /Gw ; } else { _CONFIG_OPT = /Od ; } - _CONFIG_OPT += -DDAGOR_DBGLEVEL=1 ; + _CONFIG_OPT += $(O3) -DDAGOR_DBGLEVEL=1 ; case rel : - _CONFIG_OPT = -Xclang -O3 /Gy /Gw -DDAGOR_DBGLEVEL=0 -DNDEBUG=1 -D_SECURE_SCL=0 ; + _CONFIG_OPT = $(O3) -DDAGOR_DBGLEVEL=0 -DNDEBUG=1 -D_SECURE_SCL=0 ; case irel : - _CONFIG_OPT = -Xclang -O3 /Gy /Gw -DDAGOR_DBGLEVEL=-1 -DNDEBUG=1 -D_SECURE_SCL=0 ; + _CONFIG_OPT = $(O3) -DDAGOR_DBGLEVEL=-1 -DNDEBUG=1 -D_SECURE_SCL=0 ; case dbg : _CONFIG_OPT = /Od /RTC1 -DDAGOR_DBGLEVEL=2 ; case analyze : - _CONFIG_OPT = -Xclang -O3 /Gy /Gw -DDAGOR_DBGLEVEL=1 /analyze ; + _CONFIG_OPT = $(O3) -DDAGOR_DBGLEVEL=1 /analyze ; case prefast : - _CONFIG_OPT = -Xclang -O3 /Gy /Gw -DDAGOR_DBGLEVEL=1 ; + _CONFIG_OPT = $(O3) -DDAGOR_DBGLEVEL=1 ; case * : _CONFIG_OPT = ; } diff --git a/prog/commonFx/commonFxGame/dafxSparkModules/dafx_shader_common.sh b/prog/commonFx/commonFxGame/dafxSparkModules/dafx_shader_common.dshl similarity index 98% rename from prog/commonFx/commonFxGame/dafxSparkModules/dafx_shader_common.sh rename to prog/commonFx/commonFxGame/dafxSparkModules/dafx_shader_common.dshl index 979e7dbe7..b6b7beb24 100644 --- a/prog/commonFx/commonFxGame/dafxSparkModules/dafx_shader_common.sh +++ b/prog/commonFx/commonFxGame/dafxSparkModules/dafx_shader_common.dshl @@ -1,6 +1,6 @@ -include "dafx_shaders.sh" -include "viewVecVS.sh" -include "dafx_helpers.sh" +include "dafx_shaders.dshl" +include "viewVecVS.dshl" +include "dafx_helpers.dshl" define_macro_if_not_defined DAFXEX_USE_DEPTH_FOR_COLLISION(stage) hlsl { diff --git a/prog/commonFx/commonFxGame/dafx_frame_boundary.sh b/prog/commonFx/commonFxGame/dafx_frame_boundary.dshl similarity index 99% rename from prog/commonFx/commonFxGame/dafx_frame_boundary.sh rename to prog/commonFx/commonFxGame/dafx_frame_boundary.dshl index 576a6148d..ca8cda177 100644 --- a/prog/commonFx/commonFxGame/dafx_frame_boundary.sh +++ b/prog/commonFx/commonFxGame/dafx_frame_boundary.dshl @@ -1,5 +1,5 @@ -include "dafx_shaders.sh" -include "shader_global.sh" +include "dafx_shaders.dshl" +include "shader_global.dshl" texture dafx_fill_boundary_tex; diff --git a/prog/commonFx/commonFxGame/dafx_modfx.sh b/prog/commonFx/commonFxGame/dafx_modfx.dshl similarity index 90% rename from prog/commonFx/commonFxGame/dafx_modfx.sh rename to prog/commonFx/commonFxGame/dafx_modfx.dshl index 94c15d5a4..d68789e23 100644 --- a/prog/commonFx/commonFxGame/dafx_modfx.sh +++ b/prog/commonFx/commonFxGame/dafx_modfx.dshl @@ -1,7 +1,7 @@ -include "dafx_shaders.sh" -include "dafx_helpers.sh" -include "shader_global.sh" -include "viewVecVS.sh" +include "dafx_shaders.dshl" +include "dafx_helpers.dshl" +include "shader_global.dshl" +include "viewVecVS.dshl" shader dafx_modfx_emission, dafx_modfx_simulation, dafx_modfx_emission_adv, dafx_modfx_simulation_adv { diff --git a/prog/commonFx/commonFxGame/dafx_sparks.sh b/prog/commonFx/commonFxGame/dafx_sparks.dshl similarity index 98% rename from prog/commonFx/commonFxGame/dafx_sparks.sh rename to prog/commonFx/commonFxGame/dafx_sparks.dshl index 94d613977..971a7355c 100644 --- a/prog/commonFx/commonFxGame/dafx_sparks.sh +++ b/prog/commonFx/commonFxGame/dafx_sparks.dshl @@ -1,5 +1,5 @@ -include "dafxSparkModules/dafx_shader_common.sh" -include "dafx_helpers.sh" +include "dafxSparkModules/dafx_shader_common.dshl" +include "dafx_helpers.dshl" shader dafx_culling_discard { diff --git a/prog/commonFx/commonFxGame/modfx_bboard_render.sh b/prog/commonFx/commonFxGame/modfx_bboard_render.dshl similarity index 97% rename from prog/commonFx/commonFxGame/modfx_bboard_render.sh rename to prog/commonFx/commonFxGame/modfx_bboard_render.dshl index c8838e34e..5ff615284 100644 --- a/prog/commonFx/commonFxGame/modfx_bboard_render.sh +++ b/prog/commonFx/commonFxGame/modfx_bboard_render.dshl @@ -1,10 +1,10 @@ -include "dafx_shaders.sh" -include "shader_global.sh" -include "dafx_helpers.sh" -include "fom_shadows.sh" -include "clustered/lights_cb.sh" -include "dynamic_lights_count.sh" -include "flexible_scale_rasterization.sh" +include "dafx_shaders.dshl" +include "shader_global.dshl" +include "dafx_helpers.dshl" +include "fom_shadows.dshl" +include "clustered/lights_cb.dshl" +include "dynamic_lights_count.dshl" +include "flexible_scale_rasterization.dshl" int modfx_debug_render = 0; interval modfx_debug_render : off < 1, on; diff --git a/prog/dagorInclude/3d/dag_drv3dCmd.h b/prog/dagorInclude/3d/dag_drv3dCmd.h index a5de24f49..0921bdcf3 100644 --- a/prog/dagorInclude/3d/dag_drv3dCmd.h +++ b/prog/dagorInclude/3d/dag_drv3dCmd.h @@ -104,8 +104,6 @@ enum DRV3D_COMMAND_GET_VENDOR, - DRV3D_COMMAND_GET_RESOLUTION, - DRV3D_COMMAND_OVERRIDE_MAX_ANISOTROPY_LEVEL, // Creates an engine texture object from a raw resource diff --git a/prog/dagorInclude/3d/dag_drvDecl.h b/prog/dagorInclude/3d/dag_drvDecl.h index de7fdfb87..19a6f0792 100644 --- a/prog/dagorInclude/3d/dag_drvDecl.h +++ b/prog/dagorInclude/3d/dag_drvDecl.h @@ -8,6 +8,7 @@ #include #include #include +#include class BaseTexture; struct Driver3dRenderTarget; @@ -159,9 +160,8 @@ struct Driver3dRenderTarget if ((l.used & Driver3dRenderTarget::DEPTH) && l.depth != r.depth) return false; - for (uint32_t mask = l.used & Driver3dRenderTarget::COLOR_MASK, i = 0; mask && i < Driver3dRenderTarget::MAX_SIMRT; - ++i, mask >>= 1) - if ((mask & 1) && (l.color[i] != r.color[i])) + for (auto i : LsbVisitor{l.used & Driver3dRenderTarget::COLOR_MASK}) + if (l.color[i] != r.color[i]) return false; return true; diff --git a/prog/dagorInclude/3d/dag_lockSbuffer.h b/prog/dagorInclude/3d/dag_lockSbuffer.h index eaf75b50c..9df8204e6 100644 --- a/prog/dagorInclude/3d/dag_lockSbuffer.h +++ b/prog/dagorInclude/3d/dag_lockSbuffer.h @@ -37,6 +37,14 @@ class LockedBuffer eastl::swap(mData, rhs.mData); eastl::swap(mCount, rhs.mCount); } + LockedBuffer operator=(const LockedBuffer &rhs) = delete; + LockedBuffer &operator=(LockedBuffer &&rhs) noexcept + { + eastl::swap(mLockedObject, rhs.mLockedObject); + eastl::swap(mData, rhs.mData); + eastl::swap(mCount, rhs.mCount); + return *this; + } ~LockedBuffer() { if (mLockedObject) diff --git a/prog/dagorInclude/3d/dag_lockTexture.h b/prog/dagorInclude/3d/dag_lockTexture.h index 47fbb6e01..1427a5def 100644 --- a/prog/dagorInclude/3d/dag_lockTexture.h +++ b/prog/dagorInclude/3d/dag_lockTexture.h @@ -299,11 +299,14 @@ class LockedImage : public ImageView } public: - static LockedImage lock_texture(BaseTexture *tex, int level, unsigned flags) { return lock_texture(tex, {}, level, flags); } + static LockedImage lock_texture(BaseTexture *tex, int level, unsigned flags) + { + return lock_texture(tex, eastl::nullopt, level, flags); + } static LockedImage lock_texture(BaseTexture *tex, int layer, int level, unsigned flags) { - return lock_texture(tex, layer, level, flags); + return lock_texture(tex, eastl::optional{layer}, level, flags); } ~LockedImage() diff --git a/prog/dagorInclude/3d/dag_multidrawContext.h b/prog/dagorInclude/3d/dag_multidrawContext.h new file mode 100644 index 000000000..3bbf70cb4 --- /dev/null +++ b/prog/dagorInclude/3d/dag_multidrawContext.h @@ -0,0 +1,201 @@ +// +// Dagor Engine 6.5 +// Copyright (C) 2023 Gaijin Games KFT. All rights reserved +// (for conditions of use see prog/license.txt) +// +#pragma once + +#include +#include + +#include <3d/dag_resPtr.h> +#include <3d/dag_lockSbuffer.h> + + +/** Multidraw Context + * + * This class incapsulates logic of filling multidraw buffers. + * It implements draw call id/per draw parameters passing for different platforms and manages buffers required for it. + */ +template +class MultidrawContext +{ + /** + * @brief Name for context that is used as a buffer name and as a prefix for helper buffers. + */ + eastl::string name; + /** + * @brief Buffer for draw calls arguments. + */ + UniqueBuf multidrawArguments; + /** + * @brief Buffer for per draw parameters. + */ + UniqueBufHolder perDrawArgsBuffer; + /** + * @brief Number of draw calls that can be stored in buffer. + */ + uint32_t allocatedDrawcallsInBuffer = 0; + + /** + * @brief Extended draw call arguments structure. + * + * This structure is used for platforms that pass draw call id/per draw parameters using per draw root constants. + * Currently it is used only for DX12. + */ + struct ExtendedDrawIndexedIndirectArgs + { + uint32_t drawcallId; + DrawIndexedIndirectArgs args; + }; + + /** + * @brief Checks if extended draw call arguments structure is used. + */ + static bool usesExtendedMultiDrawStruct() { return d3d::get_driver_code().is(d3d::dx12); } + + /** + * @brief Returns size of draw call arguments structure for a current driver. + */ + static uint32_t bytesCountPerDrawcall() + { + const uint32_t multiDrawArgsStructSize = + usesExtendedMultiDrawStruct() ? sizeof(ExtendedDrawIndexedIndirectArgs) : sizeof(DrawIndexedIndirectArgs); + return multiDrawArgsStructSize; + } + + /** + * @brief Returns size of draw call arguments structure in dwords for a current driver. + */ + static uint32_t dwordsCountPerDrawcall() + { + const uint32_t multiDrawArgsStructSize = bytesCountPerDrawcall(); + G_ASSERT(multiDrawArgsStructSize % sizeof(uint32_t) == 0); + return multiDrawArgsStructSize / sizeof(uint32_t); + } + + /** + * @brief Returns name for per draw parameters buffer. + */ + eastl::string getPerDrawArgsBufferName() const { return name + "_perDrawArgsBuffer"; } + + /** + * @brief Checks if per draw parameter could be stored instead of draw id. In this case we don't need per draw parameters buffer. + */ + static bool needPerDrawParamsBuffer() { return sizeof(PerDrawDataT) != sizeof(uint32_t); } + +public: + /** + * @brief Default constructor. + * @param name must be unique for each context. + */ + MultidrawContext(const char *name) : name(name) {} + /** + * @brief Default move constructor. + */ + MultidrawContext(MultidrawContext &&) = default; + /** + * @brief Default move assignment operator. + */ + MultidrawContext &operator=(MultidrawContext &&) = default; + /** + * @brief Removed copy constructor since we use unique buffer holders. + */ + MultidrawContext(MultidrawContext &) = delete; + /** + * @brief Removed copy assignment operator since we use unique buffer holders. + */ + MultidrawContext &operator=(MultidrawContext &) = delete; + + /** + * @brief Type for a callback that is called for each draw call to fill draw call parameters. + * We don't allow to fill startInstanceLocation because it is used for draw call id on some platforms. + */ + using MultidrawParametersSetter = eastl::fixed_function; + + /** + * @brief Fills multidraw buffers. + * @param drawcalls_count number of draw calls. + * @param params_setter function that sets draw call parameters. + * + * This method iterates over locked buffers content and calls params_setter for each draw call to fill only allowed parameters of + * drawcall. If the buffers are too small, it recreates them. + */ + void fillBuffers(uint32_t drawcalls_count, const MultidrawParametersSetter ¶ms_setter) + { + if (allocatedDrawcallsInBuffer < drawcalls_count || !multidrawArguments.getBuf()) + { + allocatedDrawcallsInBuffer = drawcalls_count; + multidrawArguments.close(); + multidrawArguments = + dag::create_sbuffer(sizeof(uint32_t), allocatedDrawcallsInBuffer * dwordsCountPerDrawcall(), SBCF_INDIRECT, 0, name.c_str()); + if (needPerDrawParamsBuffer()) + { + perDrawArgsBuffer.close(); + perDrawArgsBuffer = dag::create_sbuffer(sizeof(PerDrawDataT), allocatedDrawcallsInBuffer, + SBCF_MISC_STRUCTURED | SBCF_BIND_SHADER_RES | SBCF_DYNAMIC, 0, getPerDrawArgsBufferName().c_str()); + } + } + + eastl::variant, LockedBuffer> + multidrawArgs; + bool bufferLocked = true; + if (usesExtendedMultiDrawStruct()) + { + multidrawArgs = lock_sbuffer(multidrawArguments.getBuf(), 0, drawcalls_count, VBLOCK_DISCARD); + bufferLocked = (bool)eastl::get<2>(multidrawArgs); + } + else + { + multidrawArgs = lock_sbuffer(multidrawArguments.getBuf(), 0, drawcalls_count, VBLOCK_DISCARD); + bufferLocked = (bool)eastl::get<1>(multidrawArgs); + } + if (!bufferLocked) + { + logerr("Buffer %s data wasn't updated.", multidrawArguments.getBuf()->getBufName()); + return; + } + + eastl::optional> perDrawArgs; + if (needPerDrawParamsBuffer()) + { + perDrawArgs.value() = lock_sbuffer(perDrawArgsBuffer.getBuf(), 0, drawcalls_count, VBLOCK_DISCARD); + if (!perDrawArgs) + { + logerr("Buffer %s data wasn't updated.", perDrawArgsBuffer.getBuf()->getBufName()); + return; + } + } + for (uint32_t i = 0; i < drawcalls_count; ++i) + { + DrawIndexedIndirectArgs &drawCall = + multidrawArgs.index() == 1 ? eastl::get<1>(multidrawArgs)[i] : eastl::get<2>(multidrawArgs)[i].args; + uint32_t &drawcallId = multidrawArgs.index() == 1 ? drawCall.startInstanceLocation : eastl::get<2>(multidrawArgs)[i].drawcallId; + PerDrawDataT &perDrawData = perDrawArgs ? perDrawArgs.value()[i] : reinterpret_cast(drawcallId); + params_setter(i, drawCall.indexCountPerInstance, drawCall.instanceCount, drawCall.startIndexLocation, + drawCall.baseVertexLocation, perDrawData); + if (perDrawArgs) + drawcallId = i; + } + } + /** + * @brief Closes buffers. + */ + void close() + { + multidrawArguments.close(); + perDrawArgsBuffer.close(); + allocatedDrawcallsInBuffer = 0; + } + /** + * @brief Returns buffer for draw call arguments. + */ + Sbuffer *getBuffer() const { return multidrawArguments.getBuf(); } + + /** + * @brief Stride for draw call arguments buffer to use it in a draw call. + */ + static uint32_t getStride() { return bytesCountPerDrawcall(); } +}; diff --git a/prog/dagorInclude/3d/dag_tex3d.h b/prog/dagorInclude/3d/dag_tex3d.h index f1e031c54..413643b97 100644 --- a/prog/dagorInclude/3d/dag_tex3d.h +++ b/prog/dagorInclude/3d/dag_tex3d.h @@ -299,6 +299,8 @@ class BaseTexture : public D3dResource protected: ~BaseTexture() override {} + + static constexpr int TEX_COPIED = 1 << 30; }; typedef BaseTexture Texture; @@ -306,6 +308,8 @@ typedef BaseTexture CubeTexture; typedef BaseTexture VolTexture; typedef BaseTexture ArrayTexture; +uint32_t auto_mip_levels_count(uint32_t w, uint32_t h, uint32_t min_size); + void assert_tex_size(Texture *tex, int w, int h); void apply_gen_tex_props(BaseTexture *t, const struct TextureMetaData &tmd, bool force_addr_from_tmd = true); diff --git a/prog/dagorInclude/gameRes/dag_stdGameRes.h b/prog/dagorInclude/gameRes/dag_stdGameRes.h index 6182332d7..f3c75bb59 100644 --- a/prog/dagorInclude/gameRes/dag_stdGameRes.h +++ b/prog/dagorInclude/gameRes/dag_stdGameRes.h @@ -22,7 +22,7 @@ void register_phys_obj_gameres_factory(); void register_ragdoll_gameres_factory(); void register_effect_gameres_factory(); void register_isl_light_gameres_factory(); -void register_animchar_gameres_factory(); +void register_animchar_gameres_factory(bool warn_about_missing_anim = true); void register_cloud_gameres_factory(); void register_material_gameres_factory(); void register_lshader_gameres_factory(); diff --git a/prog/dagorInclude/generic/dag_bitset.h b/prog/dagorInclude/generic/dag_bitset.h new file mode 100644 index 000000000..13ea7d572 --- /dev/null +++ b/prog/dagorInclude/generic/dag_bitset.h @@ -0,0 +1,170 @@ +// +// Dagor Engine 6.5 +// Copyright (C) 2023 Gaijin Games KFT. All rights reserved +// (for conditions of use see prog/license.txt) +// +#pragma once + +#include +#include +#include + + +template +class Bitset : public eastl::bitset +{ +public: + using base_type = eastl::bitset; + using this_type = Bitset; + using word_type = WordType; + using size_type = typename base_type::size_type; + + using base_type::base_type; + + using base_type::kBitsPerWord; + using base_type::kSize; + using base_type::mWord; + + static constexpr size_t NW = BITSET_WORD_COUNT(N, WordType); + + Bitset(const base_type &value) : base_type{value} {} + + size_type find_first() const + { + for (auto &word : mWord) + { + if (word) + { + const size_type fbiw = __ctz_unsafe(word); + return eastl::distance(mWord, eastl::addressof(word)) * kBitsPerWord + fbiw; + } + } + return kSize; + } + + size_type find_last() const + { + for (auto it = mWord + N - 1, end = mWord - 1; it != end; it--) + { + if (*it) + { + const size_type lbiw = __clz_unsafe(*it); + return (N - eastl::distance(mWord, it)) * kBitsPerWord + lbiw; + } + } + return kSize; + } + + size_type find_first_and_reset() + { + for (auto &word : mWord) + { + if (word) + { + auto tmp = __blsr(word); + const size_type fbiw = __ctz_unsafe(word); + word = tmp; + return eastl::distance(mWord, eastl::addressof(word)) * kBitsPerWord + fbiw; + } + } + return kSize; + } + +private: + struct IteratorBaseA + { + using this_type = IteratorBaseA; + using iterator_category = eastl::input_iterator_tag; + using difference_type = eastl::make_signed_t; + using value_type = WordType; + using pointer = WordType const *; + using reference = const WordType &; + + value_type operator*() const + { + // value = 0 means it is an end iterator, and in normal behaving code before dereferencing the iterator should check + // with it != end(), so this operator will never be called when value is 0 + G_ASSERT(value); + + return __ctz_unsafe(value); + } + + this_type &operator++() + { + value = __blsr(value); + return *this; + } + + this_type operator++(int) + { + const auto copy = *this; + ++*this; + return copy; + } + + constexpr pointer operator->() const = delete; + + constexpr bool operator==(const this_type &other) const { return value == other.value; } + constexpr bool operator!=(const this_type &other) const { return value != other.value; } + + value_type value = 0; + }; + + struct IteratorBaseB : IteratorBaseA + { + using this_type = IteratorBaseB; + using value_type = typename IteratorBaseA::value_type; + using pointer = typename IteratorBaseA::pointer; + + using IteratorBaseA::value; + + value_type operator*() const + { + if (value == 0) + { + value = *ptr; + } + return __ctz_unsafe(value); + } + + this_type &operator++() + { + value = __blsr(value); + if (value == 0) + { + ptr++; + } + return *this; + } + + constexpr bool operator==(const this_type &other) const { return ptr == other.ptr; } + constexpr bool operator!=(const this_type &other) const { return ptr != other.ptr; } + + pointer ptr = nullptr; + }; + +public: + struct Iterator : eastl::conditional_t + {}; + + constexpr Iterator begin() const + { + if constexpr (NW == 1) + return {mWord[0]}; + else + return {mWord[0], mWord}; + } + + constexpr Iterator end() const + { + if constexpr (NW == 1) + return {0}; + else + return {0, mWord + NW}; + } +}; + +// To ensure the layout doesn't change between eastl::bitset and Bitset, +// They should be interchangeable, only a few member function have been overwritten and optimized in Bitset +static_assert(sizeof(Bitset<32>) == sizeof(eastl::bitset<32>)); +static_assert(sizeof(Bitset<1024>) == sizeof(eastl::bitset<1024>)); diff --git a/prog/dagorInclude/math/dag_TMatrix4.h b/prog/dagorInclude/math/dag_TMatrix4.h index 14ea39ca0..bfcc5821c 100644 --- a/prog/dagorInclude/math/dag_TMatrix4.h +++ b/prog/dagorInclude/math/dag_TMatrix4.h @@ -317,11 +317,13 @@ INLINE real TMatrix4::det() const m[0][1] * m[1][0] * m[2][2] - m[1][2] * m[2][1] * m[0][0]; } -extern double det4x4(const TMatrix4 &m); // -#include #include #include #include diff --git a/prog/dagorInclude/math/dag_intrin.h b/prog/dagorInclude/math/dag_intrin.h index 990623fea..d43a6e53e 100644 --- a/prog/dagorInclude/math/dag_intrin.h +++ b/prog/dagorInclude/math/dag_intrin.h @@ -5,14 +5,10 @@ // #pragma once -#if defined(_MSC_VER) && !defined(__clang__) +#if (defined(_MSC_VER) && !defined(__clang__)) || defined(__BMI__) #include #endif -#if defined(__BMI__) -#include -#endif - inline unsigned __ctz_unsafe(unsigned long long value) { #if defined(__clang__) || defined(__GNUC__) @@ -64,90 +60,11 @@ inline unsigned __ctz_unsafe(unsigned long value) inline unsigned __ctz_unsafe(long value) { return __ctz_unsafe((unsigned long)value); } -inline unsigned __ctz(unsigned long long value) -{ -#if defined(__arm64__) || defined(__ARM_ARCH) // Apple silicon or ARMv7 and above - return __builtin_ctzll(value); // rbit + clz -#else -#if _TARGET_64BIT -#if defined(__clang__) - return __builtin_ia32_tzcnt_u64(value); // bsf or tzct if -mbmi -#elif defined(__GNUC__) -#ifdef __BMI__ - return __builtin_ctzll(value); // tzcnt -#else - return value ? __builtin_ctzll(value) : 64; // bsf -#endif -#elif defined(_MSC_VER) -#if defined(__AVX2__) - return _tzcnt_u64(value); // tzcnt -#else - unsigned long r; - _BitScanForward64(&r, value); // bsf - return value ? r : 64; -#endif -#endif -#endif -#endif - - if (value) //-V779 - { - unsigned n = 1; - // clang-format off - if((value & 0xFFFFFFFF) == 0) { n += 32; value >>= 32; } - if((value & 0x0000FFFF) == 0) { n += 16; value >>= 16; } - if((value & 0x000000FF) == 0) { n += 8; value >>= 8; } - if((value & 0x0000000F) == 0) { n += 4; value >>= 4; } - if((value & 0x00000003) == 0) { n += 2; value >>= 2; } - // clang-format on - return (n - ((unsigned)value & 1)); - } - - return 64; -} +inline unsigned __ctz(unsigned long long value) { return value ? __ctz_unsafe(value) : 64; } inline unsigned __ctz(long long value) { return __ctz((unsigned long long)value); } -inline unsigned __ctz(unsigned int value) -{ -#if defined(__arm64__) || defined(__ARM_ARCH) // Apple silicon or ARMv7 and above - return __builtin_ctz(value); // rbit + clz -#else -#if _TARGET_64BIT -#if defined(__clang__) - return __builtin_ia32_tzcnt_u32(value); // bsf or tzct if -mbmi -#elif defined(__GNUC__) -#ifdef __BMI__ - return __builtin_ctz(value); // tzcnt -#else - return value ? __builtin_ctz(value) : 32; // bsf -#endif -#elif defined(_MSC_VER) -#if defined(__AVX2__) - return _tzcnt_u32(value); // tzcnt -#else - unsigned long r; - _BitScanForward(&r, value); // bsf - return value ? r : 32; -#endif -#endif -#endif -#endif - - if (value) //-V779 - { - unsigned n = 1; - // clang-format off - if((value & 0x0000FFFF) == 0) { n += 16; value >>= 16; } - if((value & 0x000000FF) == 0) { n += 8; value >>= 8; } - if((value & 0x0000000F) == 0) { n += 4; value >>= 4; } - if((value & 0x00000003) == 0) { n += 2; value >>= 2; } - // clang-format on - return (n - ((unsigned)value & 1)); - } - - return 32; -} +inline unsigned __ctz(unsigned int value) { return value ? __ctz_unsafe(value) : 32; } inline unsigned __ctz(int value) { return __ctz((unsigned int)value); } @@ -171,10 +88,10 @@ inline unsigned __clz_unsafe(unsigned long long value) #ifdef __LZCNT__ return __builtin_ia32_lzcnt_u64(value); // lzcnt #else - return __builtin_clzll(value); // bsr + return __builtin_clzll(value); // bsr #endif #elif defined(__GNUC__) - return __builtin_clzll(value); // bsr or lznct if -mabm + return __builtin_clzll(value); // bsr or lznct if -mabm #elif defined(_MSC_VER) #if defined(__AVX2__) return _lzcnt_u64(value); // lzcnt @@ -211,7 +128,7 @@ inline unsigned __clz_unsafe(unsigned int value) #ifdef __LZCNT__ return __builtin_ia32_lzcnt_u32(value); // lzcnt #else - return __builtin_clz(value); // bsr + return __builtin_clz(value); // bsr #endif #elif defined(__GNUC__) return __builtin_clz(value); // bsr or lznct if -mabm @@ -250,100 +167,11 @@ inline unsigned __clz_unsafe(unsigned long value) inline unsigned __clz_unsafe(long value) { return __clz_unsafe((unsigned long)value); } -inline unsigned __clz(unsigned long long value) -{ -#if defined(__arm64__) || defined(__aarch64__) // Apple silicon or ARMv8 - return __builtin_clzll(value); // clz -#else -#if _TARGET_64BIT -#if defined(__clang__) -#ifdef __LZCNT__ - return __builtin_ia32_lzcnt_u64(value); // lzcnt -#else - return value ? __builtin_clzll(value) : 64; // bsr -#endif -#elif defined(__GNUC__) -#ifdef __LZCNT__ - return __builtin_clzll(value); // lzcnt -#else - return value ? __builtin_clzll(value) : 64; // bsr -#endif -#elif defined(_MSC_VER) -#if defined(__AVX2__) - return _lzcnt_u64(value); // lzcnt -#else - unsigned long r; - _BitScanForward64(&r, value); // bsr - return value ? r ^ 63 : 64; -#endif -#endif -#endif -#endif - - if (value) //-V779 - { - unsigned n = 0; - // clang-format off - if(value & (0xFFFFFFFF00000000ull)) { n += 32; value >>= 32; } - if(value & 0xFFFF0000) { n += 16; value >>= 16; } - if(value & 0xFFFFFF00) { n += 8; value >>= 8; } - if(value & 0xFFFFFFF0) { n += 4; value >>= 4; } - if(value & 0xFFFFFFFC) { n += 2; value >>= 2; } - if(value & 0xFFFFFFFE) { n += 1; } - // clang-format on - - return n; - } - - return 64; -} +inline unsigned __clz(unsigned long long value) { return value ? __clz_unsafe(value) : 64; } inline unsigned __clz(long long value) { return __clz((unsigned long long)value); } -inline unsigned __clz(unsigned int value) -{ -#if defined(__ARM_ARCH) - return __builtin_clz(value); // clz -#else -#if defined(__clang__) -#ifdef __LZCNT__ - return __builtin_ia32_lzcnt_u32(value); // lzcnt -#else - return value ? __builtin_clz(value) : 32; // bsr -#endif -#elif defined(__GNUC__) -#ifdef __LZCNT__ - return __builtin_clz(value); // lzcnt -#else - return value ? __builtin_clz(value) : 32; // bsr -#endif -#elif defined(_MSC_VER) -#if defined(__AVX2__) - return _lzcnt_u32(value); // lzcnt -#else - unsigned long r; - _BitScanForward(&r, value); // bsr - return value ? r ^ 31 : 32; -#endif -#endif -#endif - - if (value) //-V779 - { - unsigned n = 0; - // clang-format off - if(value & 0xFFFF0000) { n += 16; value >>= 16; } - if(value & 0xFFFFFF00) { n += 8; value >>= 8; } - if(value & 0xFFFFFFF0) { n += 4; value >>= 4; } - if(value & 0xFFFFFFFC) { n += 2; value >>= 2; } - if(value & 0xFFFFFFFE) { n += 1; } - // clang-format on - - return n; - } - - return 32; -} +inline unsigned __clz(unsigned int value) { return value ? __clz_unsafe(value) : 32; } inline unsigned __clz(int value) { return __clz((unsigned int)value); } diff --git a/prog/dagorInclude/math/dag_lsbVisitor.h b/prog/dagorInclude/math/dag_lsbVisitor.h new file mode 100644 index 000000000..9efcc5c7a --- /dev/null +++ b/prog/dagorInclude/math/dag_lsbVisitor.h @@ -0,0 +1,79 @@ +// +// Dagor Engine 6.5 +// Copyright (C) 2023 Gaijin Games KFT. All rights reserved +// (for conditions of use see prog/license.txt) +// +#pragma once + +#include +#include +#include "dag_intrin.h" + + +/// Visitor to iterate through the set bits of the initial integer value. +/// The operator* will give back the index of least significant set bit. +/// On most of the platforms it will use intrinsics to perform the calculation in 1 or 2 instructions. +/// E.g. in +/// for(auto i : LsbVisitor{0x4002}) +/// print(i); +/// +/// code example the block of for loop will execute only twice and will print out the *1* and *14* +/// +/// 0100000000000010b +/// <-- +template +struct LeastSignificantSetBitVisitor +{ + struct Iterator + { + using iterator_category = eastl::input_iterator_tag; + using value_type = eastl::conditional_t; + using difference_type = eastl::conditional_t; + using pointer = value_type const *; + using reference = const value_type &; + + value_type operator*() const + { + // value = 0 means it is an end iterator, and in normal behaving code before dereferencing the iterator should check + // with it != end(), so this operator will never be called when value is 0 + G_ASSERT(value); + + return __ctz_unsafe(value); + } + + Iterator &operator++() + { + value = __blsr(value); + return *this; + } + + Iterator operator++(int) + { + const auto copy = *this; + ++*this; + return copy; + } + + constexpr pointer operator->() const = delete; + + constexpr bool operator==(const Iterator &other) const { return value == other.value; } + constexpr bool operator!=(const Iterator &other) const { return value != other.value; } + + value_type value = 0; + }; + + constexpr Iterator begin() const { return {value}; } + constexpr Iterator end() const { return {}; } + + typename Iterator::value_type value = 0; +}; + +template +LeastSignificantSetBitVisitor(T value) -> LeastSignificantSetBitVisitor; + +template +struct LsbVisitor : LeastSignificantSetBitVisitor +{}; + +template +LsbVisitor(T value) -> LsbVisitor; diff --git a/prog/dagorInclude/memory/dag_physMem.h b/prog/dagorInclude/memory/dag_physMem.h index 7436aab77..2898c6dee 100644 --- a/prog/dagorInclude/memory/dag_physMem.h +++ b/prog/dagorInclude/memory/dag_physMem.h @@ -28,7 +28,7 @@ enum }; //! returns total number of calls to malloc since program start -KRNLIMP void *alloc_phys_mem(size_t size, size_t alignment, uint32_t prot_flags, bool cpu_cached); +KRNLIMP void *alloc_phys_mem(size_t size, size_t alignment, uint32_t prot_flags, bool cpu_cached, bool log_failure = true); //! returns total allocated memory size KRNLIMP void free_phys_mem(void *ptr); diff --git a/prog/dagorInclude/util/dag_baseDef.h b/prog/dagorInclude/util/dag_baseDef.h index b1e8ca4ad..4ef40bbb3 100644 --- a/prog/dagorInclude/util/dag_baseDef.h +++ b/prog/dagorInclude/util/dag_baseDef.h @@ -116,24 +116,13 @@ struct DestroyDeleter #endif #endif -#if defined(_MSC_VER) -#define SNPRINTF(buf, buf_size, ...) \ - do \ - { \ - int sprintf_result_len_ = _snprintf(buf, buf_size, __VA_ARGS__); \ - G_ASSERT((unsigned)sprintf_result_len_ < (unsigned)buf_size); \ - static_cast(sprintf_result_len_); \ - buf[(buf_size)-1] = 0; \ +#define SNPRINTF(buf, buf_size, ...) \ + do \ + { \ + int sprintf_result_len_ = snprintf(buf, buf_size, __VA_ARGS__); \ + G_ASSERT((unsigned)sprintf_result_len_ < (unsigned)buf_size); \ + static_cast(sprintf_result_len_); \ } while (0) -#else -#define SNPRINTF(buf, buf_size, ...) \ - do \ - { \ - int sprintf_result_len_ = _snprintf(buf, buf_size, __VA_ARGS__); \ - G_ASSERT((unsigned)sprintf_result_len_ < (unsigned)buf_size); \ - static_cast(sprintf_result_len_); \ - } while (0) -#endif #if _TARGET_PC_WIN | _TARGET_XBOX | _TARGET_C1 | _TARGET_C2 static constexpr int DAGOR_MAX_PATH = 260; diff --git a/prog/dagorInclude/util/dag_oaHashNameMap.h b/prog/dagorInclude/util/dag_oaHashNameMap.h index 516f6474e..9ee39b2f6 100644 --- a/prog/dagorInclude/util/dag_oaHashNameMap.h +++ b/prog/dagorInclude/util/dag_oaHashNameMap.h @@ -12,11 +12,9 @@ #include #include #include -#include #include #include #include -#include template > struct OAHashNameMap diff --git a/prog/dagorInclude/util/dag_watchdog.h b/prog/dagorInclude/util/dag_watchdog.h index 6b1f03248..b060b44f5 100644 --- a/prog/dagorInclude/util/dag_watchdog.h +++ b/prog/dagorInclude/util/dag_watchdog.h @@ -43,6 +43,9 @@ KRNLIMP void watchdog_init(WatchdogConfig *cfg = NULL); KRNLIMP void watchdog_shutdown(); KRNLIMP void watchdog_kick(); KRNLIMP intptr_t watchdog_set_option(int option, intptr_t p0 = 0, intptr_t p1 = 0); +#if _TARGET_PC_WIN +KRNLIMP bool is_watchdog_thread(uintptr_t thread_id); +#endif #include class ScopeSetWatchdogCurrentThreadDump diff --git a/prog/engine/_docs/render/docs/conf.py b/prog/engine/_docs/render/docs/conf.py index 5a1fbc6b4..37576017d 100644 --- a/prog/engine/_docs/render/docs/conf.py +++ b/prog/engine/_docs/render/docs/conf.py @@ -70,6 +70,7 @@ def get_headers(path): 'dag_drv3d.h', 'dag_drv3dConsts.h', 'dag_tex3d.h', + 'dag_multidrawContext.h', ]), "daBFG": get_headers(os.path.join(dagor_prog_root, 'gameLibs/publicInclude/render/daBfg')), "resourceSlot": get_headers(os.path.join(dagor_prog_root, 'gameLibs/publicInclude/render/resourceSlot')), diff --git a/prog/engine/_docs/render/docs/source/index/d3dAPI.rst b/prog/engine/_docs/render/docs/source/index/d3dAPI.rst index 7ea24d1af..e64a961a1 100644 --- a/prog/engine/_docs/render/docs/source/index/d3dAPI.rst +++ b/prog/engine/_docs/render/docs/source/index/d3dAPI.rst @@ -12,3 +12,4 @@ D3D API is our unified API which hides GAPI calls for different platforms. d3dAPI/other d3dAPI/constants d3dAPI/textures + d3dAPI/helperClasses diff --git a/prog/engine/_docs/render/docs/source/index/d3dAPI/helperClasses.rst b/prog/engine/_docs/render/docs/source/index/d3dAPI/helperClasses.rst new file mode 100644 index 000000000..127886c66 --- /dev/null +++ b/prog/engine/_docs/render/docs/source/index/d3dAPI/helperClasses.rst @@ -0,0 +1,10 @@ +Helper classes for D3D API +================================================= + +These classes are not part of core D3D API, but they simplifies common usages of D3D API. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + helperClasses/multidrawContext diff --git a/prog/engine/_docs/render/docs/source/index/d3dAPI/helperClasses/multidrawContext.rst b/prog/engine/_docs/render/docs/source/index/d3dAPI/helperClasses/multidrawContext.rst new file mode 100644 index 000000000..05d85c3b1 --- /dev/null +++ b/prog/engine/_docs/render/docs/source/index/d3dAPI/helperClasses/multidrawContext.rst @@ -0,0 +1,5 @@ +MultidrawContext +================================================= + +.. autodoxygenfile:: dag_multidrawContext.h + :project: d3dAPI diff --git a/prog/engine/_docs/render/docs/source/index/helperClasses.rst b/prog/engine/_docs/render/docs/source/index/helperClasses.rst new file mode 100644 index 000000000..0b55cda3b --- /dev/null +++ b/prog/engine/_docs/render/docs/source/index/helperClasses.rst @@ -0,0 +1,10 @@ +Helper classes +================================================= + +Here we have miscellaneous helper classes that are used to simplify rendinring code and make it safer. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + helperClasses/multidrawContext \ No newline at end of file diff --git a/prog/engine/_docs/render/setup.sh b/prog/engine/_docs/render/setup.sh index 5ef51de45..1bdc20360 100755 --- a/prog/engine/_docs/render/setup.sh +++ b/prog/engine/_docs/render/setup.sh @@ -2,7 +2,7 @@ PATH=$PATH:$GDEVTOOL/python3 python3 -m pip install -U virtualenv setuptools echo "virtualenv installed" -python3 -m venv .venv +python3 -m venv .venv --symlinks echo "virtualenv created" source .venv/Scripts/activate echo "virtualenv activated" diff --git a/prog/engine/anim/animGraph.cpp b/prog/engine/anim/animGraph.cpp index e9d8ab763..842177ad1 100644 --- a/prog/engine/anim/animGraph.cpp +++ b/prog/engine/anim/animGraph.cpp @@ -1793,7 +1793,8 @@ static bool load_generic_graph(AnimationGraph &graph, const DataBlock &blk, dag: IAnimBlendNode *node = graph.getBlendNodePtr(root); if (!node) { - ANIM_ERR("root node '%s' not found!", root); + if (!is_ignoring_unavailable_resources()) + ANIM_ERR("root node '%s' not found!", root); return false; } graph.replaceRoot(node); @@ -2092,7 +2093,8 @@ void AnimBlendCtrl_1axis::createNode(AnimationGraph &graph, const DataBlock &blk IAnimBlendNode *n = graph.getBlendNodePtr(nm, nm_suffix); if (!n) { - ANIM_ERR("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); + if (!is_ignoring_unavailable_resources()) + ANIM_ERR("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); return; } node->addBlendNode(n, cblk->getReal("start", 0), cblk->getReal("end", 1.0)); @@ -2138,7 +2140,8 @@ void AnimBlendCtrl_LinearPoly::createNode(AnimationGraph &graph, const DataBlock IAnimBlendNode *n = graph.getBlendNodePtr(nm, nm_suffix); if (!n) { - ANIM_ERR("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); + if (!is_ignoring_unavailable_resources()) + ANIM_ERR("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); return; } node->addBlendNode(n, cblk->getReal("val", 0), graph, name, var_name); @@ -2197,7 +2200,8 @@ void AnimBlendCtrl_RandomSwitcher::createNode(AnimationGraph &graph, const DataB IAnimBlendNode *n = graph.getBlendNodePtr(nm, nm_suffix); if (!n) { - logerr_ctx("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); + if (!is_ignoring_unavailable_resources()) + logerr_ctx("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); continue; } node->addBlendNode(n, cblk->getReal(i), rblk ? rblk->getInt(nm, 1) : 1); @@ -2244,7 +2248,7 @@ void AnimBlendCtrl_ParametricSwitcher::createNode(AnimationGraph &graph, const D IAnimBlendNode *n = graph.getBlendNodePtr(nm, nm_suffix); if (!n) { - if (!isOptional) + if (!isOptional && !is_ignoring_unavailable_resources()) logerr_ctx("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); continue; } @@ -2320,7 +2324,8 @@ void AnimBlendCtrl_ParametricSwitcher::createNode(AnimationGraph &graph, const D IAnimBlendNode *n = graph.getBlendNodePtr(nm.c_str(), nm_suffix); if (!n) { - ANIM_ERR("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); + if (!is_ignoring_unavailable_resources()) + ANIM_ERR("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); continue; } int eval = AnimV20::getEnumValueByName(enum_nm); @@ -2393,7 +2398,8 @@ void AnimBlendCtrl_Hub::createNode(AnimationGraph &graph, const DataBlock &blk, if (!isOptional) { delete node; - ANIM_ERR("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); + if (!is_ignoring_unavailable_resources()) + ANIM_ERR("blend node <%s> (suffix=%s) not found!", nm, nm_suffix); return; } else diff --git a/prog/engine/anim/animPostBlendCtrl.cpp b/prog/engine/anim/animPostBlendCtrl.cpp index bffb860b2..ea4431d9d 100644 --- a/prog/engine/anim/animPostBlendCtrl.cpp +++ b/prog/engine/anim/animPostBlendCtrl.cpp @@ -1381,7 +1381,8 @@ void ApbAnimateCtrl::createNode(AnimationGraph &graph, const DataBlock &blk) } if (!n || !n->isSubOf(AnimBlendNodeLeafCID)) { - fatal_x("bad BNL ref in ApbAnimateCtrl '%s', block %d", bnl_nm, name, j); + if (!is_ignoring_unavailable_resources()) + fatal_x("bad BNL ref in ApbAnimateCtrl '%s', block %d", bnl_nm, name, j); continue; } diff --git a/prog/engine/baseUtil/safeArg.cpp b/prog/engine/baseUtil/safeArg.cpp index cd43d9daf..b3a396157 100644 --- a/prog/engine/baseUtil/safeArg.cpp +++ b/prog/engine/baseUtil/safeArg.cpp @@ -445,8 +445,6 @@ int DagorSafeArg::count_len(const char *fmt, const DagorSafeArg *arg, int anum) int DagorSafeArg::print_fmt(char *buf, int len, const char *fmt, const DagorSafeArg *arg, int anum) { - G_FAST_ASSERT(buf && fmt && len > 0); // Don't use regular `G_ASSERT` since it might create unwanted recursion - if (!anum) { int l = (int)strlen(fmt); @@ -460,6 +458,7 @@ int DagorSafeArg::print_fmt(char *buf, int len, const char *fmt, const DagorSafe int carg = 0; char fmt_buf[32]; char *bufp = buf; + len = max(len, 0); // do nothing when len < 0 for (char c = *fmt; c && len; fmt++, c = *fmt) { diff --git a/prog/engine/baseUtil/watchdog.cpp b/prog/engine/baseUtil/watchdog.cpp index 5a6e083a5..39162f633 100644 --- a/prog/engine/baseUtil/watchdog.cpp +++ b/prog/engine/baseUtil/watchdog.cpp @@ -277,5 +277,9 @@ intptr_t watchdog_set_option(int option, intptr_t p0, intptr_t p1) return -1; } +#if _TARGET_PC_WIN +bool is_watchdog_thread(uintptr_t thread_id) { return GetThreadId(*(HANDLE *)watchdog_thread->getCurrentThreadIdPtr()) == thread_id; } +#endif + #define EXPORT_PULL dll_pull_baseutil_watchdog #include diff --git a/prog/engine/drv/drv3d_DX11/basetex.cpp b/prog/engine/drv/drv3d_DX11/basetex.cpp index cf7be5325..dcfa7bccb 100644 --- a/prog/engine/drv/drv3d_DX11/basetex.cpp +++ b/prog/engine/drv/drv3d_DX11/basetex.cpp @@ -103,8 +103,6 @@ extern uint32_t get_texture_res_size(const BaseTex *bt, int skip = 0); extern HRESULT map_without_context_blocking(ID3D11Resource *resource, UINT subresource, D3D11_MAP maptype, bool nosyslock, D3D11_MAPPED_SUBRESOURCE *mapped); -static constexpr int TEX_COPIED = 1 << 30; - template inline void set_res_view_mip(T &d, uint32_t mip_level, int32_t mip_count) { diff --git a/prog/engine/drv/drv3d_DX11/driver.h b/prog/engine/drv/drv3d_DX11/driver.h index 356fd1bdf..de1d942f4 100644 --- a/prog/engine/drv/drv3d_DX11/driver.h +++ b/prog/engine/drv/drv3d_DX11/driver.h @@ -304,8 +304,8 @@ struct RenderState : public FrameStateTM bool rtModified; uint8_t viewModified; // VIEWMOD_ bool scissorModified; - bool psModified; bool vsModified; + bool psModified; bool csModified; bool vertexInputModified; bool rasterizerModified; @@ -339,7 +339,7 @@ struct RenderState : public FrameStateTM Driver3dRenderTarget nextRtState; Driver3dRenderTarget currRtState; - uint8_t stencilRef = 0; + uint8_t stencilRef; float blendFactor[BLEND_FACTORS_COUNT]; int8_t maxUsedTarget; @@ -347,26 +347,32 @@ struct RenderState : public FrameStateTM RenderState() : modified(true), - depthStencilModified(true), - alphaBlendModified(true), rtModified(true), viewModified(VIEWMOD_FULL), scissorModified(false), - psModified(true), vsModified(true), - vertexInputModified(true), + psModified(true), csModified(true), + vertexInputModified(true), + rasterizerModified(true), + alphaBlendModified(true), + depthStencilModified(true), + srgb_bb_write(0), hdgBits(0), hullTopology(0), - rasterizerModified(true), - maxUsedTarget(-1), + nextVertexInput{}, + currVertexInput{}, currPrimType(0), nextVdecl(BAD_HANDLE), - nextPixelShader(BAD_HANDLE), nextVertexShader(BAD_HANDLE), + nextPixelShader(BAD_HANDLE), nextComputeShader(BAD_HANDLE), - currentFrameDip(0), - srgb_bb_write(0) + nextRasterizerState{}, + nextRtState{}, + currRtState{}, + stencilRef(0), + maxUsedTarget(-1), + currentFrameDip(0) { blendFactor[0] = 1.0f; blendFactor[1] = 1.0f; @@ -384,7 +390,6 @@ struct RenderState : public FrameStateTM nextRtState.setBackbufColor(); } - void resetFrame() { modified = true; diff --git a/prog/engine/drv/drv3d_DX11/drvmain.cpp b/prog/engine/drv/drv3d_DX11/drvmain.cpp index 08e5ffe3a..c6905d8e6 100644 --- a/prog/engine/drv/drv3d_DX11/drvmain.cpp +++ b/prog/engine/drv/drv3d_DX11/drvmain.cpp @@ -605,17 +605,6 @@ int d3d::driver_command(int command, void *par1, void *par2, void *par3) return secondary_backbuffer_color_tex ? 1 : 0; } - case DRV3D_COMMAND_GET_RESOLUTION: - { - if (par1 && par2) - { - *((int *)par1) = resolution.x; - *((int *)par2) = resolution.y; - return 1; - } - return 0; - } - case DRV3D_COMMAND_OVERRIDE_MAX_ANISOTROPY_LEVEL: { override_max_anisotropy_level = (int)(intptr_t)par1; //-V542 diff --git a/prog/engine/drv/drv3d_DX11/shaders.cpp b/prog/engine/drv/drv3d_DX11/shaders.cpp index 642f8ad18..21170544a 100644 --- a/prog/engine/drv/drv3d_DX11/shaders.cpp +++ b/prog/engine/drv/drv3d_DX11/shaders.cpp @@ -135,7 +135,7 @@ void ConstantBuffers::create() desc.StructureByteStride = 0; { - G_STATIC_ASSERT(MAX_PS_CONSTS <= MIN_PS_CONSTS + PS_CONSTS_STEP * PS_BINS); + G_STATIC_ASSERT(MAX_PS_CONSTS <= MIN_PS_CONSTS + PS_CONSTS_STEP * (PS_BINS - 1)); for (int i = 0; i < PS_BINS; ++i) { desc.ByteWidth = (MIN_PS_CONSTS + PS_CONSTS_STEP * i) * sizeof(vec4f); diff --git a/prog/engine/drv/drv3d_DX11/shaders.h b/prog/engine/drv/drv3d_DX11/shaders.h index 17cb811a0..3f009a9b5 100644 --- a/prog/engine/drv/drv3d_DX11/shaders.h +++ b/prog/engine/drv/drv3d_DX11/shaders.h @@ -36,7 +36,7 @@ struct ConstantBuffers { MIN_PS_CONSTS = 16, PS_CONSTS_STEP = 32, - PS_BINS = 4 + PS_BINS = 5 // The largest bin must fit MAX_PS_CONSTS }; int psCurrentBuffer; carray psConstBuffer; diff --git a/prog/engine/drv/drv3d_DX11/texture.cpp b/prog/engine/drv/drv3d_DX11/texture.cpp index 28ba78542..f2dc9b627 100644 --- a/prog/engine/drv/drv3d_DX11/texture.cpp +++ b/prog/engine/drv/drv3d_DX11/texture.cpp @@ -581,61 +581,12 @@ int dxgi_format_to_bpp(DXGI_FORMAT fmt) return 0; } -uint32_t texfmt_to_d3dformat(/*D3DFORMAT*/ uint32_t fmt) -{ - switch (fmt) - { - case TEXFMT_A8R8G8B8: return D3DFMT_A8R8G8B8; - case TEXFMT_R8G8B8A8: return D3DFMT_A8B8G8R8; - case TEXFMT_A2B10G10R10: return D3DFMT_A2B10G10R10; - case TEXFMT_A16B16G16R16: return D3DFMT_A16B16G16R16; - case TEXFMT_A16B16G16R16F: return D3DFMT_A16B16G16R16F; - case TEXFMT_A32B32G32R32F: return D3DFMT_A32B32G32R32F; - case TEXFMT_G16R16: return D3DFMT_G16R16; - case TEXFMT_V16U16: return D3DFMT_V16U16; - case TEXFMT_L16: return D3DFMT_L16; - case TEXFMT_A8: return D3DFMT_A8; - case TEXFMT_R8: return D3DFMT_L8; - case TEXFMT_A8L8: return D3DFMT_A8L8; - case TEXFMT_G16R16F: return D3DFMT_G16R16F; - case TEXFMT_G32R32F: return D3DFMT_G32R32F; - case TEXFMT_R16F: return D3DFMT_R16F; - case TEXFMT_R32F: return D3DFMT_R32F; - case TEXFMT_DXT1: return D3DFMT_DXT1; - case TEXFMT_DXT3: return D3DFMT_DXT3; - case TEXFMT_DXT5: return D3DFMT_DXT5; - case TEXFMT_A4R4G4B4: return D3DFMT_A4R4G4B4; // dxgi 1.2 - case TEXFMT_A1R5G5B5: return D3DFMT_A1R5G5B5; - case TEXFMT_R5G6B5: return D3DFMT_R5G6B5; - case TEXFMT_ATI1N: return _MAKE4C('ATI1'); - case TEXFMT_ATI2N: return _MAKE4C('ATI2'); - case TEXFMT_BC6H: return _MAKE4C('BC6H'); - case TEXFMT_BC7: return _MAKE4C('BC7 '); - } - G_ASSERTF(0, "can't convert tex format: %d", fmt); - return D3DFMT_A8R8G8B8; -} - - void override_unsupported_bc(uint32_t &cflg) { if ((cflg & TEXFMT_MASK) == TEXFMT_BC7 && g_device_desc.shaderModel < 5.0_sm) cflg = (cflg & ~TEXFMT_MASK) | TEXFMT_DXT5; } - -static uint32_t auto_mip_levels_count(uint32_t w, uint32_t h, uint32_t mnsz) -{ - uint32_t lev = 1; - while (w > mnsz && h > mnsz) - { - lev++; - w >>= 1; - h >>= 1; - } - return lev; -} - uint32_t calc_surface_size(uint32_t w, uint32_t h, DXGI_FORMAT fmt) { switch (fmt) @@ -1270,10 +1221,6 @@ void BaseTex::destroy() destroyObject(); } - -static constexpr int TEX_COPIED = 1 << 30; - - #define LOCK_IN_THREAD_TIMEOUT_MS (500) HRESULT map_without_context_blocking(ID3D11Resource *resource, UINT subresource, D3D11_MAP maptype, bool nosyslock, diff --git a/prog/engine/drv/drv3d_DX12/bindless.cpp b/prog/engine/drv/drv3d_DX12/bindless.cpp index 43d23783b..cf3f77d82 100644 --- a/prog/engine/drv/drv3d_DX12/bindless.cpp +++ b/prog/engine/drv/drv3d_DX12/bindless.cpp @@ -176,7 +176,9 @@ void frontend::BindlessManager::updateBindlessTexture(DeviceContext &ctx, uint32 slot = info; } - texture->setUsedWithBindless(); +#if DAGOR_DBGLEVEL > 0 + texture->setWasUsed(); +#endif ctx.bindlessSetResourceDescriptor(index, image, view); } diff --git a/prog/engine/drv/drv3d_DX12/bindless.h b/prog/engine/drv/drv3d_DX12/bindless.h index ade913726..f4e1966a0 100644 --- a/prog/engine/drv/drv3d_DX12/bindless.h +++ b/prog/engine/drv/drv3d_DX12/bindless.h @@ -18,7 +18,7 @@ namespace drv3d_dx12 class Device; class DeviceContext; -struct BaseTex; +class BaseTex; class Image; class ShaderResourceViewDescriptorHeapManager; class SamplerDescriptorHeapManager; diff --git a/prog/engine/drv/drv3d_DX12/debug/event_marker_tracker.h b/prog/engine/drv/drv3d_DX12/debug/event_marker_tracker.h index e915db5e4..4623262ae 100644 --- a/prog/engine/drv/drv3d_DX12/debug/event_marker_tracker.h +++ b/prog/engine/drv/drv3d_DX12/debug/event_marker_tracker.h @@ -1,8 +1,11 @@ #pragma once -#include #include +#include +#include +#include + namespace drv3d_dx12::debug::event_marker { @@ -12,80 +15,80 @@ class Tracker { static constexpr char separator = '/'; - using NameTableType = eastl::unordered_set; + OAHashNameMap nameTable; + using FullPathIdx = uint32_t; + using NameIdx = uint32_t; + const uint32_t INVALID_IDX = ~0u; struct EventPathEntry { - const EventPathEntry *parent = nullptr; - const eastl::string *name = nullptr; - // We keep a persistent copy of the full path for systems that rely on this, like Nvidia Aftermath - mutable eastl::string fullPath; - + FullPathIdx parent; + NameIdx name; friend bool operator==(const EventPathEntry &l, const EventPathEntry &r) { return l.parent == r.parent && l.name == r.name; } }; + dag::Vector pathTable; + dag::Vector fullpathTable; + struct EventPathEntryHasher { - size_t operator()(const EventPathEntry &e) const - { - auto parentPtr = reinterpret_cast(e.parent); - auto namePtr = reinterpret_cast(e.name); - return eastl::hash{}(parentPtr ^ namePtr); - } + size_t operator()(const EventPathEntry &e) const { return eastl::hash{}((e.parent << 16) | e.name); } }; - using PathTableType = eastl::unordered_set; - NameTableType nameTable; - PathTableType pathTable; - const EventPathEntry *currentPath = nullptr; - const eastl::string *lastMarker = nullptr; + + ska::flat_hash_map pathLookup; + FullPathIdx currentPath = INVALID_IDX; + NameIdx lastMarker = INVALID_IDX; public: eastl::string_view beginEvent(eastl::string_view name) { - auto stringRef = nameTable.emplace(name.data(), name.length()).first; + NameIdx nameId = nameTable.addNameId(name.data(), name.length()); - EventPathEntry path; - path.parent = currentPath; - path.name = &*stringRef; + const EventPathEntry previousEntry = {currentPath, nameId}; - auto [pathRef, wasNew] = pathTable.insert(path); - // create full path only on new entry - if (wasNew) + if (pathLookup.find(previousEntry) == pathLookup.end()) { - if (currentPath) + currentPath = pathTable.size(); + pathTable.push_back(previousEntry); + pathLookup[previousEntry] = currentPath; + if (previousEntry.parent != INVALID_IDX) { - pathRef->fullPath.reserve(currentPath->fullPath.length() + 1 + name.length()); - pathRef->fullPath.assign(begin(currentPath->fullPath), end(currentPath->fullPath)); - pathRef->fullPath.push_back(separator); - pathRef->fullPath.append(begin(name), end(name)); + fullpathTable.resize(pathTable.size()); + fullpathTable.back().reserve(fullpathTable[previousEntry.parent].length() + 1 + name.length()); + fullpathTable.back().assign(fullpathTable[previousEntry.parent].data(), fullpathTable[previousEntry.parent].length()); + fullpathTable.back().push_back(separator); } else { - pathRef->fullPath.assign(begin(name), end(name)); + fullpathTable.resize(pathTable.size()); + fullpathTable.back().assign(name.data(), name.length()); } } - currentPath = &*pathRef; + else + { + currentPath = pathLookup[previousEntry]; + } - return {currentPath->name->data(), currentPath->name->length()}; + return {nameTable.getName(nameId), name.length()}; } void endEvent() { - if (currentPath) + if (currentPath != INVALID_IDX) { - currentPath = currentPath->parent; + currentPath = pathTable[currentPath].parent; } } eastl::string_view marker(eastl::string_view name) { - lastMarker = &*nameTable.emplace(name.data(), name.length()).first; - return {lastMarker->data(), lastMarker->length()}; + lastMarker = nameTable.addNameId(name.data(), name.length()); + return {nameTable.getName(lastMarker), name.length()}; } eastl::string_view currentEventPath() const { - if (currentPath) + if (currentPath != INVALID_IDX) { - return {currentPath->fullPath.data(), currentPath->fullPath.length()}; + return {fullpathTable[currentPath].data(), fullpathTable[currentPath].length()}; } else { @@ -95,9 +98,13 @@ class Tracker eastl::string_view currentEvent() const { - if (currentPath) + if (currentPath != INVALID_IDX) { - return {currentPath->name->data(), currentPath->name->length()}; + const uint32_t nameId = pathTable[currentPath].name; + const char *eventName = nameTable.getName(nameId); + if (!eventName) + return {}; + return {eventName, strlen(eventName)}; } else { @@ -107,9 +114,12 @@ class Tracker eastl::string_view currentMarker() const { - if (lastMarker) + if (lastMarker != INVALID_IDX) { - return {lastMarker->data(), lastMarker->length()}; + const char *markerName = nameTable.getName(lastMarker); + if (!markerName) + return {}; + return {markerName, strlen(markerName)}; } else { diff --git a/prog/engine/drv/drv3d_DX12/device.h b/prog/engine/drv/drv3d_DX12/device.h index 244e9345c..abb2be132 100644 --- a/prog/engine/drv/drv3d_DX12/device.h +++ b/prog/engine/drv/drv3d_DX12/device.h @@ -685,8 +685,9 @@ class Device : public DeviceErrroState, public DeviceErrorObserver, prot #else unsigned getVariableShadingRateTier() const { - // T2 can never be defined without T1, so this always yields 1 if only T1 is define and 2 with both are. - return unsigned(caps.test(Caps::SHADING_RATE_T2)) + unsigned(caps.test(Caps::SHADING_RATE_T1)); + // The T1's bit is the 0b01, the T2's bit is the 0b10. + // T2 can never be defined without T1, so this always yields 1 if only T1 is define and 3 with both are. + return caps.test(Caps::SHADING_RATE_T2) ? 3 : (caps.test(Caps::SHADING_RATE_T1) ? 1 : 0); } #endif diff --git a/prog/engine/drv/drv3d_DX12/device_context.cpp b/prog/engine/drv/drv3d_DX12/device_context.cpp index 973635d82..972ebe558 100644 --- a/prog/engine/drv/drv3d_DX12/device_context.cpp +++ b/prog/engine/drv/drv3d_DX12/device_context.cpp @@ -95,6 +95,29 @@ U &resolve(T &, U &u) #undef HANDLE_RETURN_ADDRESS } // namespace +BufferImageCopy drv3d_dx12::calculate_texture_subresource_copy_info(const Image &texture, uint32_t subresource_index, uint64_t offset) +{ + auto subResInfo = calculate_texture_subresource_info(texture, SubresourceIndex::make(subresource_index)); + return {{offset, subResInfo.footprint}, subresource_index, {0, 0, 0}}; +} + +TextureMipsCopyInfo drv3d_dx12::calculate_texture_mips_copy_info(const Image &texture, uint32_t mip_levels) +{ + G_ASSERT(mip_levels <= MAX_MIPMAPS); + TextureMipsCopyInfo copies{mip_levels}; + uint64_t offset = 0; + for (uint32_t j = 0; j < mip_levels; ++j) + { + BufferImageCopy © = copies[j]; + auto subResInfo = calculate_texture_mip_info(texture, MipMapIndex::make(j)); + copy = {{offset, subResInfo.footprint}, calculate_subresource_index(j, 0, 0, mip_levels, 1), {0, 0, 0}}; + G_ASSERT(copy.layout.Offset % D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT == 0); + offset += subResInfo.rowCount * copy.layout.Footprint.RowPitch; + offset = (offset + D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1) & ~(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1); + } + return copies; +} + void DeviceContext::replayCommands() { ExecutionContext executionContext // diff --git a/prog/engine/drv/drv3d_DX12/device_context.h b/prog/engine/drv/drv3d_DX12/device_context.h index 8d36b51f2..63290eb7d 100644 --- a/prog/engine/drv/drv3d_DX12/device_context.h +++ b/prog/engine/drv/drv3d_DX12/device_context.h @@ -2,6 +2,7 @@ #include #include "query_manager.h" #include +#include #include #include #include <3d/dag_drvDecl.h> @@ -334,6 +335,13 @@ struct BufferImageCopy UINT subresourceIndex; Offset3D imageOffset; }; + +BufferImageCopy calculate_texture_subresource_copy_info(const Image &texture, uint32_t subresource_index = 0, uint64_t offset = 0); + +using TextureMipsCopyInfo = eastl::fixed_vector; + +TextureMipsCopyInfo calculate_texture_mips_copy_info(const Image &texture, uint32_t mip_levels); + struct ImageCopy { SubresourceIndex srcSubresource; diff --git a/prog/engine/drv/drv3d_DX12/dx12.cpp b/prog/engine/drv/drv3d_DX12/dx12.cpp index 7d890fdc3..5373ecb1f 100644 --- a/prog/engine/drv/drv3d_DX12/dx12.cpp +++ b/prog/engine/drv/drv3d_DX12/dx12.cpp @@ -1452,16 +1452,9 @@ int d3d::driver_command(int command, void *par1, void *par2, void *par3) // case DRV3D_COMMAND_GET_SECONDARY_BACKBUFFER: // break; - // case DRV3D_COMMAND_GET_VENDOR: - // break; - case DRV3D_COMMAND_GET_RESOLUTION: - if (par1 && par2) - { - *((int *)par1) = api_state.windowState.settings.resolutionX; - *((int *)par2) = api_state.windowState.settings.resolutionY; - return 1; - } - break; + // case DRV3D_COMMAND_GET_VENDOR: + // break; + case DRV3D_COMMAND_BEGIN_MRT_CLEAR_SEQUENCE: api_state.state.beginMrtClear(reinterpret_cast(par1)); // tell caller that we implement this optimization @@ -1773,7 +1766,6 @@ void recover_textures() if (tex->rld) { PushTextureAddressMode pushMode{tex}; - tex->setDelayedCreate(true); tex->rld->reloadD3dRes(tex); } else if ((tex->cflg & TEXCF_SYSTEXCOPY) && data_size(tex->texCopy)) @@ -1787,7 +1779,6 @@ void recover_textures() hdr.flags = flg | (u & hdr.FLG_ADDRU_MASK) | ((v << 4) & hdr.FLG_ADDRV_MASK); InPlaceMemLoadCB mcrd(tex->texCopy.data() + sizeof(hdr), data_size(tex->texCopy) - (int)sizeof(hdr)); - tex->setDelayedCreate(true); d3d::load_ddsx_tex_contents(tex, hdr, mcrd, sysCopyQualityId); } else @@ -2024,12 +2015,17 @@ bool d3d::check_texformat(int cflg) int d3d::get_max_sample_count(int cflg) { + G_UNUSED(cflg); + return 1; // Force 1 sample, untill multisampled PSO is ready. + + /* auto dxgiFormat = FormatStore::fromCreateFlags(cflg).asDxGiFormat(); for (int32_t numSamples = get_sample_count(TEXCF_SAMPLECOUNT_MAX); numSamples > 1; numSamples /= 2) if (api_state.device.isSamplesCountSupported(dxgiFormat, numSamples)) return numSamples; return 1; + */ } bool d3d::issame_texformat(int cflg1, int cflg2) @@ -2354,12 +2350,12 @@ bool d3d::set_rwtex(unsigned shader_stage, unsigned unit, BaseTexture *tex, uint ImageViewState view; if (texture) { - if (!texture->isUAV()) + if (!texture->isUav()) { logerr("Texture %p <%s> used as UAV texture, but has no UAV flag set", texture, texture->getResName()); return false; } - view = texture->getViewInfoUAV(MipMapIndex::make(mip_level), ArrayLayerIndex::make(face), as_uint); + view = texture->getViewInfoUav(MipMapIndex::make(mip_level), ArrayLayerIndex::make(face), as_uint); } api_state.state.setStageUAVTexture(shader_stage, unit, texture, view); return true; @@ -2371,16 +2367,15 @@ bool d3d::clear_rwtexi(BaseTexture *tex, const unsigned val[4], uint32_t face, u BaseTex *texture = cast_to_texture_base(tex); if (texture) { - if (!texture->isUAV()) + if (!texture->isUav()) { logerr("Texture %p <%s> cleared as UAV(i) texture, but has no UAV flag set", texture, texture->getResName()); return false; } - texture->setWasCopiedToStage(false); Image *image = texture->getDeviceImage(); // false for is_uint is same as in DX11 backend api_state.device.getContext().clearUAVTexture(image, - texture->getViewInfoUAV(MipMapIndex::make(mip_level), ArrayLayerIndex::make(face), false), val); + texture->getViewInfoUav(MipMapIndex::make(mip_level), ArrayLayerIndex::make(face), false), val); } return true; } @@ -2391,15 +2386,14 @@ bool d3d::clear_rwtexf(BaseTexture *tex, const float val[4], uint32_t face, uint BaseTex *texture = cast_to_texture_base(tex); if (texture) { - if (!texture->isUAV()) + if (!texture->isUav()) { logerr("Texture %p <%s> cleared as UAV(f) texture, but has no UAV flag set", texture, texture->getResName()); return false; } - texture->setWasCopiedToStage(false); Image *image = texture->getDeviceImage(); api_state.device.getContext().clearUAVTexture(image, - texture->getViewInfoUAV(MipMapIndex::make(mip_level), ArrayLayerIndex::make(face), false), val); + texture->getViewInfoUav(MipMapIndex::make(mip_level), ArrayLayerIndex::make(face), false), val); } return true; } @@ -3317,11 +3311,6 @@ void drv3d_dx12::notify_discard(Sbuffer *buffer, bool check_vb, bool check_const api_state.state.notifyDiscard(buffer, check_vb, check_const, check_tex, check_storage); } -void drv3d_dx12::execute_texture_replace(const TextureReplacer &replacer) -{ - api_state.state.replaceTexture(api_state.device.getContext(), replacer); -} - Texture *d3d::get_backbuffer_tex() { return api_state.device.getContext().getSwapchainColorTexture(); } Texture *d3d::get_secondary_backbuffer_tex() { return api_state.device.getContext().getSwapchainSecondaryColorTexture(); } @@ -3993,7 +3982,7 @@ void d3d::resource_barrier(ResourceBarrierDesc desc, GpuPipeline gpu_pipeline /* } auto btex = cast_to_texture_base(tex); - if (!validate_texture_barrier(state, btex->getFormat().isDepth(), btex->isRenderTarget(), btex->isUAV(), gpu_pipeline)) + if (!validate_texture_barrier(state, btex->getFormat().isDepth(), btex->isRenderTarget(), btex->isUav(), gpu_pipeline)) { logerr("DX12: Barrier validation resulted in skipped barrier for %s", btex->getResName()); return; diff --git a/prog/engine/drv/drv3d_DX12/frontend_state.h b/prog/engine/drv/drv3d_DX12/frontend_state.h index a6f8e06b4..a149837c8 100644 --- a/prog/engine/drv/drv3d_DX12/frontend_state.h +++ b/prog/engine/drv/drv3d_DX12/frontend_state.h @@ -213,7 +213,7 @@ struct FrontendState auto tex = cast_to_texture_base(rts.getColor(i).tex); if (tex) { - tex->setRTVBinding(i, in_use); + tex->setRtvBinding(i, in_use); } } } @@ -225,7 +225,7 @@ struct FrontendState { tex = ctx.getSwapchainDepthStencilTextureAnySize(); } - tex->setDSVBinding(in_use); + tex->setDsvBinding(in_use); } } @@ -501,8 +501,8 @@ struct FrontendState const Driver3dRenderTarget::RTState rtState = renderTargets.getColor(i); if (rtState.tex) { - cast_to_texture_base(rtState.tex)->dirtyBoundUAVsNoLock(); - cast_to_texture_base(rtState.tex)->dirtyBoundSRVsNoLock(); + cast_to_texture_base(rtState.tex)->dirtyBoundUavsNoLock(); + cast_to_texture_base(rtState.tex)->dirtyBoundSrvsNoLock(); } } } @@ -517,14 +517,14 @@ struct FrontendState auto ot = cast_to_texture_base(renderTargets.getColor(index).tex); if (ot) { - ot->setRTVBinding(index, false); + ot->setRtvBinding(index, false); } } if (texture) { - texture->setRTVBinding(index, true); - texture->dirtyBoundSRVsNoLock(); - texture->dirtyBoundUAVsNoLock(); + texture->setRtvBinding(index, true); + texture->dirtyBoundSrvsNoLock(); + texture->dirtyBoundUavsNoLock(); } if (toggleBits.test(ToggleState::MRT_CLEAR)) { @@ -545,7 +545,7 @@ struct FrontendState auto ot = cast_to_texture_base(renderTargets.getColor(index).tex); if (ot) { - ot->setRTVBinding(index, false); + ot->setRtvBinding(index, false); } } renderTargets.removeColor(index); @@ -563,7 +563,7 @@ struct FrontendState auto tex = cast_to_texture_base(renderTargets.getColor(i).tex); if (tex) { - tex->setRTVBinding(i, false); + tex->setRtvBinding(i, false); } } } @@ -581,9 +581,9 @@ struct FrontendState { ot = ctx.getSwapchainDepthStencilTextureAnySize(); } - ot->setDSVBinding(false); + ot->setDsvBinding(false); } - texture->setDSVBinding(true); + texture->setDsvBinding(true); renderTargets.setDepth(texture, face_index, read_only); } void removeDepthStencilTarget(DeviceContext &ctx) @@ -597,7 +597,7 @@ struct FrontendState { ot = ctx.getSwapchainDepthStencilTextureAnySize(); } - ot->setDSVBinding(false); + ot->setDsvBinding(false); } renderTargets.removeDepth(); } @@ -610,7 +610,7 @@ struct FrontendState auto ot = cast_to_texture_base(renderTargets.getDepth().tex); if (ot) { - ot->setDSVBinding(false); + ot->setDsvBinding(false); } } renderTargets.setBackbufDepth(); @@ -618,7 +618,7 @@ struct FrontendState auto swDST = ctx.getSwapchainDepthStencilTextureAnySize(); if (swDST) { - swDST->setDSVBinding(true); + swDST->setDsvBinding(true); } } @@ -670,7 +670,7 @@ struct FrontendState OSSpinlockScopedLock resourceBindingLock(resourceBindingGuard); if (target.tRegisterTextures[index]) { - target.tRegisterTextures[index]->setSRVBinding(stage, index, false); + target.tRegisterTextures[index]->setSrvBinding(stage, index, false); target.tRegisterTextures[index] = nullptr; } target.markDirtyT(index, target.tRegisterBuffers[index] != buffer); @@ -690,7 +690,7 @@ struct FrontendState OSSpinlockScopedLock resourceBindingLock(resourceBindingGuard); if (target.uRegisterTextures[index]) { - target.uRegisterTextures[index]->setUAVBinding(stage, index, false); + target.uRegisterTextures[index]->setUavBinding(stage, index, false); target.uRegisterTextures[index] = nullptr; } target.markDirtyU(index, target.uRegisterBuffers[index] != buffer); @@ -717,18 +717,18 @@ struct FrontendState OSSpinlockScopedLock resourceBindingLock(resourceBindingGuard); if (texture) { - texture->dirtyBoundUAVsNoLock(); - texture->dirtyBoundRTVsNoLock(); + texture->dirtyBoundUavsNoLock(); + texture->dirtyBoundRtvsNoLock(); } target.markDirtyT(index, target.tRegisterTextures[index] != texture); target.markDirtyS(index, target.tRegisterTextures[index] != texture); if (target.tRegisterTextures[index]) { - target.tRegisterTextures[index]->setSRVBinding(stage, index, false); + target.tRegisterTextures[index]->setSrvBinding(stage, index, false); } if (texture) { - texture->setSRVBinding(stage, index, true); + texture->setSrvBinding(stage, index, true); } target.tRegisterTextures[index] = texture; target.tRegisterBuffers[index] = nullptr; @@ -756,17 +756,17 @@ struct FrontendState OSSpinlockScopedLock resourceBindingLock(resourceBindingGuard); if (texture) { - texture->dirtyBoundSRVsNoLock(); - texture->dirtyBoundRTVsNoLock(); + texture->dirtyBoundSrvsNoLock(); + texture->dirtyBoundRtvsNoLock(); } target.markDirtyU(index, target.uRegisterTextures[index] != texture || target.uRegisterTextureViews[index] != view); if (target.uRegisterTextures[index]) { - target.uRegisterTextures[index]->setUAVBinding(stage, index, false); + target.uRegisterTextures[index]->setUavBinding(stage, index, false); } if (texture) { - texture->setUAVBinding(stage, index, true); + texture->setUavBinding(stage, index, true); } target.uRegisterTextures[index] = texture; target.uRegisterTextureViews[index] = view; @@ -1213,64 +1213,67 @@ struct FrontendState } #if !_TARGET_XBOXONE - if (dirtyState.test(DirtyState::VARIABLE_RATE_SHADING) && (device.getVariableShadingRateTier() > 0)) + if (auto shadingTier = device.getVariableShadingRateTier()) { - ctx.setVariableRateShading(constantShadingRate, vertexShadingRateCombiner, pixelShadingRateCombiner); - // a few warnings about wrong configurations - if (shadingRateTexture) + if (dirtyState.test(DirtyState::VARIABLE_RATE_SHADING)) { - if (D3D12_SHADING_RATE_COMBINER_PASSTHROUGH == pixelShadingRateCombiner) + ctx.setVariableRateShading(constantShadingRate, vertexShadingRateCombiner, pixelShadingRateCombiner); + // a few warnings about wrong configurations + if (shadingRateTexture) { - // sort of valid usage, but when no rate texture is needed it should be set to null - logwarn("DX12: VRS: Pixel Shading Rate Combiner is set to PASSTHROUGH, but a sampling " - "rate texture is set, with this combiner the texture is not used"); + if (DAGOR_UNLIKELY(D3D12_SHADING_RATE_COMBINER_PASSTHROUGH == pixelShadingRateCombiner)) + { + // sort of valid usage, but when no rate texture is needed it should be set to null + logwarn("DX12: VRS: Pixel Shading Rate Combiner is set to PASSTHROUGH, but a sampling " + "rate texture is set, with this combiner the texture is not used"); + } } - } - else if (device.getVariableShadingRateTier() == 1) - { - // on T1 combiners have no effect - if (D3D12_SHADING_RATE_COMBINER_PASSTHROUGH != pixelShadingRateCombiner) + else if (shadingTier == 1) { - logwarn("DX12: VRS: Device is VRS Tier 1 and Pixel Shading Rate Combiner is not " - "PASSTHROUGH, which is invalid and will be ignored"); + // on T1 combiners have no effect + if (DAGOR_UNLIKELY(D3D12_SHADING_RATE_COMBINER_PASSTHROUGH != pixelShadingRateCombiner)) + { + logwarn("DX12: VRS: Device is VRS Tier 1 and Pixel Shading Rate Combiner is not " + "PASSTHROUGH, which is invalid and will be ignored"); + } + if (DAGOR_UNLIKELY(D3D12_SHADING_RATE_COMBINER_PASSTHROUGH != vertexShadingRateCombiner)) + { + logwarn("DX12: VRS: Device is VRS Tier 1 and Vertex Shading Rate Combiner is not " + "PASSTHROUGH, which is invalid and will be ignored"); + } } - if (D3D12_SHADING_RATE_COMBINER_PASSTHROUGH != vertexShadingRateCombiner) + else { - logwarn("DX12: VRS: Device is VRS Tier 1 and Vertex Shading Rate Combiner is not " - "PASSTHROUGH, which is invalid and will be ignored"); + if (DAGOR_UNLIKELY(D3D12_SHADING_RATE_COMBINER_OVERRIDE == pixelShadingRateCombiner)) + { + // this is turning VRS off in a wired way + logwarn("DX12: VRS: Pixel Shading Rate Combiner is set to OVERRIDE, but no sampling rate " + "texture is set, it will override to 1x1"); + } + if (DAGOR_UNLIKELY(D3D12_SHADING_RATE_COMBINER_MIN == pixelShadingRateCombiner)) + { + // this is turning VRS off in a wired way + logwarn("DX12: VRS: Pixel Shading Rate Combiner is set to MIN, but no sampling rate " + "texture is set, this will min to 1x1"); + } + if (DAGOR_UNLIKELY(D3D12_SHADING_RATE_COMBINER_MAX == pixelShadingRateCombiner)) + { + logwarn("DX12: VRS: Pixel Shading Rate Combiner is set to MAX, but no sampling rate " + "texture is set, consider using PASSTHROUGH instead"); + } + if (DAGOR_UNLIKELY(D3D12_SHADING_RATE_COMBINER_SUM == pixelShadingRateCombiner)) + { + logwarn("DX12: VRS: Pixel Shading Rate Combiner is set to SUM, but no sampling rate " + "texture is set, this is effectively adding one to the sampling rate of the " + "previous stage"); + } } } - else + if (dirtyState.test(DirtyState::VARIABLE_RATE_SHADING_TEXTURE) && shadingTier > 1) { - if (D3D12_SHADING_RATE_COMBINER_OVERRIDE == pixelShadingRateCombiner) - { - // this is turning VRS off in a wired way - logwarn("DX12: VRS: Pixel Shading Rate Combiner is set to OVERRIDE, but no sampling rate " - "texture is set, it will override to 1x1"); - } - if (D3D12_SHADING_RATE_COMBINER_MIN == pixelShadingRateCombiner) - { - // this is turning VRS off in a wired way - logwarn("DX12: VRS: Pixel Shading Rate Combiner is set to MIN, but no sampling rate " - "texture is set, this will min to 1x1"); - } - if (D3D12_SHADING_RATE_COMBINER_MAX == pixelShadingRateCombiner) - { - logwarn("DX12: VRS: Pixel Shading Rate Combiner is set to MAX, but no sampling rate " - "texture is set, consider using PASSTHROUGH instead"); - } - if (D3D12_SHADING_RATE_COMBINER_SUM == pixelShadingRateCombiner) - { - logwarn("DX12: VRS: Pixel Shading Rate Combiner is set to SUM, but no sampling rate " - "texture is set, this is effectively adding one to the sampling rate of the " - "previous stage"); - } + ctx.setVariableRateShadingTexture(shadingRateTexture ? cast_to_texture_base(shadingRateTexture)->getDeviceImage() : nullptr); } } - if (dirtyState.test(DirtyState::VARIABLE_RATE_SHADING_TEXTURE) && (device.getVariableShadingRateTier() > 1)) - { - ctx.setVariableRateShadingTexture(shadingRateTexture ? cast_to_texture_base(shadingRateTexture)->getDeviceImage() : nullptr); - } #endif dirtyState &= unchangedMask; @@ -1323,7 +1326,7 @@ struct FrontendState OSSpinlockScopedLock resourceBindingLock(resourceBindingGuard); if (target.tRegisterTextures[index]) { - target.tRegisterTextures[index]->setSRVBinding(stage, index, false); + target.tRegisterTextures[index]->setSrvBinding(stage, index, false); target.tRegisterTextures[index] = nullptr; } target.markDirtyT(index, target.tRegisterRaytraceAccelerataionStructures[index] != as); @@ -1580,19 +1583,6 @@ struct FrontendState graphicsStaticState = state.staticRenderStateID; }; - void replaceTexture(DeviceContext &ctx, const TextureReplacer &replacer) - { - eastl::pair result; - { - OSSpinlockScopedLock resourceBindingLock(resourceBindingGuard); - result = replacer.update(); - } - if (result.first) - ctx.destroyImage(result.first); - if (result.second) - ctx.freeMemory(result.second); - } - #if !_TARGET_XBOXONE void setVariableShadingRate(D3D12_SHADING_RATE constant_rate, D3D12_SHADING_RATE_COMBINER vertex_combiner, D3D12_SHADING_RATE_COMBINER pixel_combiner) diff --git a/prog/engine/drv/drv3d_DX12/resource_memory_heap.cpp b/prog/engine/drv/drv3d_DX12/resource_memory_heap.cpp index 146a0a8ea..3f00673a1 100644 --- a/prog/engine/drv/drv3d_DX12/resource_memory_heap.cpp +++ b/prog/engine/drv/drv3d_DX12/resource_memory_heap.cpp @@ -216,7 +216,7 @@ D3D12_RESOURCE_DESC AliasHeapProvider::as_desc(const BasicTextureResourceDescrip result.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; result.MipLevels = desc.mipLevels; result.Format = format.asDxGiTextureCreateFormat(); - result.SampleDesc.Count = 1; + result.SampleDesc.Count = get_sample_count(desc.cFlags); result.SampleDesc.Quality = 0; result.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; if (TEXCF_RTARGET & desc.cFlags) @@ -5373,7 +5373,7 @@ void ResourceMemoryHeap::generateResourceAndMemoryReport(uint32_t *num_textures, out_text->aprintf(0, "%6.2f %7s q%d 2d %4dx%-4d, m%2d, aniso=%-2d filter=%7s mip=%s, %s " "- '%s'", - imageBytes.units(), imageBytes.name(), ql, tex->width, tex->height, tex->mipLevels, tex->samplerState.getAniso(), + imageBytes.units(), imageBytes.name(), ql, tex->width, tex->height, tex->level_count(), tex->samplerState.getAniso(), filter_type_to_string(tex->samplerState.getFilter()), filter_type_to_string(tex->samplerState.getMip()), img->getFormat().getNameString(), tex->getResName()); } @@ -5384,7 +5384,7 @@ void ResourceMemoryHeap::generateResourceAndMemoryReport(uint32_t *num_textures, if (out_text) { out_text->aprintf(0, "%6.2f %7s q%d cube %4d, m%2d, %s - '%s'", imageBytes.units(), imageBytes.name(), ql, tex->width, - tex->mipLevels, img->getFormat().getNameString(), tex->getResName()); + tex->level_count(), img->getFormat().getNameString(), tex->getResName()); } break; case RES3D_VOLTEX: @@ -5395,7 +5395,7 @@ void ResourceMemoryHeap::generateResourceAndMemoryReport(uint32_t *num_textures, out_text->aprintf(0, "%6.2f %7s q%d vol %4dx%-4dx%3d, m%2d, aniso=%-2d filter=%7s mip=%s, " "%s - '%s'", - imageBytes.units(), imageBytes.name(), ql, tex->width, tex->height, tex->depth, tex->mipLevels, + imageBytes.units(), imageBytes.name(), ql, tex->width, tex->height, tex->depth, tex->level_count(), tex->samplerState.getAniso(), filter_type_to_string(tex->samplerState.getFilter()), filter_type_to_string(tex->samplerState.getMip()), img->getFormat().getNameString(), tex->getResName()); } @@ -5408,7 +5408,7 @@ void ResourceMemoryHeap::generateResourceAndMemoryReport(uint32_t *num_textures, out_text->aprintf(0, "%6.2f %7s q%d arr %4dx%-4dx%3d, m%2d, aniso=%-2d filter=%7s mip=%s, " "%s - '%s'", - imageBytes.units(), imageBytes.name(), ql, tex->width, tex->height, tex->depth, tex->mipLevels, + imageBytes.units(), imageBytes.name(), ql, tex->width, tex->height, tex->depth, tex->level_count(), tex->samplerState.getAniso(), filter_type_to_string(tex->samplerState.getFilter()), filter_type_to_string(tex->samplerState.getMip()), img->getFormat().getNameString(), tex->getResName()); } diff --git a/prog/engine/drv/drv3d_DX12/shader.h b/prog/engine/drv/drv3d_DX12/shader.h index b6b30f003..988e34006 100644 --- a/prog/engine/drv/drv3d_DX12/shader.h +++ b/prog/engine/drv/drv3d_DX12/shader.h @@ -1362,6 +1362,8 @@ class InputLayoutManager InternalInputLayoutID remapInputLayout(InputLayoutID id, uint32_t layout_mask) { + G_ASSERTF(externalToInternalMap.size() > id.get(), "dx12: trying to use invalid input layout ID %u registered layouts %u", + id.get(), externalToInternalMap.size()); auto &e = externalToInternalMap[id.get()]; auto ref = eastl::find_if(begin(e.mapTable), end(e.mapTable), [layout_mask](auto &value) { return value.mask == layout_mask; }); if (end(e.mapTable) != ref) diff --git a/prog/engine/drv/drv3d_DX12/swapchain.h b/prog/engine/drv/drv3d_DX12/swapchain.h index fdbb71589..c8282e586 100644 --- a/prog/engine/drv/drv3d_DX12/swapchain.h +++ b/prog/engine/drv/drv3d_DX12/swapchain.h @@ -14,7 +14,7 @@ namespace drv3d_dx12 { -struct BaseTex; +class BaseTex; class Image; class Device; class DeviceContext; diff --git a/prog/engine/drv/drv3d_DX12/texture.cpp b/prog/engine/drv/drv3d_DX12/texture.cpp index 590bfc3db..f75e4ff94 100644 --- a/prog/engine/drv/drv3d_DX12/texture.cpp +++ b/prog/engine/drv/drv3d_DX12/texture.cpp @@ -20,88 +20,6 @@ using namespace drv3d_dx12; -namespace -{ -D3DFORMAT texfmt_to_d3dformat(uint32_t fmt) -{ - switch (fmt) - { - case TEXFMT_DEFAULT: return D3DFMT_A8R8G8B8; - case TEXFMT_A2B10G10R10: return D3DFMT_A2B10G10R10; - case TEXFMT_A16B16G16R16: return D3DFMT_A16B16G16R16; - case TEXFMT_A16B16G16R16F: return D3DFMT_A16B16G16R16F; - case TEXFMT_A32B32G32R32F: return D3DFMT_A32B32G32R32F; - case TEXFMT_G16R16: return D3DFMT_G16R16; - case TEXFMT_V16U16: return D3DFMT_V16U16; - case TEXFMT_L16: return D3DFMT_L16; - case TEXFMT_A8: return D3DFMT_A8; - case TEXFMT_R8: return D3DFMT_L8; - case TEXFMT_A8L8: return D3DFMT_A8L8; - case TEXFMT_G16R16F: return D3DFMT_G16R16F; - case TEXFMT_G32R32F: return D3DFMT_G32R32F; - case TEXFMT_R16F: return D3DFMT_R16F; - case TEXFMT_R32F: return D3DFMT_R32F; - case TEXFMT_DXT1: return D3DFMT_DXT1; - case TEXFMT_DXT3: return D3DFMT_DXT3; - case TEXFMT_DXT5: return D3DFMT_DXT5; - case TEXFMT_A4R4G4B4: return D3DFMT_A4R4G4B4; // dxgi 1.2 - case TEXFMT_A1R5G5B5: return D3DFMT_A1R5G5B5; - case TEXFMT_R5G6B5: return D3DFMT_R5G6B5; - case TEXFMT_ATI1N: return static_cast(_MAKE4C('ATI1')); - case TEXFMT_ATI2N: return static_cast(_MAKE4C('ATI2')); - } - G_ASSERTF(0, "can't convert tex format: %d", fmt); - return D3DFMT_A8R8G8B8; -} - -uint32_t auto_mip_levels_count(uint32_t w, uint32_t h, uint32_t mnsz) -{ - uint32_t lev = 1; - while (w > mnsz && h > mnsz) - { - lev++; - w >>= 1; - h >>= 1; - } - return lev; -} - -eastl::tuple fixup_tex_params(int w, int h, int32_t flg, int levels) -{ - const bool rt = (TEXCF_RTARGET & flg) != 0; - auto fmt = TEXFMT_MASK & flg; - if (TEXFMT_DEFAULT == fmt) - { - VERBOSE_DEBUG("DX12: Texture format was DEFAULT, retargeting to ARGB8888"); - fmt = TEXFMT_A8R8G8B8; // -V1048 (in case TEXFMT_DEFAULT == TEXFMT_A8R8G8B8) - } - - if (rt) - { - if (0 != (TEXCF_SRGBWRITE & flg)) - { - if ((TEXFMT_A8R8G8B8 != fmt)) - { - // TODO verify this requirement - if (0 != (TEXCF_SRGBREAD & flg)) - { - VERBOSE_DEBUG("DX12: Adding TEXCF_SRGBREAD to texture flags, because chosen format needs it"); - flg |= TEXCF_SRGBREAD; - } - } - } - } - - if (0 == levels) - { - levels = auto_mip_levels_count(w, h, rt ? 1 : 4); - VERBOSE_DEBUG("DX12: Auto compute for texture mip levels yielded %d", levels); - } - - // update format info if it had changed - return eastl::make_tuple((flg & ~TEXFMT_MASK) | fmt, levels); -} - namespace { bool needs_subresource_tracking(uint32_t cflags) @@ -110,7 +28,6 @@ bool needs_subresource_tracking(uint32_t cflags) // updated multiple times during the same frame and we need to update them during GPU timeline. return 0 != (cflags & (TEXCF_RTARGET | TEXCF_UNORDERED | TEXCF_UPDATE_DESTINATION | TEXCF_DYNAMIC)); } -} // namespace bool create_tex2d(D3DTextures &tex, BaseTex *bt_in, uint32_t w, uint32_t h, uint32_t levels, bool cube, BaseTex::ImageMem *initial_data, int array_size = 1, BaseTex *baseTexture = nullptr, bool temp_alloc = false) @@ -678,7 +595,7 @@ bool create_tex3d(D3DTextures &tex, BaseTex *bt_in, uint32_t w, uint32_t h, uint } } // namespace -ImageViewState BaseTex::getViewInfoUAV(MipMapIndex mip, ArrayLayerIndex layer, bool as_uint) const +ImageViewState BaseTex::getViewInfoUav(MipMapIndex mip, ArrayLayerIndex layer, bool as_uint) const { ImageViewState result; if (resType == RES3D_TEX) @@ -732,7 +649,7 @@ ImageViewState BaseTex::getViewInfoUAV(MipMapIndex mip, ArrayLayerIndex layer, b ImageViewState BaseTex::getViewInfoRenderTarget(MipMapIndex mip, ArrayLayerIndex layer, bool as_const) const { - FormatStore format = allowSrgbWrite() ? getFormat() : getFormat().getLinearVariant(); + FormatStore format = isSrgbWriteAllowed() ? getFormat() : getFormat().getLinearVariant(); ImageViewState result; result.isArray = resType == RES3D_ARRTEX; result.isCubemap = resType == RES3D_CUBETEX; @@ -770,7 +687,7 @@ ImageViewState BaseTex::getViewInfoRenderTarget(MipMapIndex mip, ArrayLayerIndex ImageViewState BaseTex::getViewInfo() const { ImageViewState result; - result.setFormat(allowSrgbRead() ? getFormat() : getFormat().getLinearVariant()); + result.setFormat(isSrgbReadAllowed() ? getFormat() : getFormat().getLinearVariant()); result.isArray = resType == RES3D_ARRTEX ? 1 : 0; result.isCubemap = resType == RES3D_CUBETEX ? 1 : (resType == RES3D_ARRTEX ? int(isArrayCube()) : 0); int32_t baseMip = clamp(maxMipLevel, 0, max(0, (int32_t)tex.realMipLevels - 1)); @@ -788,7 +705,7 @@ ImageViewState BaseTex::getViewInfo() const result.setMipCount(max(mipCount, 1)); result.setArrayRange(getArrayCount()); result.setSRV(); - result.sampleStencil = sampleStencil(); + result.sampleStencil = isSampleStencil(); return result; } @@ -830,6 +747,12 @@ void BaseTex::updateTexName() } } +void BaseTex::setTexName(const char *name) +{ + setResName(name); + updateTexName(); +} + void BaseTex::notifySamplerChange() { for (uint32_t s = 0; s < STAGE_MAX_EXT; ++s) @@ -841,7 +764,7 @@ void BaseTex::notifySamplerChange() } } -void BaseTex::notifySRViewChange() +void BaseTex::notifySrvChange() { for (uint32_t s = 0; s < STAGE_MAX_EXT; ++s) { @@ -865,7 +788,7 @@ void BaseTex::notifyTextureReplaceFinish() } } -void BaseTex::dirtyBoundSRVsNoLock() +void BaseTex::dirtyBoundSrvsNoLock() { for (uint32_t s = 0; s < STAGE_MAX_EXT; ++s) { @@ -876,7 +799,7 @@ void BaseTex::dirtyBoundSRVsNoLock() } } -void BaseTex::dirtyBoundUAVsNoLock() +void BaseTex::dirtyBoundUavsNoLock() { for (uint32_t s = 0; s < STAGE_MAX_EXT; ++s) { @@ -887,58 +810,38 @@ void BaseTex::dirtyBoundUAVsNoLock() } } -void BaseTex::setUAVBinding(uint32_t stage, uint32_t index, bool s) +void BaseTex::setUavBinding(uint32_t stage, uint32_t index, bool s) { uavBindingStages[stage].set(index, s); - stateBitSet.set(acitve_binding_used_offset); - if (s) - { - stateBitSet.reset(active_binding_was_copied_to_stage_offset); - } + stateBitSet.set(acitve_binding_was_used_offset); } -void BaseTex::setSRVBinding(uint32_t stage, uint32_t index, bool s) +void BaseTex::setSrvBinding(uint32_t stage, uint32_t index, bool s) { srvBindingStages[stage].set(index, s); - stateBitSet.set(acitve_binding_used_offset); + stateBitSet.set(acitve_binding_was_used_offset); } -void BaseTex::setRTVBinding(uint32_t index, bool s) +void BaseTex::setRtvBinding(uint32_t index, bool s) { G_ASSERT(index < Driver3dRenderTarget::MAX_SIMRT); stateBitSet.set(active_binding_rtv_offset + index, s); - stateBitSet.set(acitve_binding_used_offset); - if (s) - { - stateBitSet.reset(active_binding_was_copied_to_stage_offset); - stateBitSet.set(active_binding_dirty_rt); - } + stateBitSet.set(acitve_binding_was_used_offset); } -void BaseTex::setDSVBinding(bool s) +void BaseTex::setDsvBinding(bool s) { stateBitSet.set(active_binding_dsv_offset, s); - stateBitSet.set(acitve_binding_used_offset); - if (s) - { - stateBitSet.reset(active_binding_was_copied_to_stage_offset); - stateBitSet.set(active_binding_dirty_rt); - } + stateBitSet.set(acitve_binding_was_used_offset); } -eastl::bitset BaseTex::getRTVBinding() const +eastl::bitset BaseTex::getRtvBinding() const { eastl::bitset ret; ret.from_uint64((stateBitSet >> active_binding_rtv_offset).to_uint64()); return ret; } -void BaseTex::setUsedWithBindless() -{ - stateBitSet.set(active_binding_bindless_used_offset); - stateBitSet.set(acitve_binding_used_offset); -} - void BaseTex::setParams(int w, int h, int d, int levels, const char *stat_name) { G_ASSERT(levels > 0); @@ -992,8 +895,6 @@ BaseTex::BaseTex(int res_type, uint32_t cflg_) : } } -BaseTex::~BaseTex() { setRld(nullptr); } - void BaseTex::resolve(Image *dst) { get_device().getContext().resolveMultiSampleImage(tex.image, dst); } BaseTexture *BaseTex::makeTmpTexResCopy(int w, int h, int d, int l, bool staging_tex) @@ -1005,8 +906,7 @@ BaseTexture *BaseTex::makeTmpTexResCopy(int w, int h, int d, int l, bool staging if (!staging_tex) clonedTex->tidXored = tidXored, clonedTex->stubTexIdx = stubTexIdx; clonedTex->setParams(w, h, d, l, String::mk_str_cat(staging_tex ? "stg:" : "tmp:", getTexName())); - clonedTex->setPreallocBeforeLoad(true); - clonedTex->setDelayedCreate(true); + clonedTex->setIsPreallocBeforeLoad(true); if (!clonedTex->allocateTex()) del_d3dres(clonedTex); return clonedTex; @@ -1031,7 +931,9 @@ void BaseTex::replaceTexResObject(BaseTexture *&other_tex) eastl::swap(minMipLevel, other->minMipLevel); eastl::swap(maxMipLevel, other->maxMipLevel); +#if DAGOR_DBGLEVEL > 0 other->setWasUsed(); +#endif } del_d3dres(other_tex); } @@ -1118,13 +1020,12 @@ bool BaseTex::recreate() return create_tex2d(tex, this, width, height, mipLevels, false, NULL, 1); } - if (!preallocBeforeLoad()) + if (!isPreallocBeforeLoad()) { VERBOSE_DEBUG("<%s> recreate %dx%d (%s)", getResName(), width, height, "empty"); return create_tex2d(tex, this, width, height, mipLevels, false, NULL, 1); } - setDelayedCreate(preallocBeforeLoad()); VERBOSE_DEBUG("<%s> recreate %dx%d (%s)", getResName(), 4, 4, "placeholder"); if (stubTexIdx >= 0) { @@ -1144,13 +1045,12 @@ bool BaseTex::recreate() return create_tex2d(tex, this, width, height, mipLevels, true, NULL, 1); } - if (!preallocBeforeLoad()) + if (!isPreallocBeforeLoad()) { VERBOSE_DEBUG("<%s> recreate %dx%d (%s)", getResName(), width, height, "empty"); return create_tex2d(tex, this, width, height, mipLevels, true, NULL, 1); } - setDelayedCreate(preallocBeforeLoad()); VERBOSE_DEBUG("<%s> recreate %dx%d (%s)", getResName(), 4, 4, "placeholder"); if (stubTexIdx >= 0) { @@ -1170,13 +1070,12 @@ bool BaseTex::recreate() return create_tex3d(tex, this, width, height, depth, cflg, mipLevels, NULL); } - if (!preallocBeforeLoad()) + if (!isPreallocBeforeLoad()) { VERBOSE_DEBUG("<%s> recreate %dx%dx%d (%s)", getResName(), width, height, depth, "empty"); return create_tex3d(tex, this, width, height, depth, cflg, mipLevels, NULL); } - setDelayedCreate(preallocBeforeLoad()); VERBOSE_DEBUG("<%s> recreate %dx%d (%s)", getResName(), 4, 4, "placeholder"); if (stubTexIdx >= 0) { @@ -1499,12 +1398,10 @@ int BaseTex::generateMips() bool BaseTex::setReloadCallback(IReloadData *_rld) { - setRld(_rld); + rld.reset(_rld); return true; } -static constexpr int TEX_COPIED = 1 << 30; - void D3DTextures::release(uint64_t progress) { auto &device = get_device(); @@ -1541,7 +1438,7 @@ void BaseTex::resetTex() void BaseTex::releaseTex() { STORE_RETURN_ADDRESS(); - notify_delete(this, srvBindingStages, uavBindingStages, getRTVBinding(), getDSVBinding()); + notify_delete(this, srvBindingStages, uavBindingStages, getRtvBinding(), getDsvBinding()); sampler.ptr = 0; if (isStub()) tex.image = nullptr; @@ -1552,23 +1449,17 @@ void BaseTex::releaseTex() } #if _TARGET_XBOX -#if _TARGET_XBOXONE // wrapper, which wraps call to XGTextureAddressComputer::GetTexelElementOffsetBytes as on scarlett // it has one extra parameter that returns the bit offset uint64_t get_texel_element_offset_bytes(XGTextureAddressComputer *computer, uint32_t plane, uint32_t mip_level, uint64_t x, uint32_t y, uint32_t z_or_slice, uint32_t sample) { +#if _TARGET_XBOXONE return computer->GetTexelElementOffsetBytes(plane, mip_level, x, y, z_or_slice, sample); -} #else -// wrapper, which wraps call to XGTextureAddressComputer::GetTexelElementOffsetBytes as on scarlett -// it has one extra parameter that returns the bit offset -uint64_t get_texel_element_offset_bytes(XGTextureAddressComputer *computer, uint32_t plane, uint32_t mip_level, uint64_t x, uint32_t y, - uint32_t z_or_slice, uint32_t sample) -{ return computer->GetTexelElementOffsetBytes(plane, mip_level, x, y, z_or_slice, sample, nullptr); -} #endif +} #endif int BaseTex::lockimg(void **p, int &stride, int lev, unsigned flags) @@ -1660,34 +1551,22 @@ int BaseTex::lockimg(void **p, int &stride, int lev, unsigned flags) if (tex.stagingMemory) { - BufferImageCopy copies[MAX_MIPMAPS]; - uint64_t offset = 0; - - // TODO why copy all mips? - for (uint32_t j = 0; j < mipLevels; ++j) - { - BufferImageCopy © = copies[j]; - copy.subresourceIndex = calculate_subresource_index(j, 0, 0, mipLevels, 1); - auto subResInfo = calculate_texture_mip_info(*tex.image, MipMapIndex::make(j)); - copy.layout.Footprint = subResInfo.footprint; - copy.layout.Offset = offset; - G_ASSERT(copy.layout.Offset % D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT == 0); - copy.imageOffset.x = 0; - copy.imageOffset.y = 0; - copy.imageOffset.z = 0; - if (j == lev) - { - lockMsr.slicePitch = copy.layout.Footprint.RowPitch * subResInfo.rowCount; - lockMsr.memSize = copy.layout.Footprint.RowPitch * subResInfo.rowCount; - lockMsr.ptr = &tex.stagingMemory.pointer[offset]; - lockMsr.rowPitch = copy.layout.Footprint.RowPitch; - } - offset += subResInfo.rowCount * copy.layout.Footprint.RowPitch; - offset = (offset + D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1) & ~(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1); - } + auto copies = calculate_texture_mips_copy_info(*tex.image, mipLevels); + const auto © = copies[lev]; + auto subResInfo = calculate_texture_mip_info(*tex.image, MipMapIndex::make(lev)); + lockMsr.slicePitch = copy.layout.Footprint.RowPitch * subResInfo.rowCount; + lockMsr.memSize = copy.layout.Footprint.RowPitch * subResInfo.rowCount; + lockMsr.ptr = &tex.stagingMemory.pointer[copy.layout.Offset]; + lockMsr.rowPitch = copy.layout.Footprint.RowPitch; + + // - It is required to copy full resource in case of TEXLOCK_COPY_STAGING + // (because with TEXLOCK_COPY_STAGING we will upload full resource later) + // - It is also required with lockimg(nullptr, ...) + // (in this case we mark resource with TEX_COPIED flag and we can rely on these copies) + // - Otherwise -- we can copy only locked mip if (flags & TEXLOCK_COPY_STAGING) { - ctx.waitForProgress(ctx.readBackFromImage(tex.stagingMemory, copies, mipLevels, tex.image, readBackQueue)); + ctx.waitForProgress(ctx.readBackFromImage(tex.stagingMemory, copies.data(), mipLevels, tex.image, readBackQueue)); tex.stagingMemory.invalidate(); lockFlags = TEXLOCK_COPY_STAGING; return 1; @@ -1700,11 +1579,11 @@ int BaseTex::lockimg(void **p, int &stride, int lev, unsigned flags) device.getContext().waitForProgress(waitProgress); waitProgress = 0; } - waitProgress = ctx.readBackFromImage(tex.stagingMemory, copies, mipLevels, tex.image, readBackQueue); + waitProgress = ctx.readBackFromImage(tex.stagingMemory, copies.data(), mipLevels, tex.image, readBackQueue); } else if (!resourceCopied) { - ctx.waitForProgress(ctx.readBackFromImage(tex.stagingMemory, copies, mipLevels, tex.image, readBackQueue)); + ctx.waitForProgress(ctx.readBackFromImage(tex.stagingMemory, ©, 1, tex.image, readBackQueue)); tex.stagingMemory.invalidate(); *p = lockMsr.ptr; @@ -1867,58 +1746,38 @@ int BaseTex::unlockimg() VERBOSE_DEBUG("%s %dx%d updated DDSx for TEXCF_SYSTEXCOPY", getResName(), hdr->w, hdr->h, data_size(texCopy)); } - if (tex.stagingMemory) + if (tex.stagingMemory && tex.image) { - if (tex.image) + if (lockFlags & TEXLOCK_DISCARD) { - if (lockFlags & TEXLOCK_DISCARD) - { - BufferImageCopy copy{}; - - copy.subresourceIndex = lockedSubRes; - auto subResInfo = calculate_texture_subresource_info(*tex.image, SubresourceIndex::make(lockedSubRes)); - copy.layout.Footprint = subResInfo.footprint; - copy.layout.Offset = 0; - copy.imageOffset.x = 0; - copy.imageOffset.y = 0; - copy.imageOffset.z = 0; - tex.stagingMemory.flush(); - // Allow upload happen on the upload queue as a discard upload. If the driver can not safely - // execute the upload on the upload queue, it will move it to the graphics queue. - ctx.uploadToImage(tex.image, ©, 1, tex.stagingMemory, DeviceQueueType::UPLOAD, true); - - ctx.freeMemory(tex.stagingMemory); - tex.stagingMemory = HostDeviceSharedMemoryRegion{}; - } - else if ((lockFlags & (TEXLOCK_RWMASK | TEXLOCK_UPDATEFROMSYSTEX)) != 0 && !(lockFlags & TEXLOCK_DONOTUPDATEON9EXBYDEFAULT) && - !(cflg & TEXCF_RTARGET)) - { - // TODO: copy only locked level? (check VK too) - BufferImageCopy copies[MAX_MIPMAPS]; - uint64_t offset = 0; + // Allow upload happen on the upload queue as a discard upload. If the driver can not safely + // execute the upload on the upload queue, it will move it to the graphics queue. + tex.stagingMemory.flush(); + auto copy = calculate_texture_subresource_copy_info(*tex.image, lockedSubRes); + ctx.uploadToImage(tex.image, ©, 1, tex.stagingMemory, DeviceQueueType::UPLOAD, true); - for (uint32_t j = 0; j < mipLevels; ++j) - { - BufferImageCopy © = copies[j]; - copy.subresourceIndex = calculate_subresource_index(j, 0, 0, mipLevels, 1); - auto subResInfo = calculate_texture_mip_info(*tex.image, MipMapIndex::make(j)); - copy.layout.Footprint = subResInfo.footprint; - copy.layout.Offset = offset; - G_ASSERT(copy.layout.Offset % D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT == 0); - copy.imageOffset.x = 0; - copy.imageOffset.y = 0; - copy.imageOffset.z = 0; - offset += subResInfo.rowCount * copy.layout.Footprint.RowPitch; - offset = (offset + D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1) & ~(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1); - } - tex.stagingMemory.flush(); - ctx.uploadToImage(tex.image, copies, mipLevels, tex.stagingMemory, DeviceQueueType::UPLOAD, false); - } + ctx.freeMemory(tex.stagingMemory); + tex.stagingMemory = HostDeviceSharedMemoryRegion{}; + } + else if ((lockFlags & TEXLOCK_DONOTUPDATEON9EXBYDEFAULT) != 0) + stateBitSet.set(unlock_image_is_upload_skipped, true); + else if ((lockFlags & (TEXLOCK_RWMASK | TEXLOCK_UPDATEFROMSYSTEX)) != 0 && !(cflg & TEXCF_RTARGET)) + { + // Sometimes we use TEXLOCK_DONOTUPDATEON9EXBYDEFAULT flag and don't copy locked subresource on unlock. + // Copy all mips is required after that action. + tex.stagingMemory.flush(); + auto copies = calculate_texture_mips_copy_info(*tex.image, mipLevels); + const eastl::span fullResource{copies}; + const eastl::span oneSubresource{&copies[calculate_mip_slice_from_index(lockedSubRes, mipLevels)], 1}; + const auto uploadRegions = stateBitSet.test(unlock_image_is_upload_skipped) ? fullResource : oneSubresource; + ctx.uploadToImage(tex.image, uploadRegions.data(), uploadRegions.size(), tex.stagingMemory, DeviceQueueType::UPLOAD, false); + stateBitSet.set(unlock_image_is_upload_skipped, false); } } if (tex.stagingMemory && (lockFlags & TEXLOCK_DELSYSMEMCOPY) && !(cflg & TEXCF_DYNAMIC)) { + G_ASSERT(!stateBitSet.test(unlock_image_is_upload_skipped)); ctx.freeMemory(tex.stagingMemory); tex.stagingMemory = HostDeviceSharedMemoryRegion{}; } @@ -2259,7 +2118,7 @@ int BaseTex::getinfo(TextureInfo &ti, int level) const ti.a = getArrayCount().count(); break; case RES3D_VOLTEX: - ti.d = max(1u, getDepthSlices() >> level); + ti.d = max(1u, depth >> level); ti.a = 1; break; default: @@ -2341,7 +2200,7 @@ int BaseTex::texmiplevel(int minlevel, int maxlevel) { maxMipLevel = (minlevel >= 0) ? minlevel : 0; minMipLevel = (maxlevel >= 0) ? maxlevel : (mipLevels - 1); - notifySRViewChange(); + notifySrvChange(); return 1; } @@ -2371,7 +2230,7 @@ static Texture *create_tex_internal(TexImage32 *img, int w, int h, int flg, int w = clamp(w, dd.mintexw, dd.maxtexw); h = clamp(h, dd.mintexh, dd.maxtexh); - eastl::tie(flg, levels) = fixup_tex_params(w, h, flg, levels); + eastl::tie(flg, levels) = add_srgb_read_flag_and_count_mips(w, h, flg, levels); if (img) { @@ -2489,7 +2348,7 @@ static CubeTexture *create_cubetex_internal(int size, int flg, int levels, const const Driver3dDesc &dd = d3d::get_driver_desc(); size = get_bigger_pow2(clamp(size, dd.mincubesize, dd.maxcubesize)); - eastl::tie(flg, levels) = fixup_tex_params(size, size, flg, levels); + eastl::tie(flg, levels) = add_srgb_read_flag_and_count_mips(size, size, flg, levels); auto tex = get_device().newTextureObject(RES3D_CUBETEX, flg); tex->setParams(size, size, 1, levels, stat_name); @@ -2521,7 +2380,7 @@ static VolTexture *create_voltex_internal(int w, int h, int d, int flg, int leve return nullptr; } - eastl::tie(flg, levels) = fixup_tex_params(w, h, flg, levels); + eastl::tie(flg, levels) = add_srgb_read_flag_and_count_mips(w, h, flg, levels); auto tex = get_device().newTextureObject(RES3D_VOLTEX, flg); tex->setParams(w, h, d, levels, stat_name); @@ -2574,7 +2433,7 @@ static ArrayTexture *create_array_tex_internal(int w, int h, int d, int flg, int { G_ASSERT_RETURN(d3d::check_texformat(flg), nullptr); - eastl::tie(flg, levels) = fixup_tex_params(w, h, flg, levels); + eastl::tie(flg, levels) = add_srgb_read_flag_and_count_mips(w, h, flg, levels); auto tex = get_device().newTextureObject(RES3D_ARRTEX, flg); tex->setParams(w, h, d, levels, stat_name); @@ -2601,7 +2460,7 @@ static ArrayTexture *create_cube_array_tex_internal(int side, int d, int flg, in { G_ASSERT_RETURN(d3d::check_cubetexformat(flg), nullptr); - eastl::tie(flg, levels) = fixup_tex_params(side, side, flg, levels); + eastl::tie(flg, levels) = add_srgb_read_flag_and_count_mips(side, side, flg, levels); auto tex = get_device().newTextureObject(RES3D_ARRTEX, flg); tex->setParams(side, side, d, levels, stat_name); @@ -2716,8 +2575,7 @@ BaseTexture *d3d::alloc_ddsx_tex(const ddsx::Header &hdr, int flg, int q_id, int bt->setParams(w, h, d, levels, stat_name); bt->stubTexIdx = stub_tex_idx; - bt->setPreallocBeforeLoad(true); - bt->setDelayedCreate(true); + bt->setIsPreallocBeforeLoad(true); if (stub_tex_idx >= 0) { @@ -2757,36 +2615,6 @@ bool d3d::set_tex_usage_hint(int, int, int, const char *, unsigned int) return true; } -eastl::pair TextureReplacer::update() const -{ - Image *resultImage = nullptr; - HostDeviceSharedMemoryRegion resultMemory{}; - // ->> releaseTex - // rep.target->releaseTex(); - if (target->isStub()) - target->tex.image = nullptr; - else if (target->tex.image) - TEXQL_ON_RELEASE(target); - if (target->tex.stagingMemory) - { - resultMemory = target->tex.stagingMemory; - target->tex.stagingMemory = HostDeviceSharedMemoryRegion{}; - } - - if (target->tex.image) - { - resultImage = target->tex.image; - target->tex.image = nullptr; - } - // <<- releaseTex - target->tex = newTex; - target->updateTexName(); - // ensures that used textures are rebound on next flush - target->notifyTextureReplaceFinish(); - - return {resultImage, resultMemory}; -} - Texture *d3d::alias_tex(Texture *baseTexture, TexImage32 *img, int w, int h, int flg, int levels, const char *stat_name) { diff --git a/prog/engine/drv/drv3d_DX12/texture.h b/prog/engine/drv/drv3d_DX12/texture.h index 1fdf93513..06312aa72 100644 --- a/prog/engine/drv/drv3d_DX12/texture.h +++ b/prog/engine/drv/drv3d_DX12/texture.h @@ -13,35 +13,20 @@ #include "image_view_state.h" #include "sampler_state.h" - -namespace ddsx -{ -struct Header; -} - namespace drv3d_dx12 { -struct BaseTex; +class BaseTex; class Image; struct D3DTextures { Image *image = nullptr; HostDeviceSharedMemoryRegion stagingMemory; - D3D12_RESOURCE_FLAGS usage = D3D12_RESOURCE_FLAG_NONE; uint32_t memSize = 0; uint32_t realMipLevels = 0; void release(uint64_t progress); }; -struct TextureReplacer -{ - BaseTex *target; - D3DTextures newTex; - - eastl::pair update() const; -}; -void execute_texture_replace(const TextureReplacer &replacer); void notify_delete(BaseTex *texture, const eastl::bitset *srvs, const eastl::bitset *uavs, eastl::bitset rtvs, bool dsv); void dirty_srv_no_lock(BaseTex *texture, uint32_t stage, eastl::bitset slots); @@ -54,33 +39,18 @@ void dirty_rendertarget_no_lock(BaseTex *texture, eastl::bitsetdestroySelf(); - } - }; - - typedef eastl::unique_ptr ReloadDataPointer; - - SamplerState samplerState; - SamplerState lastSamplerState; //-V730_NOINIT - D3D12_CPU_DESCRIPTOR_HANDLE sampler{0}; - uint8_t mipLevels = 0; - uint8_t minMipLevel = 0; - uint8_t maxMipLevel = 0; - static constexpr uint32_t active_binding_rtv_offset = 0; - static constexpr uint32_t active_binding_dsv_offset = Driver3dRenderTarget::MAX_SIMRT + active_binding_rtv_offset; - static constexpr uint32_t acitve_binding_used_offset = 1 + active_binding_dsv_offset; - static constexpr uint32_t active_binding_delayed_create_offset = 1 + acitve_binding_used_offset; - static constexpr uint32_t active_binding_prealloc_before_load_offset = 1 + active_binding_delayed_create_offset; - static constexpr uint32_t active_binding_sample_stencil = 1 + active_binding_prealloc_before_load_offset; - static constexpr uint32_t active_binding_is_array_cube_offset = 1 + active_binding_sample_stencil; - static constexpr uint32_t active_binding_was_copied_to_stage_offset = 1 + active_binding_is_array_cube_offset; - static constexpr uint32_t active_binding_dirty_rt = 1 + active_binding_was_copied_to_stage_offset; - static constexpr uint32_t active_binding_bindless_used_offset = 1 + active_binding_dirty_rt; - static constexpr uint32_t active_binding_state_count = 1 + active_binding_bindless_used_offset; - eastl::bitset srvBindingStages[STAGE_MAX_EXT]; - eastl::bitset uavBindingStages[STAGE_MAX_EXT]; - eastl::bitset stateBitSet; void notifySamplerChange(); - void notifySRViewChange(); + void notifySrvChange(); void notifyTextureReplaceFinish(); - void dirtyBoundSRVsNoLock(); - void dirtyBoundUAVsNoLock(); - void dirtyBoundRTVsNoLock() { dirty_rendertarget_no_lock(this, getRTVBinding()); } - void setUAVBinding(uint32_t stage, uint32_t index, bool s); - void setSRVBinding(uint32_t stage, uint32_t index, bool s); - void setRTVBinding(uint32_t index, bool s); - void setDSVBinding(bool s); - eastl::bitset getUAVBinding(uint32_t stage) const { return uavBindingStages[stage]; } - eastl::bitset getSRVBinding(uint32_t stage) const { return srvBindingStages[stage]; } - eastl::bitset getRTVBinding() const; - bool getDSVBinding() const { return stateBitSet.test(active_binding_dsv_offset); } - bool wasUsed() const { return stateBitSet.test(acitve_binding_used_offset); } - void setWasUsed() { stateBitSet.set(acitve_binding_used_offset); } - bool delayedCreate() const { return stateBitSet.test(active_binding_delayed_create_offset); } - void setDelayedCreate(bool s) { stateBitSet.set(active_binding_delayed_create_offset, s); } - bool preallocBeforeLoad() const { return stateBitSet.test(active_binding_prealloc_before_load_offset); } - void setPreallocBeforeLoad(bool s) { stateBitSet.set(active_binding_prealloc_before_load_offset, s); } - bool sampleStencil() const { return stateBitSet.test(active_binding_sample_stencil); } - void setSampleStencil(bool s) { stateBitSet.set(active_binding_sample_stencil, s); } + void dirtyBoundSrvsNoLock(); + void dirtyBoundUavsNoLock(); + void dirtyBoundRtvsNoLock() { dirty_rendertarget_no_lock(this, getRtvBinding()); } + + void setUavBinding(uint32_t stage, uint32_t index, bool s); + void setSrvBinding(uint32_t stage, uint32_t index, bool s); + void setRtvBinding(uint32_t index, bool s); + void setDsvBinding(bool s); + eastl::bitset getRtvBinding() const; + bool getDsvBinding() const { return stateBitSet.test(active_binding_dsv_offset); } +#if DAGOR_DBGLEVEL > 0 + bool wasUsed() const { return stateBitSet.test(acitve_binding_was_used_offset); } + void setWasUsed() { stateBitSet.set(acitve_binding_was_used_offset); } +#endif + bool isPreallocBeforeLoad() const { return stateBitSet.test(active_binding_is_prealloc_before_load_offset); } + void setIsPreallocBeforeLoad(bool s) { stateBitSet.set(active_binding_is_prealloc_before_load_offset, s); } + bool isSampleStencil() const { return stateBitSet.test(active_binding_is_sample_stencil); } + void setIsSampleStencil(bool s) { stateBitSet.set(active_binding_is_sample_stencil, s); } bool isArrayCube() const { return stateBitSet.test(active_binding_is_array_cube_offset); } void setIsArrayCube(bool s) { stateBitSet.set(active_binding_is_array_cube_offset, s); } - bool wasCopiedToStage() const { return stateBitSet.test(active_binding_was_copied_to_stage_offset); } - void setWasCopiedToStage(bool s) { stateBitSet.set(active_binding_was_copied_to_stage_offset, s); } - bool dirtyRt() const { return stateBitSet.test(active_binding_dirty_rt); } - void setDirtyRty(bool s) { stateBitSet.set(active_binding_dirty_rt, s); } - void setUsedWithBindless(); - bool wasUsedWithBindless() const { return stateBitSet.test(active_binding_bindless_used_offset); } - - uint16_t width = 0; - uint16_t height = 0; - uint16_t depth = 0; - // uint16_t layers = 0; - - uint32_t lockedSubRes = 0; - - SmallTab texCopy; //< ddsx::Header + ddsx data; sysCopyQualityId stored in hdr.hqPartLevel - ReloadDataPointer rld; - - struct ImageMem - { - void *ptr = nullptr; - uint32_t rowPitch = 0; - uint32_t slicePitch = 0; - uint32_t memSize = 0; - }; - - ImageMem lockMsr; DECLARE_TQL_TID_AND_STUB() @@ -179,18 +89,10 @@ struct BaseTex final : public BaseTexture ArrayLayerCount getArrayCount() const; - uint32_t getDepthSlices() const - { - if (resType == RES3D_VOLTEX) - return depth; - return 1; - } - BaseTex(int res_type, uint32_t cflg_); - ~BaseTex() override; /// ->> - void setReadStencil(bool on) override { setSampleStencil(on && getFormat().isStencil()); } + void setReadStencil(bool on) override { setIsSampleStencil(on && getFormat().isStencil()); } int restype() const override { return resType; } int ressize() const override; int getinfo(TextureInfo &ti, int level = 0) const override; @@ -213,7 +115,8 @@ struct BaseTex final : public BaseTexture bool setReloadCallback(IReloadData *_rld) override; void resetTex(); - void releaseTex(); + + void updateTexName(); int lockimg(void **, int &stride_bytes, int level = 0, unsigned flags = TEXLOCK_DEFAULT) override; int lockimg(void **, int &stride_bytes, int face, int level = 0, unsigned flags = TEXLOCK_DEFAULT) override; @@ -225,26 +128,12 @@ struct BaseTex final : public BaseTexture int unlockbox() override; void destroy() override; - void setRld(BaseTexture::IReloadData *_rld) { rld.reset(_rld); } - - void release() { releaseTex(); } bool recreate(); - void destroyObject(); - - void updateTexName(); - - void setTexName(const char *name) - { - setResName(name); - updateTexName(); - } - bool allocateTex() override; void discardTex() override; - bool isTexResEqual(BaseTexture *bt) const { return bt && ((BaseTex *)bt)->tex.image == tex.image; } - bool isCubeArray() const { return isArrayCube(); } + bool isCubeArray() const override { return isArrayCube(); } BaseTexture *makeTmpTexResCopy(int w, int h, int d, int l, bool staging_tex) override; void replaceTexResObject(BaseTexture *&other_tex) override; @@ -254,14 +143,87 @@ struct BaseTex final : public BaseTexture static uint32_t update_flags_for_linear_layout(uint32_t cflags, FormatStore format); static DeviceMemoryClass get_memory_class(uint32_t cflags); -}; -static inline BaseTex *getbasetex(BaseTexture *t) { return t ? (BaseTex *)t : nullptr; } + D3DTextures tex; + FormatStore fmt; + uint32_t cflg = 0; + int resType = 0; + + uint16_t width = 0; + uint16_t height = 0; + uint16_t depth = 0; -static inline const BaseTex *getbasetex(const BaseTexture *t) { return t ? (const BaseTex *)t : nullptr; } + SmallTab texCopy; //< ddsx::Header + ddsx data; sysCopyQualityId stored in hdr.hqPartLevel -inline BaseTex *cast_to_texture_base(BaseTexture *t) { return getbasetex(t); } + struct ReloadDataHandler + { + void operator()(IReloadData *rd) + { + if (rd) + rd->destroySelf(); + } + }; + + eastl::unique_ptr rld; + + SamplerState samplerState; + + struct ImageMem + { + void *ptr = nullptr; + uint32_t rowPitch = 0; + uint32_t slicePitch = 0; + uint32_t memSize = 0; + }; + +private: + bool isSrgbWriteAllowed() const { return (cflg & TEXCF_SRGBWRITE) != 0; } + bool isSrgbReadAllowed() const { return (cflg & TEXCF_SRGBREAD) != 0; } + void resolve(Image *dst); + + void releaseTex(); + void destroyObject(); + void release() { releaseTex(); } + + void setTexName(const char *name); + + bool isTexResEqual(BaseTexture *bt) const { return bt && ((BaseTex *)bt)->tex.image == tex.image; } + + static constexpr float default_lodbias = 0.f; + static constexpr int default_aniso = 1; + + static constexpr uint32_t active_binding_rtv_offset = 0; + static constexpr uint32_t active_binding_dsv_offset = Driver3dRenderTarget::MAX_SIMRT + active_binding_rtv_offset; + static constexpr uint32_t acitve_binding_was_used_offset = 1 + active_binding_dsv_offset; + static constexpr uint32_t active_binding_is_prealloc_before_load_offset = 1 + acitve_binding_was_used_offset; + static constexpr uint32_t active_binding_is_sample_stencil = 1 + active_binding_is_prealloc_before_load_offset; + static constexpr uint32_t active_binding_is_array_cube_offset = 1 + active_binding_is_sample_stencil; + static constexpr uint32_t unlock_image_is_upload_skipped = active_binding_is_array_cube_offset + 1; + static constexpr uint32_t texture_state_bits_count = unlock_image_is_upload_skipped + 1; + eastl::bitset srvBindingStages[STAGE_MAX_EXT]; + eastl::bitset uavBindingStages[STAGE_MAX_EXT]; + eastl::bitset stateBitSet; + + uint32_t lockFlags = 0; + uint64_t waitProgress = 0; + + uint32_t lockedSubRes = 0; + + SamplerState lastSamplerState; //-V730_NOINIT + + ImageMem lockMsr; + + D3D12_CPU_DESCRIPTOR_HANDLE sampler{0}; + uint8_t mipLevels = 0; + uint8_t minMipLevel = 0; + uint8_t maxMipLevel = 0; +}; + +static inline BaseTex *getbasetex(BaseTexture *t) { return static_cast(t); } +static inline const BaseTex *getbasetex(const BaseTexture *t) { return static_cast(t); } + +inline BaseTex *cast_to_texture_base(BaseTexture *t) { return getbasetex(t); } inline BaseTex &cast_to_texture_base(BaseTexture &t) { return *getbasetex(&t); } typedef BaseTex TextureInterfaceBase; diff --git a/prog/engine/drv/drv3d_Metal/d3d_rtarget.mm b/prog/engine/drv/drv3d_Metal/d3d_rtarget.mm index 607b90515..a95c036fc 100644 --- a/prog/engine/drv/drv3d_Metal/d3d_rtarget.mm +++ b/prog/engine/drv/drv3d_Metal/d3d_rtarget.mm @@ -174,7 +174,17 @@ bool setRtState(TrackDriver3dRenderTarget &oldrt, TrackDriver3dRenderTarget &rt) drv3d_metal::Texture* ri = nullptr; for (uint32_t i = 0; i < 8; ++i) if (rt.color[i].tex) + { +#if DAGOR_DBGLEVEL > 0 + drv3d_metal::Texture *curRt = (drv3d_metal::Texture*)rt.color[i].tex; + if (ri && (ri->getWidth() != curRt->getWidth() || + ri->getHeight() != curRt->getHeight())) + G_ASSERT_FAIL("Bound RT dimensions don't match %s:%dx%d %s:%dx%d ", + ri->getResName(), ri->getWidth(), ri->getHeight(), + curRt->getResName(), curRt->getWidth(), curRt->getHeight()); +#endif ri = (drv3d_metal::Texture*)rt.color[i].tex; + } for (int i = 0; i < tmp_depth.size() && ri; i++) { diff --git a/prog/engine/drv/drv3d_Metal/d3d_states.mm b/prog/engine/drv/drv3d_Metal/d3d_states.mm index f4f1b6a4a..4e366428e 100644 --- a/prog/engine/drv/drv3d_Metal/d3d_states.mm +++ b/prog/engine/drv/drv3d_Metal/d3d_states.mm @@ -360,14 +360,6 @@ static int sizeofAccelerationStruct() #endif //return drv3d_vulkan::api_state.device.getDeviceVendor(); break; - case DRV3D_COMMAND_GET_RESOLUTION: - /*if (par1 && par2) - { - *((int *)par1) = api_state.windowState.settings.resolutionX; - *((int *)par2) = api_state.windowState.settings.resolutionY; - return 1; - }*/ - break; case DRV3D_COMMAND_START_CAPTURE_FRAME: { render.start_capture = true; diff --git a/prog/engine/drv/drv3d_commonCode/basetexture.cpp b/prog/engine/drv/drv3d_commonCode/basetexture.cpp index 8dfdc6ac3..87523e7d0 100644 --- a/prog/engine/drv/drv3d_commonCode/basetexture.cpp +++ b/prog/engine/drv/drv3d_commonCode/basetexture.cpp @@ -66,3 +66,40 @@ int BaseTextureImpl::getinfo(TextureInfo &ti, int level) const ti.cflg = cflg; return 1; } + +uint32_t auto_mip_levels_count(uint32_t w, uint32_t h, uint32_t min_size) +{ + uint32_t lev = 1; + uint32_t minExtend = min(w, h); + while (minExtend > min_size) + { + lev++; + minExtend >>= 1; + } + return lev; +} + +eastl::pair add_srgb_read_flag_and_count_mips(int w, int h, int32_t flg, int levels) +{ + const bool rt = (TEXCF_RTARGET & flg) != 0; + auto fmt = TEXFMT_MASK & flg; + + if (rt && (0 != (TEXCF_SRGBWRITE & flg)) && (TEXFMT_A8R8G8B8 != fmt)) + { + // TODO verify this requirement (RE-508) + if (0 != (TEXCF_SRGBREAD & flg)) + { + debug("Adding TEXCF_SRGBREAD to texture flags, because chosen format needs it"); + flg |= TEXCF_SRGBREAD; + } + } + + if (0 == levels) + { + levels = auto_mip_levels_count(w, h, rt ? 1 : 4); + debug("Auto compute for texture mip levels yielded %d", levels); + } + + // update format info if it had changed + return {(flg & ~TEXFMT_MASK) | fmt, levels}; +} diff --git a/prog/engine/drv/drv3d_commonCode/basetexture.h b/prog/engine/drv/drv3d_commonCode/basetexture.h index 397485386..fd8a00cd2 100644 --- a/prog/engine/drv/drv3d_commonCode/basetexture.h +++ b/prog/engine/drv/drv3d_commonCode/basetexture.h @@ -1,4 +1,5 @@ #include <3d/dag_drv3d.h> +#include #include @@ -71,6 +72,9 @@ class BaseTextureImpl : public BaseTexture #endif }; +eastl::pair add_srgb_read_flag_and_count_mips(int w, int h, int32_t flg, int levels); + // common helpers to convert DDSx format to TEXFMT_ one uint32_t d3dformat_to_texfmt(/*D3DFORMAT*/ uint32_t fmt); +uint32_t texfmt_to_d3dformat(/*D3DFORMAT*/ uint32_t fmt); static inline uint32_t implant_d3dformat(uint32_t cflg, uint32_t fmt) { return (cflg & ~TEXFMT_MASK) | d3dformat_to_texfmt(fmt); } diff --git a/prog/engine/drv/drv3d_commonCode/d3dToTexFmt.cpp b/prog/engine/drv/drv3d_commonCode/d3dToTexFmt.cpp index 193448b79..4882ec8f9 100644 --- a/prog/engine/drv/drv3d_commonCode/d3dToTexFmt.cpp +++ b/prog/engine/drv/drv3d_commonCode/d3dToTexFmt.cpp @@ -61,3 +61,38 @@ uint32_t d3dformat_to_texfmt(/*D3DFORMAT*/ uint32_t fmt) G_ASSERTF(0, "can't convert d3d format"); return TEXFMT_A8R8G8B8; // TEXFMT_DEFAULT; } + +uint32_t texfmt_to_d3dformat(/*D3DFORMAT*/ uint32_t fmt) +{ + switch (fmt) + { + case TEXFMT_A8R8G8B8: return D3DFMT_A8R8G8B8; + case TEXFMT_R8G8B8A8: return D3DFMT_A8B8G8R8; + case TEXFMT_A2B10G10R10: return D3DFMT_A2B10G10R10; + case TEXFMT_A16B16G16R16: return D3DFMT_A16B16G16R16; + case TEXFMT_A16B16G16R16F: return D3DFMT_A16B16G16R16F; + case TEXFMT_A32B32G32R32F: return D3DFMT_A32B32G32R32F; + case TEXFMT_G16R16: return D3DFMT_G16R16; + case TEXFMT_V16U16: return D3DFMT_V16U16; + case TEXFMT_L16: return D3DFMT_L16; + case TEXFMT_A8: return D3DFMT_A8; + case TEXFMT_R8: return D3DFMT_L8; + case TEXFMT_A8L8: return D3DFMT_A8L8; + case TEXFMT_G16R16F: return D3DFMT_G16R16F; + case TEXFMT_G32R32F: return D3DFMT_G32R32F; + case TEXFMT_R16F: return D3DFMT_R16F; + case TEXFMT_R32F: return D3DFMT_R32F; + case TEXFMT_DXT1: return D3DFMT_DXT1; + case TEXFMT_DXT3: return D3DFMT_DXT3; + case TEXFMT_DXT5: return D3DFMT_DXT5; + case TEXFMT_A4R4G4B4: return D3DFMT_A4R4G4B4; // dxgi 1.2 + case TEXFMT_A1R5G5B5: return D3DFMT_A1R5G5B5; + case TEXFMT_R5G6B5: return D3DFMT_R5G6B5; + case TEXFMT_ATI1N: return _MAKE4C('ATI1'); + case TEXFMT_ATI2N: return _MAKE4C('ATI2'); + case TEXFMT_BC6H: return _MAKE4C('BC6H'); + case TEXFMT_BC7: return _MAKE4C('BC7 '); + } + G_ASSERTF(0, "can't convert tex format: %d", fmt); + return D3DFMT_A8R8G8B8; +} diff --git a/prog/engine/drv/drv3d_commonCode/hangHandler.sh b/prog/engine/drv/drv3d_commonCode/hangHandler.dshl similarity index 92% rename from prog/engine/drv/drv3d_commonCode/hangHandler.sh rename to prog/engine/drv/drv3d_commonCode/hangHandler.dshl index 8a537a36e..2e10b0a6d 100644 --- a/prog/engine/drv/drv3d_commonCode/hangHandler.sh +++ b/prog/engine/drv/drv3d_commonCode/hangHandler.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" shader hang_gpu_cs { diff --git a/prog/engine/drv/drv3d_vulkan/buffer_locktransfer.cpp b/prog/engine/drv/drv3d_vulkan/buffer_locktransfer.cpp index 2dc9500c9..96355e8d3 100644 --- a/prog/engine/drv/drv3d_vulkan/buffer_locktransfer.cpp +++ b/prog/engine/drv/drv3d_vulkan/buffer_locktransfer.cpp @@ -106,14 +106,14 @@ void GenericBufferInterface::lockDMA(void **ptr) // sync with the host lockReadback( ptr, [&]() { ctx.flushBufferToHost(buffer, lockRange); }, - [&]() { buffer->markNonCoherentRange(lockRange.front(), lockRange.size(), false); }); + [&]() { buffer->markNonCoherentRangeLoc(lockRange.front(), lockRange.size(), false); }); } if (ptr) - *ptr = buffer->dataPointer(lockRange.front()); + *ptr = buffer->ptrOffsetLoc(lockRange.front()); } -void GenericBufferInterface::unlockWriteDMA() { buffer->markNonCoherentRange(lockRange.front(), lockRange.size(), true); } +void GenericBufferInterface::unlockWriteDMA() { buffer->markNonCoherentRangeLoc(lockRange.front(), lockRange.size(), true); } // staging path - for device visible buffers @@ -127,11 +127,11 @@ void GenericBufferInterface::lockStaging(void **ptr) lockReadback( ptr, [&]() { ctx.downloadBuffer(buffer, stagingBuffer, lockRange.front(), stageOffset, lockRange.size()); }, - [&]() { stagingBuffer->markNonCoherentRange(stageOffset, lockRange.size(), false); }); + [&]() { stagingBuffer->markNonCoherentRangeLoc(stageOffset, lockRange.size(), false); }); } if (ptr) - *ptr = stagingBuffer->dataPointer(stageOffset); + *ptr = stagingBuffer->ptrOffsetLoc(stageOffset); } void GenericBufferInterface::unlockWriteStaging() @@ -142,7 +142,7 @@ void GenericBufferInterface::unlockWriteStaging() if (stagingBufferIsPermanent()) stageOffset = lockRange.front(); - stagingBuffer->markNonCoherentRange(stageOffset, lockRange.size(), true); + stagingBuffer->markNonCoherentRangeLoc(stageOffset, lockRange.size(), true); ctx.uploadBuffer(stagingBuffer, buffer, stageOffset, lockRange.front(), lockRange.size()); } diff --git a/prog/engine/drv/drv3d_vulkan/buffer_resource.cpp b/prog/engine/drv/drv3d_vulkan/buffer_resource.cpp index 439fc271e..e96c47810 100644 --- a/prog/engine/drv/drv3d_vulkan/buffer_resource.cpp +++ b/prog/engine/drv/drv3d_vulkan/buffer_resource.cpp @@ -40,12 +40,18 @@ VkBufferUsageFlags Buffer::getUsage(VulkanDevice &device, DeviceMemoryClass memC } #if VK_KHR_buffer_device_address -VkDeviceAddress Buffer::getDeviceAddress(VulkanDevice &device) +VkDeviceAddress Buffer::getDeviceAddress(VulkanDevice &device) const { VkBufferDeviceAddressInfo info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; info.buffer = getHandle(); return device.vkGetBufferDeviceAddressKHR(device.get(), &info); } + +VkDeviceAddress Buffer::devOffsetAbs(VkDeviceSize ofs) const +{ + return getDeviceAddress(get_device().getVkDevice()) + sharedOffset + ofs; +} + #endif void Buffer::reportToTQL(bool is_allocating) @@ -114,29 +120,56 @@ MemoryRequirementInfo Buffer::getMemoryReq() return ret; } +// TODO: improve this, aligment should be, per spec, same for usage&flags combo +VkMemoryRequirements Buffer::getSharedHandleMemoryReq() +{ + Device &drvDev = get_device(); + VulkanDevice &vkDev = drvDev.getVkDevice(); + + VkMemoryRequirements ret; + ret.alignment = drvDev.getMinimalBufferAlignment(); + ret.size = getTotalSize(); + ret.memoryTypeBits = drvDev.memory->getMemoryTypeMaskForClass(desc.memoryClass); + + { + VulkanBufferHandle tmpBuf; + VkBufferCreateInfo bci; + bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bci.pNext = NULL; + bci.flags = 0; + bci.size = getTotalSize(); + bci.usage = Buffer::getUsage(vkDev, desc.memoryClass); + bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + bci.queueFamilyIndexCount = 0; + bci.pQueueFamilyIndices = NULL; + const VkResult resCode = VULKAN_CHECK_RESULT(vkDev.vkCreateBuffer(vkDev.get(), &bci, NULL, ptr(tmpBuf))); + if (resCode != VK_SUCCESS) + { + MemoryRequirementInfo ret2 = get_memory_requirements(vkDev, tmpBuf); + ret = ret2.requirements; + vkDev.vkDestroyBuffer(vkDev.get(), tmpBuf, nullptr); + } + } + +#if VULKAN_MAPPED_BUFFER_OVERRUN_WRITE_CHECK > 0 + ret.size *= 2; +#endif + return ret; +} + void Buffer::bindMemory() { G_ASSERT(getBaseHandle()); G_ASSERT(getMemoryId() != -1); - Device &drvDev = get_device(); - VulkanDevice &dev = drvDev.getVkDevice(); - const ResourceMemory &mem = getMemory(); + G_ASSERT(mem.isDeviceMemory()); + memoryOffset = mem.offset; + sharedOffset = 0; + fillPointers(mem); + // we are binding object to memory offset - baseMemoryOffset = 0; - if (mem.mappedPointer) - { - mappedPtr = mem.mappedPtrOffset(baseMemoryOffset); -#if VULKAN_MAPPED_BUFFER_OVERRUN_WRITE_CHECK > 0 - memset(mappedPtr + mem.size / 2, buffer_tail_filler, mem.size / 2); -#endif - } - if (!drvDev.isCoherencyAllowedFor(mem.memType)) - { - nonCoherentMemoryHandle = mem.deviceMemory(); - nonCoherentMemoryOffset = mem.offset; - } + VulkanDevice &dev = get_device().getVkDevice(); VULKAN_EXIT_ON_FAIL(dev.vkBindBufferMemory(dev.get(), getHandle(), mem.deviceMemory(), mem.offset)); reportToTQL(true); @@ -144,13 +177,39 @@ void Buffer::bindMemory() void Buffer::reuseHandle() { + G_ASSERT(!getBaseHandle()); G_ASSERT(getMemoryId() != -1); const ResourceMemory &mem = getMemory(); G_ASSERT(!mem.isDeviceMemory()); + memoryOffset = 0; + sharedOffset = mem.offset; + fillPointers(mem); - baseMemoryOffset = mem.offset; + // we are reusing handle setHandle(mem.handle); + reportToTQL(true); +} + +void Buffer::releaseSharedHandle() +{ + G_ASSERT(!getMemory().isDeviceMemory()); + G_ASSERT(isHandleShared()); + reportToTQL(false); + setHandle(generalize(Handle())); +} + +void Buffer::fillPointers(const ResourceMemory &mem) +{ + if (mem.mappedPointer) + { + mappedPtr = mem.mappedPtrOffset(0); +#if VULKAN_MAPPED_BUFFER_OVERRUN_WRITE_CHECK > 0 + memset(mappedPtr + mem.size / 2, buffer_tail_filler, mem.size / 2); +#endif + } + if (!get_device().isCoherencyAllowedFor(mem.memType)) + nonCoherentMemoryHandle = mem.isDeviceMemory() ? mem.deviceMemory() : mem.deviceMemorySlow(); } void Buffer::evict() { fatal("vulkan: buffers are not evictable"); } @@ -192,11 +251,14 @@ void Buffer::shutdown() discardAvailableFrames.reset(); } -uint8_t *Buffer::getMappedOffset(VkDeviceSize ofs) const { return mappedPtr + ofs; } - bool Buffer::hasMappedMemory() const { return mappedPtr != nullptr; } -void Buffer::markNonCoherentRange(uint32_t offset, uint32_t size, bool flush) +void Buffer::markNonCoherentRangeLoc(uint32_t offset, uint32_t size, bool flush) +{ + markNonCoherentRangeAbs(offset + getCurrentDiscardOffset(), size, flush); +} + +void Buffer::markNonCoherentRangeAbs(uint32_t offset, uint32_t size, bool flush) { // coherent memory does not need this if (is_null(nonCoherentMemoryHandle)) @@ -207,7 +269,7 @@ void Buffer::markNonCoherentRange(uint32_t offset, uint32_t size, bool flush) VkMappedMemoryRange range = {VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, nullptr}; range.memory = nonCoherentMemoryHandle; - range.offset = dataOffset(offset) + nonCoherentMemoryOffset; + range.offset = memOffsetAbs(offset); range.size = size; // Conform it to VUID-VkMappedMemoryRange-size-01390 diff --git a/prog/engine/drv/drv3d_vulkan/buffer_resource.h b/prog/engine/drv/drv3d_vulkan/buffer_resource.h index b2a4ca5cb..d058b8dc1 100644 --- a/prog/engine/drv/drv3d_vulkan/buffer_resource.h +++ b/prog/engine/drv/drv3d_vulkan/buffer_resource.h @@ -32,8 +32,10 @@ class Buffer : public BufferImplBase, public ResourceExecutionSyncableExtend void destroyVulkanObject(); void createVulkanObject(); MemoryRequirementInfo getMemoryReq(); + VkMemoryRequirements getSharedHandleMemoryReq(); void bindMemory(); void reuseHandle(); + void releaseSharedHandle(); void evict(); void restoreFromSysCopy(); bool isEvictable(); @@ -52,27 +54,27 @@ class Buffer : public BufferImplBase, public ResourceExecutionSyncableExtend void onDelayedCleanupFinish(); private: - uint32_t currentDiscardIndex = 0; eastl::unique_ptr views; eastl::unique_ptr discardAvailableFrames; - VkDeviceSize baseMemoryOffset = 0; + uint32_t currentDiscardIndex = 0; uint8_t *mappedPtr = nullptr; - VkDeviceSize nonCoherentMemoryOffset = 0; + VkDeviceSize sharedOffset = 0; + VkDeviceSize memoryOffset = 0; VulkanDeviceMemoryHandle nonCoherentMemoryHandle{}; - uint32_t getDiscardBlockSize() const { return desc.blockSize; } uint32_t getCurrentDiscardOffset() const { G_ASSERT(currentDiscardIndex < desc.discardCount); - return getDiscardBlockSize() * currentDiscardIndex; + return desc.blockSize * currentDiscardIndex; } void reportToTQL(bool is_allocating); + void fillPointers(const ResourceMemory &mem); public: - void markNonCoherentRange(uint32_t offset, uint32_t size, bool flush); + void markNonCoherentRangeAbs(uint32_t offset, uint32_t size, bool flush); + void markNonCoherentRangeLoc(uint32_t offset, uint32_t size, bool flush); - VkDeviceSize getBaseOffsetIntoMemory(VkDeviceSize offset) const { return offset + baseMemoryOffset; } inline bool onDiscard(uint32_t frontFrameIdx) { G_ASSERT(currentDiscardIndex < desc.discardCount); @@ -109,34 +111,49 @@ class Buffer : public BufferImplBase, public ResourceExecutionSyncableExtend inline bool hasView() const { return nullptr != views; } bool hasMappedMemory() const; - uint8_t *getMappedOffset(VkDeviceSize ofs) const; - - inline uint8_t *dataPointer(VkDeviceSize ofs) const { return getMappedOffset(ofs + getCurrentDiscardOffset()); } - inline VkDeviceSize dataOffset(VkDeviceSize ofs) const { return baseMemoryOffset + ofs + getCurrentDiscardOffset(); } - inline VkDeviceSize dataOffsetWithDiscardIndex(VkDeviceSize ofs, uint32_t discard_index) const - { - return baseMemoryOffset + ofs + (getDiscardBlockSize() * discard_index); - } - inline VkDeviceSize offsetOfLastDiscardIndex(VkDeviceSize ofs) const - { - G_ASSERT(currentDiscardIndex > 0); - return baseMemoryOffset + ofs + getCurrentDiscardOffset() - getDiscardBlockSize(); - } - inline VkDeviceSize offset(VkDeviceSize ofs) const { return baseMemoryOffset + ofs + getCurrentDiscardOffset(); } - inline VkDeviceSize offsetWithDiscardIndex(VkDeviceSize ofs, uint32_t discard_index) const - { - return baseMemoryOffset + ofs + (getDiscardBlockSize() * discard_index); - } - inline VkDeviceSize dataSize() const { return totalSize(); } - - Buffer(const Description &in_desc, bool managed = true) : BufferImplBase(in_desc, managed), currentDiscardIndex(0) {} - - inline VkDeviceSize totalSize() const { return getDiscardBlockSize(); } +private: +public: + // <....*..................> - memory + // ^ memory offset / device address + // <...*..............> - shared buffer object (buf suballoc) + // ^ shared buffer offset + // <...|...|...> - buffer object + // ^ discard block offset + // <...> - discard block + // ^ offset + + // 4 type of offsets with different bases + // memory + // Abs - memory offset + shared buffer offset + X + // Loc - memory offset + shared buffer offset + discard block offset + X + // buffer + // Abs - shared buffer offset + X + // Loc - shared buffer offset + discard block offset + X + // device + // Abs - device address + shared buffer offset + X + // Loc - device address + shared buffer offset + discard block offset + X + // ptr (mapped) + // Abs - mappedPtr + X + // Loc - mappedPtr + discard block offset + X + + VkDeviceSize memOffsetAbs(VkDeviceSize ofs) const { return memoryOffset + sharedOffset + ofs; } + VkDeviceSize bufOffsetAbs(VkDeviceSize ofs) const { return sharedOffset + ofs; } + uint8_t *ptrOffsetAbs(VkDeviceSize ofs) const { return mappedPtr + ofs; } + + VkDeviceSize memOffsetLoc(VkDeviceSize ofs) const { return memOffsetAbs(ofs) + getCurrentDiscardOffset(); } + VkDeviceSize bufOffsetLoc(VkDeviceSize ofs) const { return bufOffsetAbs(ofs) + getCurrentDiscardOffset(); } + uint8_t *ptrOffsetLoc(VkDeviceSize ofs) const { return ptrOffsetAbs(ofs) + getCurrentDiscardOffset(); } #if VK_KHR_buffer_device_address - VkDeviceAddress getDeviceAddress(VulkanDevice &device); + VkDeviceAddress getDeviceAddress(VulkanDevice &device) const; + VkDeviceAddress devOffsetAbs(VkDeviceSize ofs) const; + VkDeviceAddress devOffsetLoc(VkDeviceSize ofs) const { return devOffsetAbs(ofs) + getCurrentDiscardOffset(); } #endif + VkDeviceSize getBlockSize() { return desc.blockSize; } + VkDeviceSize getTotalSize() { return desc.blockSize * desc.discardCount; } + + Buffer(const Description &in_desc, bool managed = true) : BufferImplBase(in_desc, managed), currentDiscardIndex(0) {} static VkBufferUsageFlags getUsage(VulkanDevice &device, DeviceMemoryClass memClass); }; @@ -184,18 +201,15 @@ struct BufferRef ~BufferRef() = default; BufferRef(const BufferRef &) = default; BufferRef &operator=(const BufferRef &) = default; - // all defined in device.h // make this explicit to make it clear that we grab and hold on to the current // discard index explicit BufferRef(Buffer *bfr, uint32_t visible_data_size = 0); explicit operator bool() const; VulkanBufferHandle getHandle() const; VulkanBufferViewHandle getView() const; - VkDeviceSize dataOffset(VkDeviceSize ofs) const; - VkDeviceSize dataSize() const; - VkDeviceSize offset(VkDeviceSize ofs) const; + VkDeviceSize bufOffset(VkDeviceSize ofs) const; + VkDeviceSize memOffset(VkDeviceSize ofs) const; VkDeviceSize totalSize() const; - VkDeviceSize offsetOfLastDiscardIndex(VkDeviceSize ofs) const; }; inline bool operator==(const BufferRef &l, const BufferRef &r) { return (l.buffer == r.buffer) && (l.discardIndex == r.discardIndex); } @@ -205,7 +219,7 @@ inline bool operator!=(const BufferRef &l, const BufferRef &r) { return !(l == r inline BufferRef::BufferRef(Buffer *bfr, uint32_t visible_data_size) : buffer(bfr), discardIndex(bfr ? bfr->getCurrentDiscardIndex() : 0), - visibleDataSize(bfr && !visible_data_size ? bfr->dataSize() : visible_data_size) + visibleDataSize(bfr && !visible_data_size ? bfr->getBlockSize() : visible_data_size) {} inline BufferRef::operator bool() const { return nullptr != buffer; } @@ -217,18 +231,15 @@ inline VulkanBufferViewHandle BufferRef::getView() const return buffer->hasView() ? buffer->getViewOfDiscardIndex(discardIndex) : VulkanBufferViewHandle{}; } -inline VkDeviceSize BufferRef::dataOffset(VkDeviceSize ofs) const { return buffer->dataOffsetWithDiscardIndex(ofs, discardIndex); } - -inline VkDeviceSize BufferRef::dataSize() const { return visibleDataSize; } - -inline VkDeviceSize BufferRef::offset(VkDeviceSize ofs) const { return buffer->offsetWithDiscardIndex(ofs, discardIndex); } - -inline VkDeviceSize BufferRef::totalSize() const { return buffer->totalSize(); } - -inline VkDeviceSize BufferRef::offsetOfLastDiscardIndex(VkDeviceSize ofs) const +inline VkDeviceSize BufferRef::bufOffset(VkDeviceSize ofs) const { - G_ASSERT(discardIndex > 0); - return buffer->offsetWithDiscardIndex(ofs, discardIndex - 1); + return buffer->getBlockSize() * discardIndex + buffer->bufOffsetAbs(ofs); } +inline VkDeviceSize BufferRef::memOffset(VkDeviceSize ofs) const +{ + return buffer->getBlockSize() * discardIndex + buffer->memOffsetAbs(ofs); +} +inline VkDeviceSize BufferRef::totalSize() const { return buffer->getBlockSize(); } + } // namespace drv3d_vulkan diff --git a/prog/engine/drv/drv3d_vulkan/d3d_resource_update_buffer.cpp b/prog/engine/drv/drv3d_vulkan/d3d_resource_update_buffer.cpp index c864aec2f..3fa65fe23 100644 --- a/prog/engine/drv/drv3d_vulkan/d3d_resource_update_buffer.cpp +++ b/prog/engine/drv/drv3d_vulkan/d3d_resource_update_buffer.cpp @@ -71,7 +71,7 @@ d3d::ResUpdateBuffer *d3d::allocate_update_buffer_for_tex_region(BaseTexture *de rub->pitch = fmt.calculateRowPitch(width); rub->slicePitch = slicePitch; rub->uploadInfo = - make_copy_info(fmt, dest_mip, dest_slice, 1, {uint32_t(width), uint32_t(height), uint32_t(depth)}, stagingBuffer->dataOffset(0)); + make_copy_info(fmt, dest_mip, dest_slice, 1, {uint32_t(width), uint32_t(height), uint32_t(depth)}, stagingBuffer->bufOffsetLoc(0)); rub->uploadInfo.imageOffset.x = offset_x; rub->uploadInfo.imageOffset.y = offset_y; rub->uploadInfo.imageOffset.z = offset_z; @@ -121,13 +121,13 @@ d3d::ResUpdateBuffer *d3d::allocate_update_buffer_for_tex(BaseTexture *dest_base { case RES3D_VOLTEX: { - rub->uploadInfo = make_copy_info(fmt, dest_mip, 0, 1, {base_ti.w, base_ti.h, 1}, stagingBuffer->dataOffset(0)); + rub->uploadInfo = make_copy_info(fmt, dest_mip, 0, 1, {base_ti.w, base_ti.h, 1}, stagingBuffer->bufOffsetLoc(0)); rub->uploadInfo.imageOffset.z = dest_slice; break; } default: { - rub->uploadInfo = make_copy_info(fmt, dest_mip, dest_slice, 1, {base_ti.w, base_ti.h, 1}, stagingBuffer->dataOffset(0)); + rub->uploadInfo = make_copy_info(fmt, dest_mip, dest_slice, 1, {base_ti.w, base_ti.h, 1}, stagingBuffer->bufOffsetLoc(0)); break; } } @@ -150,14 +150,14 @@ char *d3d::get_update_buffer_addr_for_write(d3d::ResUpdateBuffer *rub) if (ResUpdateBufferImp *rub_imp = reinterpret_cast(rub)) { G_ASSERT(rub_imp->stagingBuffer->hasMappedMemory()); - return reinterpret_cast(rub_imp->stagingBuffer->dataPointer(0)); + return reinterpret_cast(rub_imp->stagingBuffer->ptrOffsetLoc(0)); } return nullptr; } size_t d3d::get_update_buffer_size(d3d::ResUpdateBuffer *rub) { - return rub ? ((ResUpdateBufferImp *)rub)->stagingBuffer->dataSize() : 0; + return rub ? ((ResUpdateBufferImp *)rub)->stagingBuffer->getBlockSize() : 0; } size_t d3d::get_update_buffer_pitch(d3d::ResUpdateBuffer *rub) { return rub ? ((ResUpdateBufferImp *)rub)->pitch : 0; } @@ -174,7 +174,7 @@ bool d3d::update_texture_and_release_update_buffer(d3d::ResUpdateBuffer *&rub) ResUpdateBufferImp *&rub_imp = reinterpret_cast(rub); - rub_imp->stagingBuffer->markNonCoherentRange(0, rub_imp->stagingBuffer->dataSize(), true); + rub_imp->stagingBuffer->markNonCoherentRangeLoc(0, rub_imp->stagingBuffer->getBlockSize(), true); drv3d_vulkan::get_device().getContext().copyBufferToImage(rub_imp->stagingBuffer, rub_imp->destTex->tex.image, 1, &rub_imp->uploadInfo, true); diff --git a/prog/engine/drv/drv3d_vulkan/device.cpp b/prog/engine/drv/drv3d_vulkan/device.cpp index 8af3337df..6f5e51646 100644 --- a/prog/engine/drv/drv3d_vulkan/device.cpp +++ b/prog/engine/drv/drv3d_vulkan/device.cpp @@ -40,7 +40,7 @@ VkAccelerationStructureGeometryKHR RaytraceGeometryDescriptionToVkAccelerationSt result.flags = toGeometryFlagsKHR(info.flags); return result; } -VkAccelerationStructureGeometryKHR RaytraceGeometryDescriptionToVkAccelerationStructureGeometryKHRTriangles(VulkanDevice &vkDev, +VkAccelerationStructureGeometryKHR RaytraceGeometryDescriptionToVkAccelerationStructureGeometryKHRTriangles(VulkanDevice &, const RaytraceGeometryDescription::TrianglesInfo &info) { auto devVbuf = ((GenericBufferInterface *)info.vertexBuffer)->getDeviceBuffer(); @@ -50,16 +50,15 @@ VkAccelerationStructureGeometryKHR RaytraceGeometryDescriptionToVkAccelerationSt result.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; result.geometry.triangles.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR; result.geometry.triangles.pNext = nullptr; - result.geometry.triangles.vertexData.deviceAddress = - devVbuf->getDeviceAddress(vkDev) + devVbuf->dataOffset(info.vertexOffset * info.vertexStride); - result.geometry.triangles.maxVertex = devVbuf->dataSize() / info.vertexStride - 1; // assume any vertex can be accessed + result.geometry.triangles.vertexData.deviceAddress = devVbuf->devOffsetLoc(info.vertexOffset * info.vertexStride); + result.geometry.triangles.maxVertex = devVbuf->getBlockSize() / info.vertexStride - 1; // assume any vertex can be accessed result.geometry.triangles.vertexStride = info.vertexStride; result.geometry.triangles.vertexFormat = VSDTToVulkanFormat(info.vertexFormat); if (info.indexBuffer) { auto ibuf = (GenericBufferInterface *)info.indexBuffer; auto devIbuf = ibuf->getDeviceBuffer(); - result.geometry.triangles.indexData.deviceAddress = devIbuf->getDeviceAddress(vkDev) + devIbuf->dataOffset(0); + result.geometry.triangles.indexData.deviceAddress = devIbuf->devOffsetLoc(0); result.geometry.triangles.indexType = ibuf->getIndexType(); } result.flags = toGeometryFlagsKHR(info.flags); @@ -132,6 +131,12 @@ void Device::configure(const Config &ucfg, const PhysicalDeviceSet &pds) debugLevel = ucfg.debugLevel; } +bool Device::checkImageViewFormat(FormatStore fmt, Image *img) +{ + return checkFormatSupport(fmt.asVkFormat(), VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, img->getUsage(), img->getCreateFlags(), + img->getSampleCount()); +} + // hot function VulkanImageViewHandle Device::getImageView(Image *img, ImageViewState state) { @@ -143,12 +148,19 @@ VulkanImageViewHandle Device::getImageView(Image *img, ImageViewState state) TIME_PROFILE(vulkan_get_image_view_ctor); VkImageViewCreateInfo ivci; FormatStore fmt = state.getFormat(); - if (!checkFormatSupport(fmt.asVkFormat(), VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, img->getUsage(), img->getCreateFlags(), - img->getSampleCount())) + bool fmtOk = checkImageViewFormat(fmt, img); + if (!fmtOk && fmt != img->getFormat()) { - logerr("vulkan: unsupported view format %s, falling back for image original format %s", fmt.getNameString(), + debug("vulkan: unsupported view format %s, falling back for image original format %s", fmt.getNameString(), img->getFormat().getNameString()); fmt = img->getFormat(); + fmtOk = checkImageViewFormat(fmt, img); + } + if (!fmtOk) + { + logerr("vulkan: failed to create image view for %p:%s with format %s usage %s samples %u flags %u", img, img->getDebugName(), + fmt.getNameString(), formatImageUsageFlags(img->getUsage()), img->getSampleCount(), img->getCreateFlags()); + return VulkanImageViewHandle{}; } ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; ivci.pNext = NULL; @@ -370,7 +382,7 @@ void Device::setupDummyResources() addBufferView(dummyBuffer, bufViewFmt); // zero out the buffer auto stage = createBuffer(dummySize, DeviceMemoryClass::HOST_RESIDENT_HOST_WRITE_ONLY_BUFFER, 1, BufferMemoryFlags::NONE); - memset(stage->dataPointer(0), 0, dummySize); + memset(stage->ptrOffsetLoc(0), 0, dummySize); // everything is 0 execept target image aspect, layer count and extent VkBufferImageCopy region = {}; @@ -528,21 +540,22 @@ void Device::setupDummyResources() dummyResourceTable[spirv::MISSING_STORAGE_BUFFER_SAMPLED_IMAGE_INDEX].resource = (void *)dummyBuffer; dummyResourceTable[spirv::MISSING_STORAGE_BUFFER_SAMPLED_IMAGE_INDEX].descriptor.texelBuffer = dummyBuffer->getView(); - VkDeviceSize dummyUniformSize = min(dummyBuffer->dataSize(), physicalDeviceInfo.properties.limits.maxUniformBufferRange); + VkDeviceSize dummyUniformSize = + min(dummyBuffer->getBlockSize(), physicalDeviceInfo.properties.limits.maxUniformBufferRange); dummyResourceTable[spirv::MISSING_BUFFER_INDEX].resource = (void *)dummyBuffer; dummyResourceTable[spirv::MISSING_BUFFER_INDEX].descriptor.buffer.buffer = dummyBuffer->getHandle(); - dummyResourceTable[spirv::MISSING_BUFFER_INDEX].descriptor.buffer.offset = dummyBuffer->dataOffset(0); + dummyResourceTable[spirv::MISSING_BUFFER_INDEX].descriptor.buffer.offset = dummyBuffer->bufOffsetLoc(0); dummyResourceTable[spirv::MISSING_BUFFER_INDEX].descriptor.buffer.range = dummyUniformSize; dummyResourceTable[spirv::MISSING_STORAGE_BUFFER_INDEX].resource = (void *)dummyBuffer; dummyResourceTable[spirv::MISSING_STORAGE_BUFFER_INDEX].descriptor.buffer.buffer = dummyBuffer->getHandle(); - dummyResourceTable[spirv::MISSING_STORAGE_BUFFER_INDEX].descriptor.buffer.offset = dummyBuffer->dataOffset(0); - dummyResourceTable[spirv::MISSING_STORAGE_BUFFER_INDEX].descriptor.buffer.range = dummyBuffer->dataSize(); + dummyResourceTable[spirv::MISSING_STORAGE_BUFFER_INDEX].descriptor.buffer.offset = dummyBuffer->bufOffsetLoc(0); + dummyResourceTable[spirv::MISSING_STORAGE_BUFFER_INDEX].descriptor.buffer.range = dummyBuffer->getBlockSize(); dummyResourceTable[spirv::MISSING_CONST_BUFFER_INDEX].resource = (void *)dummyBuffer; dummyResourceTable[spirv::MISSING_CONST_BUFFER_INDEX].descriptor.buffer.buffer = dummyBuffer->getHandle(); - dummyResourceTable[spirv::MISSING_CONST_BUFFER_INDEX].descriptor.buffer.offset = dummyBuffer->dataOffset(0); + dummyResourceTable[spirv::MISSING_CONST_BUFFER_INDEX].descriptor.buffer.offset = dummyBuffer->bufOffsetLoc(0); dummyResourceTable[spirv::MISSING_CONST_BUFFER_INDEX].descriptor.buffer.range = dummyUniformSize; // dummy is special, should be treated as null to avoid clearing up after fallback replacement @@ -1215,10 +1228,11 @@ Buffer *Device::createBuffer(uint32_t size, DeviceMemoryClass memory_class, uint void Device::addBufferView(Buffer *buffer, FormatStore format) { - G_ASSERTF((buffer->dataSize() % format.getBytesPerPixelBlock()) == 0, + G_ASSERTF((buffer->getBlockSize() % format.getBytesPerPixelBlock()) == 0, "invalid view of buffer, buffer has a size of %u, format (%s) element size is %u" " which leaves %u dangling bytes", - buffer->dataSize(), format.getNameString(), format.getBytesPerPixelBlock(), buffer->dataSize() % format.getBytesPerPixelBlock()); + buffer->getBlockSize(), format.getNameString(), format.getBytesPerPixelBlock(), + buffer->getBlockSize() % format.getBytesPerPixelBlock()); uint32_t viewCount = buffer->getMaxDiscardLimit(); eastl::unique_ptr views(new VulkanBufferViewHandle[viewCount]); @@ -1229,7 +1243,7 @@ void Device::addBufferView(Buffer *buffer, FormatStore format) bvci.flags = 0; bvci.buffer = buffer->getHandle(); bvci.format = format.asVkFormat(); - bvci.range = buffer->dataSize(); + bvci.range = buffer->getBlockSize(); { uint64_t sizeLimit = physicalDeviceInfo.properties.limits.maxStorageBufferRange; @@ -1249,7 +1263,7 @@ void Device::addBufferView(Buffer *buffer, FormatStore format) for (uint32_t d = 0; d < viewCount; ++d) { - bvci.offset = buffer->dataOffsetWithDiscardIndex(0, d); + bvci.offset = buffer->bufOffsetAbs(d * buffer->getBlockSize()); VULKAN_EXIT_ON_FAIL(device.vkCreateBufferView(device.get(), &bvci, NULL, ptr(views[d]))); } @@ -1469,14 +1483,10 @@ bool Device::hasGeometryShader() const { return VK_FALSE != physicalDeviceInfo.f bool Device::hasTesselationShader() const { - // FIXME: disabled temporarily because DXC compiled shaders work wrongly - // need to fix them and enable back - return false; - // const bool hasEnoughDescriptorSets = physicalDeviceInfo.properties.limits.maxBoundDescriptorSets > - // spirv::graphics::evaluation::REGISTERS_SET_INDEX; - // - // return physicalDeviceInfo.features.tessellationShader && - // hasEnoughDescriptorSets; + const bool hasEnoughDescriptorSets = + physicalDeviceInfo.properties.limits.maxBoundDescriptorSets > spirv::graphics::evaluation::REGISTERS_SET_INDEX; + + return physicalDeviceInfo.features.tessellationShader && hasEnoughDescriptorSets; } bool Device::hasFragmentShaderUAV() const { return VK_FALSE != physicalDeviceInfo.features.fragmentStoresAndAtomics; } @@ -1661,7 +1671,7 @@ void Device::ensureRoomForRaytraceBuildScratchBuffer(VkDeviceSize size) WinAutoLock lock(raytraceData.scratchReallocMutex); if (raytraceData.scratchBuffer) { - currentSize = raytraceData.scratchBuffer->dataSize(); + currentSize = raytraceData.scratchBuffer->getBlockSize(); } if (currentSize < size) diff --git a/prog/engine/drv/drv3d_vulkan/device.h b/prog/engine/drv/drv3d_vulkan/device.h index b3ee8ff17..097440aed 100644 --- a/prog/engine/drv/drv3d_vulkan/device.h +++ b/prog/engine/drv/drv3d_vulkan/device.h @@ -141,6 +141,7 @@ class Device Image *getDummy2DImage() { return dummyImage2D; } const ResourceDummySet &getDummyResourceTable() const { return dummyResourceTable; } + bool checkImageViewFormat(FormatStore fmt, Image *img); VulkanImageViewHandle getImageView(Image *img, ImageViewState state); VulkanDevice &getVkDevice() { return device; }; diff --git a/prog/engine/drv/drv3d_vulkan/device_context.cpp b/prog/engine/drv/drv3d_vulkan/device_context.cpp index 8226c987e..cf62acf9a 100644 --- a/prog/engine/drv/drv3d_vulkan/device_context.cpp +++ b/prog/engine/drv/drv3d_vulkan/device_context.cpp @@ -630,8 +630,8 @@ void DeviceContext::endSurvey(uint32_t name) void DeviceContext::uploadBuffer(Buffer *src, Buffer *dst, uint32_t src_offset, uint32_t dst_offset, uint32_t size) { VkBufferCopy copy; - copy.srcOffset = src->dataOffset(src_offset); - copy.dstOffset = dst->dataOffset(dst_offset); + copy.srcOffset = src->bufOffsetLoc(src_offset); + copy.dstOffset = dst->bufOffsetLoc(dst_offset); copy.size = size; BufferCopyInfo info; info.src = src; @@ -646,8 +646,8 @@ void DeviceContext::uploadBuffer(Buffer *src, Buffer *dst, uint32_t src_offset, void DeviceContext::uploadBufferOrdered(Buffer *src, Buffer *dst, uint32_t src_offset, uint32_t dst_offset, uint32_t size) { VkBufferCopy copy; - copy.srcOffset = src->dataOffset(src_offset); - copy.dstOffset = dst->dataOffset(dst_offset); + copy.srcOffset = src->bufOffsetLoc(src_offset); + copy.dstOffset = dst->bufOffsetLoc(dst_offset); copy.size = size; BufferCopyInfo info; info.src = src; @@ -662,8 +662,8 @@ void DeviceContext::uploadBufferOrdered(Buffer *src, Buffer *dst, uint32_t src_o void DeviceContext::downloadBuffer(Buffer *src, Buffer *dst, uint32_t src_offset, uint32_t dst_offset, uint32_t size) { VkBufferCopy copy; - copy.srcOffset = src->dataOffset(src_offset); - copy.dstOffset = dst->dataOffset(dst_offset); + copy.srcOffset = src->bufOffsetLoc(src_offset); + copy.dstOffset = dst->bufOffsetLoc(dst_offset); copy.size = size; BufferCopyInfo info; info.src = src; @@ -695,7 +695,7 @@ Buffer *DeviceContext::discardBuffer(Buffer *to_discared, DeviceMemoryClass memo if (!to_discared->onDiscard(front.frameIndex)) { uint32_t discardCount = to_discared->getMaxDiscardLimit() + FRAME_FRAME_BACKLOG_LENGTH + MAX_PENDING_WORK_ITEMS; - ret = device.createBuffer(to_discared->dataSize(), memory_class, discardCount, BufferMemoryFlags::NONE); + ret = device.createBuffer(to_discared->getBlockSize(), memory_class, discardCount, BufferMemoryFlags::NONE); if (to_discared->hasView()) device.addBufferView(ret, view_format); @@ -884,7 +884,7 @@ void DeviceContext::flushBufferToHost(Buffer *buffer, ValueRange range { BufferFlushInfo info; info.buffer = buffer; - info.offset = buffer->dataOffset(range.front()); + info.offset = buffer->bufOffsetLoc(range.front()); info.range = range.size(); VULKAN_LOCK_FRONT(); front.replayRecord->bufferToHostFlushes.push_back(info); @@ -1024,17 +1024,17 @@ RaytraceBLASBufferRefs getRaytraceGeometryRefs(const RaytraceGeometryDescription auto devIbuf = ((GenericBufferInterface *)desc.data.triangles.indexBuffer)->getDeviceBuffer(); uint32_t indexSize = ((GenericBufferInterface *)desc.data.triangles.indexBuffer)->getIndexType() == VkIndexType::VK_INDEX_TYPE_UINT32 ? 4 : 2; - return {devVbuf, (uint32_t)devVbuf->dataOffset(vofs), (uint32_t)devVbuf->dataSize() - vofs, devIbuf, - (uint32_t)devIbuf->dataOffset(desc.data.triangles.indexOffset * indexSize), desc.data.triangles.indexCount * indexSize}; + return {devVbuf, (uint32_t)devVbuf->bufOffsetLoc(vofs), (uint32_t)devVbuf->getBlockSize() - vofs, devIbuf, + (uint32_t)devIbuf->bufOffsetLoc(desc.data.triangles.indexOffset * indexSize), desc.data.triangles.indexCount * indexSize}; } else - return {devVbuf, (uint32_t)devVbuf->dataOffset(vofs), (uint32_t)devVbuf->dataSize() - vofs, nullptr, 0, 0}; + return {devVbuf, (uint32_t)devVbuf->bufOffsetLoc(vofs), (uint32_t)devVbuf->getBlockSize() - vofs, nullptr, 0, 0}; } case RaytraceGeometryDescription::Type::AABBS: { auto devBuf = ((GenericBufferInterface *)desc.data.aabbs.buffer)->getDeviceBuffer(); return { - devBuf, (uint32_t)devBuf->dataOffset(desc.data.aabbs.offset), desc.data.aabbs.stride * desc.data.aabbs.count, nullptr, 0, 0}; + devBuf, (uint32_t)devBuf->bufOffsetLoc(desc.data.aabbs.offset), desc.data.aabbs.stride * desc.data.aabbs.count, nullptr, 0, 0}; } default: G_ASSERTF(0, "vulkan: unknown geometry type %u in RaytraceGeometryDescription", (uint32_t)desc.type); } @@ -1241,7 +1241,7 @@ void DeviceContext::copyRaytraceShaderGroupHandlesToMemory(ProgramID prog, uint3 if (buffer->hasMappedMemory()) { - cmd.ptr = buffer->dataPointer(offset); + cmd.ptr = buffer->ptrOffsetLoc(offset); VULKAN_DISPATCH_COMMAND(cmd); } else diff --git a/prog/engine/drv/drv3d_vulkan/device_context.h b/prog/engine/drv/drv3d_vulkan/device_context.h index 6ad1a3c9d..b4d9932cc 100644 --- a/prog/engine/drv/drv3d_vulkan/device_context.h +++ b/prog/engine/drv/drv3d_vulkan/device_context.h @@ -197,6 +197,11 @@ class ExecutionContext bool flushProcessed = false; bool renderAllowed = false; + // counts amount of non-indirected drawcalls + uint32_t directDrawCount = 0; + // store amount of non-indirected drawcalls at start of survey + // to avoid waiting empty surveys as they can hang on some GPUs + uint32_t directDrawCountInSurvey = 0; VulkanCommandBufferHandle frameCore = VulkanHandle(); typedef ContextedPipelineBarrier PrimaryPipelineBarrier; @@ -291,7 +296,7 @@ class ExecutionContext void endQuery(VulkanQueryPoolHandle pool, uint32_t index); void writeTimestamp(const TimestampQueryRef &query); void wait(ThreadedFence *fence); - void beginConditionalRender(VulkanBufferHandle buffer, VkDeviceSize offset); + void beginConditionalRender(const BufferRef &buffer, VkDeviceSize offset); void endConditionalRender(); void addShaderModule(const ShaderModuleBlob *sci, uint32_t id); void removeShaderModule(uint32_t id); @@ -337,7 +342,7 @@ class ExecutionContext uint32_t first_region); void blitImage(Image *src, Image *dst, const VkImageBlit ®ion); void resetQuery(VulkanQueryPoolHandle pool, uint32_t index, uint32_t count); - void copyQueryResult(VulkanQueryPoolHandle pool, uint32_t index, uint32_t count, Buffer *dst, VkQueryResultFlags flags); + void copyQueryResult(VulkanQueryPoolHandle pool, uint32_t index, uint32_t count, Buffer *dst); void generateMipmaps(Image *img); void setGraphicsPipeline(ProgramID program); bool isInMultisampledFBPass(); diff --git a/prog/engine/drv/drv3d_vulkan/device_context/execution_context.cpp b/prog/engine/drv/drv3d_vulkan/device_context/execution_context.cpp index 4a8172588..89f0cabd2 100644 --- a/prog/engine/drv/drv3d_vulkan/device_context/execution_context.cpp +++ b/prog/engine/drv/drv3d_vulkan/device_context/execution_context.cpp @@ -94,15 +94,15 @@ void ExecutionContext::processFillEmptySubresources() // greedy allocation to avoid reallocations and memory wasting VkDeviceSize subresSz = i->getSubresourceMaxSize(); - if (!zeroBuf || (zeroBuf->dataSize() < subresSz)) + if (!zeroBuf || (zeroBuf->getBlockSize() < subresSz)) { if (zeroBuf) back.contextState.frame.get().cleanups.enqueueFromBackend(*zeroBuf); zeroBuf = get_device().createBuffer(subresSz, DeviceMemoryClass::DEVICE_RESIDENT_HOST_WRITE_ONLY_BUFFER, 1, BufferMemoryFlags::TEMP); zeroBuf->setDebugName("fill empty subres zero buf"); - memset(zeroBuf->dataPointer(0), 0, zeroBuf->dataSize()); - zeroBuf->markNonCoherentRange(0, zeroBuf->dataSize(), true); + memset(zeroBuf->ptrOffsetLoc(0), 0, zeroBuf->getBlockSize()); + zeroBuf->markNonCoherentRangeLoc(0, zeroBuf->getBlockSize(), true); } ValueRange mipRange = i->getMipLevelRange(); @@ -120,7 +120,7 @@ void ExecutionContext::processFillEmptySubresources() // present barrier is very special, as vkQueuePresent does all visibility ops // ref: vkQueuePresentKHR spec notes {VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT}, i, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, {mip, 1, arr, 1}); - copies.push_back(i->makeBufferCopyInfo(mip, arr, zeroBuf->dataOffset(0))); + copies.push_back(i->makeBufferCopyInfo(mip, arr, zeroBuf->bufOffsetLoc(0))); } back.syncTrack.completeNeeded(frameCore, vkDev); @@ -593,10 +593,12 @@ VulkanImageViewHandle ExecutionContext::getImageView(Image *img, ImageViewState void ExecutionContext::beginQuery(VulkanQueryPoolHandle pool, uint32_t index, VkQueryControlFlags flags) { VULKAN_LOG_CALL(vkDev.vkCmdBeginQuery(frameCore, pool, index, flags)); + directDrawCountInSurvey = directDrawCount; } void ExecutionContext::endQuery(VulkanQueryPoolHandle pool, uint32_t index) { + directDrawCountInSurvey = directDrawCount - directDrawCountInSurvey; VULKAN_LOG_CALL(vkDev.vkCmdEndQuery(frameCore, pool, index)); } @@ -604,11 +606,15 @@ void ExecutionContext::writeTimestamp(const TimestampQueryRef &query) { device.t void ExecutionContext::wait(ThreadedFence *fence) { fence->wait(vkDev); } -void ExecutionContext::beginConditionalRender(VulkanBufferHandle buffer, VkDeviceSize offset) +void ExecutionContext::beginConditionalRender(const BufferRef &buffer, VkDeviceSize offset) { #if VK_EXT_conditional_rendering + VkDeviceSize bufOffset = buffer.bufOffset(offset); + back.syncTrack.addBufferAccess({VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT, VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT}, + buffer.buffer, {bufOffset, sizeof(uint32_t)}); + VkConditionalRenderingBeginInfoEXT crbi = // - {VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, nullptr, buffer, offset, 0}; + {VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, nullptr, buffer.getHandle(), bufOffset, 0}; VULKAN_LOG_CALL(vkDev.vkCmdBeginConditionalRenderingEXT(frameCore, &crbi)); #else G_UNUSED(buffer); @@ -756,7 +762,7 @@ void ExecutionContext::buildAccelerationStructure(VkAccelerationStructureTypeKHR if (type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR) { back.syncTrack.addBufferAccess({VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_ACCESS_SHADER_READ_BIT}, - instance_buffer, {instance_buffer->dataOffset(instance_offset), sizeof(VkAccelerationStructureInstanceKHR) * instance_count}); + instance_buffer, {instance_offset, sizeof(VkAccelerationStructureInstanceKHR) * instance_count}); } else { @@ -774,7 +780,7 @@ void ExecutionContext::buildAccelerationStructure(VkAccelerationStructureTypeKHR back.syncTrack.addBufferAccess({VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR}, - scratch, {scratch->dataOffset(0), scratch->dataSize()}); + scratch, {scratch->bufOffsetLoc(0), scratch->getBlockSize()}); if (update) back.syncTrack.addAccelerationStructureAccess( @@ -1009,7 +1015,7 @@ void ExecutionContext::captureScreen(Buffer *buffer) // do the copy to buffer auto extent = colorImage->getMipExtents2D(0); VkBufferImageCopy copy{}; - copy.bufferOffset = buffer->dataOffset(0); + copy.bufferOffset = buffer->bufOffsetLoc(0); copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copy.imageSubresource.layerCount = 1; copy.imageExtent.width = extent.width; @@ -1020,7 +1026,7 @@ void ExecutionContext::captureScreen(Buffer *buffer) back.syncTrack.addImageAccess({VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT}, colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, {0, 1, 0, 1}); back.syncTrack.addBufferAccess({VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT}, buffer, - {buffer->dataOffset(0), copySize}); + {copy.bufferOffset, copySize}); back.syncTrack.completeNeeded(frameCore, vkDev); VULKAN_LOG_CALL(vkDev.vkCmdCopyImageToBuffer(frameCore, colorImage->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, @@ -1080,7 +1086,7 @@ void ExecutionContext::dispatchIndirect(BufferRef buffer, uint32_t offset) trackIndirectArgAccesses(buffer, offset, 1, sizeof(VkDispatchIndirectCommand)); flushComputeState(); - VULKAN_LOG_CALL(vkDev.vkCmdDispatchIndirect(frameCore, buffer.getHandle(), buffer.dataOffset(offset))); + VULKAN_LOG_CALL(vkDev.vkCmdDispatchIndirect(frameCore, buffer.getHandle(), buffer.bufOffset(offset))); writeExectionChekpoint(frameCore, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } @@ -1259,6 +1265,7 @@ void ExecutionContext::blitImage(Image *src, Image *dst, const VkImageBlit ®i VULKAN_LOG_CALL(vkDev.vkCmdBlitImage(frameCore, srcI->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstI->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion, VK_FILTER_LINEAR)); + writeExectionChekpoint(frameCore, VK_PIPELINE_STAGE_TRANSFER_BIT); } void ExecutionContext::resetQuery(VulkanQueryPoolHandle pool, uint32_t index, uint32_t count) @@ -1267,18 +1274,24 @@ void ExecutionContext::resetQuery(VulkanQueryPoolHandle pool, uint32_t index, ui VULKAN_LOG_CALL(vkDev.vkCmdResetQueryPool(frameCore, pool, index, count)); } -void ExecutionContext::copyQueryResult(VulkanQueryPoolHandle pool, uint32_t index, uint32_t count, Buffer *dst, - VkQueryResultFlags flags) +void ExecutionContext::copyQueryResult(VulkanQueryPoolHandle pool, uint32_t index, uint32_t count, Buffer *dst) { const uint32_t stride = sizeof(uint32_t); - uint32_t ofs = dst->dataOffset(index * stride); + uint32_t ofs = dst->bufOffsetLoc(index * stride); uint32_t sz = stride * count; + // do not copy if there was no writes to query, as copy will crash on some GPUs in this situation + if (directDrawCountInSurvey == 0) + { + // fill zero instead + fillBuffer(dst, ofs, sz, 1); + return; + } + back.syncTrack.addBufferAccess({VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT}, dst, {ofs, sz}); back.syncTrack.completeNeeded(frameCore, vkDev); - // TODO: put this at the end of the work item - VULKAN_LOG_CALL(vkDev.vkCmdCopyQueryPoolResults(frameCore, pool, index, count, dst->getHandle(), ofs, sz, flags)); + VULKAN_LOG_CALL(vkDev.vkCmdCopyQueryPoolResults(frameCore, pool, index, count, dst->getHandle(), ofs, sz, VK_QUERY_RESULT_WAIT_BIT)); } void ExecutionContext::generateMipmaps(Image *img) @@ -1342,6 +1355,7 @@ void ExecutionContext::generateMipmaps(Image *img) lastMipExtent = mipExtent; } } + writeExectionChekpoint(frameCore, VK_PIPELINE_STAGE_TRANSFER_BIT); } void ExecutionContext::bindVertexUserData(BufferSubAllocation bsa) @@ -1365,14 +1379,14 @@ void ExecutionContext::drawIndirect(BufferRef buffer, uint32_t offset, uint32_t // emulate multi draw indirect for (uint32_t i = 0; i < count; ++i) { - VULKAN_LOG_CALL(vkDev.vkCmdDrawIndirect(frameCore, buffer.getHandle(), buffer.dataOffset(offset), 1, stride)); + VULKAN_LOG_CALL(vkDev.vkCmdDrawIndirect(frameCore, buffer.getHandle(), buffer.bufOffset(offset), 1, stride)); writeExectionChekpoint(frameCore, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); offset += stride; } } else { - VULKAN_LOG_CALL(vkDev.vkCmdDrawIndirect(frameCore, buffer.getHandle(), buffer.dataOffset(offset), count, stride)); + VULKAN_LOG_CALL(vkDev.vkCmdDrawIndirect(frameCore, buffer.getHandle(), buffer.bufOffset(offset), count, stride)); writeExectionChekpoint(frameCore, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); } } @@ -1389,14 +1403,14 @@ void ExecutionContext::drawIndexedIndirect(BufferRef buffer, uint32_t offset, ui // emulate multi draw indirect for (uint32_t i = 0; i < count; ++i) { - VULKAN_LOG_CALL(vkDev.vkCmdDrawIndexedIndirect(frameCore, buffer.getHandle(), buffer.dataOffset(offset), 1, stride)); + VULKAN_LOG_CALL(vkDev.vkCmdDrawIndexedIndirect(frameCore, buffer.getHandle(), buffer.bufOffset(offset), 1, stride)); writeExectionChekpoint(frameCore, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); offset += stride; } } else { - VULKAN_LOG_CALL(vkDev.vkCmdDrawIndexedIndirect(frameCore, buffer.getHandle(), buffer.dataOffset(offset), count, stride)); + VULKAN_LOG_CALL(vkDev.vkCmdDrawIndexedIndirect(frameCore, buffer.getHandle(), buffer.bufOffset(offset), count, stride)); writeExectionChekpoint(frameCore, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); } } @@ -1406,6 +1420,7 @@ void ExecutionContext::draw(uint32_t count, uint32_t instance_count, uint32_t st if (!renderAllowed) return; + ++directDrawCount; VULKAN_LOG_CALL(vkDev.vkCmdDraw(frameCore, count, instance_count, start, first_instance)); writeExectionChekpoint(frameCore, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); } @@ -1416,13 +1431,14 @@ void ExecutionContext::drawIndexed(uint32_t count, uint32_t instance_count, uint if (!renderAllowed) return; + ++directDrawCount; VULKAN_LOG_CALL(vkDev.vkCmdDrawIndexed(frameCore, count, instance_count, index_start, vertex_base, first_instance)); writeExectionChekpoint(frameCore, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); } void ExecutionContext::bindIndexUser(BufferSubAllocation bsa) { - vkDev.vkCmdBindIndexBuffer(frameCore, bsa.buffer->getHandle(), bsa.buffer->offset(bsa.offset), VK_INDEX_TYPE_UINT16); + vkDev.vkCmdBindIndexBuffer(frameCore, bsa.buffer->getHandle(), bsa.buffer->bufOffsetLoc(bsa.offset), VK_INDEX_TYPE_UINT16); // set state dirty to restore after this intervention back.executionState.set(1); } @@ -1536,7 +1552,7 @@ void ExecutionContext::trackStageResAccesses(const spirv::ShaderHeader &header, break; case TRegister::TYPE_BUF: back.syncTrack.addBufferAccess(ExecutionSyncTracker::LogicAddress::forBufferOnExecStage(stageIndex, RegisterType::T), - reg.buf.buffer, {reg.buf.offset(0), reg.buf.dataSize()}); + reg.buf.buffer, {reg.buf.bufOffset(0), reg.buf.visibleDataSize}); break; #if D3D_HAS_RAY_TRACING case TRegister::TYPE_AS: @@ -1563,7 +1579,7 @@ void ExecutionContext::trackStageResAccesses(const spirv::ShaderHeader &header, else if (reg.buffer.buffer) { back.syncTrack.addBufferAccess(ExecutionSyncTracker::LogicAddress::forBufferOnExecStage(stageIndex, RegisterType::U), - reg.buffer.buffer, {reg.buffer.offset(0), reg.buffer.dataSize()}); + reg.buffer.buffer, {reg.buffer.bufOffset(0), reg.buffer.visibleDataSize}); } } @@ -1576,14 +1592,14 @@ void ExecutionContext::trackStageResAccesses(const spirv::ShaderHeader &header, const BufferRef ® = state.bRegisters[i]; if (reg.buffer) back.syncTrack.addBufferAccess(ExecutionSyncTracker::LogicAddress::forBufferOnExecStage(stageIndex, RegisterType::B), - reg.buffer, {reg.offset(0), reg.dataSize()}); + reg.buffer, {reg.bufOffset(0), reg.visibleDataSize}); } } void ExecutionContext::trackIndirectArgAccesses(BufferRef buffer, uint32_t offset, uint32_t count, uint32_t stride) { back.syncTrack.addBufferAccess({VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT}, buffer.buffer, - {buffer.offset(offset), stride * count}); + {buffer.bufOffset(offset), stride * count}); } void ExecutionContext::trackBindlessRead(Image *img) diff --git a/prog/engine/drv/drv3d_vulkan/device_context_cmd.inc b/prog/engine/drv/drv3d_vulkan/device_context_cmd.inc index 03db5adc0..c58d073a7 100644 --- a/prog/engine/drv/drv3d_vulkan/device_context_cmd.inc +++ b/prog/engine/drv/drv3d_vulkan/device_context_cmd.inc @@ -284,7 +284,7 @@ VULKAN_BEGIN_CONTEXT_COMMAND(CopyBuffer) #if VULKAN_CONTEXT_COMMAND_IMPLEMENTATION ctx.beginCustomStage("CopyBuffer"); - ctx.copyBuffer(source.buffer, dest.buffer, source.dataOffset(sourceOffset), dest.dataOffset(destOffset), dataSize); + ctx.copyBuffer(source.buffer, dest.buffer, source.bufOffset(sourceOffset), dest.bufOffset(destOffset), dataSize); #endif VULKAN_END_CONTEXT_COMMAND @@ -302,7 +302,7 @@ VULKAN_BEGIN_CONTEXT_COMMAND(ClearBufferFloat) fAsI.f = values[0]; // TODO: this is incorrect, but it works for now ctx.beginCustomStage("ClearBufferFloat"); - ctx.fillBuffer(buffer.buffer, buffer.dataOffset(0), buffer.dataSize(), fAsI.i); + ctx.fillBuffer(buffer.buffer, buffer.bufOffset(0), buffer.visibleDataSize, fAsI.i); #endif VULKAN_END_CONTEXT_COMMAND @@ -313,7 +313,7 @@ VULKAN_BEGIN_CONTEXT_COMMAND(ClearBufferInt) #if VULKAN_CONTEXT_COMMAND_IMPLEMENTATION // TODO: this is incorrect, but it works for now ctx.beginCustomStage("ClearBufferInt"); - ctx.fillBuffer(buffer.buffer, buffer.dataOffset(0), buffer.dataSize(), values[0]); + ctx.fillBuffer(buffer.buffer, buffer.bufOffset(0), buffer.visibleDataSize, values[0]); #endif VULKAN_END_CONTEXT_COMMAND @@ -434,7 +434,7 @@ VULKAN_BEGIN_CONTEXT_COMMAND(EndSurvey) #if VULKAN_CONTEXT_COMMAND_IMPLEMENTATION ctx.beginCustomStage("EndSurvey"); - ctx.copyQueryResult(pool, index, 1, buffer, VK_QUERY_RESULT_WAIT_BIT); + ctx.copyQueryResult(pool, index, 1, buffer); #endif VULKAN_END_CONTEXT_COMMAND @@ -593,7 +593,7 @@ VULKAN_BEGIN_CONTEXT_COMMAND(CaptureScreen) VULKAN_END_CONTEXT_COMMAND VULKAN_BEGIN_CONTEXT_COMMAND(SetConditionalRender) - VULKAN_CONTEXT_COMMAND_PARAM(VulkanBufferHandle, buffer) + VULKAN_CONTEXT_COMMAND_PARAM(BufferRef, buffer) VULKAN_CONTEXT_COMMAND_PARAM(VkDeviceSize, offset) #if VULKAN_CONTEXT_COMMAND_IMPLEMENTATION @@ -726,7 +726,7 @@ VULKAN_BEGIN_CONTEXT_COMMAND(RaytraceBuildTopAccelerationStructure) #if VK_KHR_ray_tracing_pipeline || VK_KHR_ray_query ctx.beginCustomStage("RaytraceBuildTopAccelerationStructure"); ctx.buildAccelerationStructure(VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, instanceCount, instanceBuffer.buffer, - instanceBuffer.dataOffset(0), 0, 0, ToVkBuildAccelerationStructureFlagsKHR(flags), update, as, {}, scratchBuffer); + instanceBuffer.bufOffset(0), 0, 0, ToVkBuildAccelerationStructureFlagsKHR(flags), update, as, {}, scratchBuffer); #endif #endif diff --git a/prog/engine/drv/drv3d_vulkan/device_memory.h b/prog/engine/drv/drv3d_vulkan/device_memory.h index eef2ba453..f8fa27b20 100644 --- a/prog/engine/drv/drv3d_vulkan/device_memory.h +++ b/prog/engine/drv/drv3d_vulkan/device_memory.h @@ -191,6 +191,13 @@ class DeviceMemoryPool { return DeviceMemoryTypeRange(classTypes[uint32_t(memory_class)], mask); } + uint32_t getMemoryTypeMaskForClass(DeviceMemoryClass memory_class) const + { + uint32_t ret = 0; + for (uint32_t i : classTypes[uint32_t(memory_class)]) + ret |= 1 << i; + return ret; + } VkDeviceSize getFeeMemoryForMemoryType(uint32_t type) const { return types[type].heap->size - types[type].heap->inUse; } DeviceMemory allocate(const DeviceMemoryClassAllocationInfo &info); DeviceMemory allocate(const DeviceMemoryTypeAllocationInfo &info); diff --git a/prog/engine/drv/drv3d_vulkan/device_memory_pages.cpp b/prog/engine/drv/drv3d_vulkan/device_memory_pages.cpp index c05ae9f8a..b8f9ac90e 100644 --- a/prog/engine/drv/drv3d_vulkan/device_memory_pages.cpp +++ b/prog/engine/drv/drv3d_vulkan/device_memory_pages.cpp @@ -73,18 +73,67 @@ uint32_t DeviceMemoryPage::getCatIdx(uint32_t allocator_idx) { return allocator_ bool DeviceMemoryPage::init(AbstractAllocator *allocator, SubAllocationMethod suballoc_method, VkDeviceSize in_size) { + Device &drvDev = get_device(); + VulkanDevice &vkDev = drvDev.getVkDevice(); subType = suballoc_method; + VkDeviceSize correctedSize = in_size; + + if (suballoc_method == SubAllocationMethod::BUF_OFFSET) + { + // Create buffer + VkBufferCreateInfo bci; + bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bci.pNext = NULL; + bci.flags = 0; + bci.size = in_size; + bci.usage = Buffer::getUsage(vkDev, drvDev.memory->isDeviceLocalMemoryType(allocator->getMemType()) + ? DeviceMemoryClass::DEVICE_RESIDENT_BUFFER + : DeviceMemoryClass::HOST_RESIDENT_HOST_READ_WRITE_BUFFER); + bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + bci.queueFamilyIndexCount = 0; + bci.pQueueFamilyIndices = NULL; + const VkResult resCode = VULKAN_CHECK_RESULT(vkDev.vkCreateBuffer(vkDev.get(), &bci, NULL, ptr(buffer))); + if (resCode != VK_SUCCESS) + return false; + + MemoryRequirementInfo ret = get_memory_requirements(vkDev, buffer); + correctedSize = ret.requirements.size; + if (!correctedSize) + { + vkDev.vkDestroyBuffer(vkDev.get(), buffer, nullptr); + return false; + } + } DeviceMemoryTypeAllocationInfo devMemDsc; devMemDsc.typeIndex = allocator->getMemType(); - devMemDsc.size = in_size; + devMemDsc.size = correctedSize; + + mem = drvDev.memory->allocate(devMemDsc); + if (is_null(mem)) + return false; - mem = get_device().memory->allocate(devMemDsc); - return !is_null(mem); + if (suballoc_method == SubAllocationMethod::BUF_OFFSET) + { + const VkResult resCode = VULKAN_CHECK_RESULT(vkDev.vkBindBufferMemory(vkDev.get(), buffer, mem.memory, 0)); + if (resCode != VK_SUCCESS) + { + vkDev.vkDestroyBuffer(vkDev.get(), buffer, nullptr); + return false; + } + } + + return true; } void DeviceMemoryPage::shutdown() { + if (buffer) + { + VulkanDevice &vkDev = get_device().getVkDevice(); + vkDev.vkDestroyBuffer(vkDev.get(), buffer, nullptr); + buffer = VulkanNullHandle(); + } get_device().memory->free(mem); mem.memory = VulkanNullHandle(); } @@ -100,9 +149,7 @@ bool DeviceMemoryPage::isAllocAllowedFor(const AllocationDesc &desc) void DeviceMemoryPage::useOffset(ResourceMemory &target, VkDeviceSize offset) { G_ASSERT(mem.size > offset); - // TODO: buf suballoc branch - // if (subType == SubAllocationMethod::BUF_OFFSET) - target.handle = generalize(mem.memory); + target.handle = subType == SubAllocationMethod::BUF_OFFSET ? generalize(buffer) : generalize(mem.memory); target.offset = offset; target.mappedPointer = mem.pointer; } @@ -156,15 +203,15 @@ void FixedOccupancyPage::free(ResourceMemory &target) shutdown(); } -VkDeviceSize FixedOccupancyPage::getUnusedMemorySize() { return freePlaces.size() * getSize() / totalPlaces; } +VkDeviceSize FixedOccupancyPage::getUnusedMemorySize() { return freePlaces.size() * getAllocatedMemorySize() / totalPlaces; } uint32_t FixedOccupancyPage::getOccupiedCount() { return totalPlaces - freePlaces.size(); } String FixedOccupancyPage::printMemoryMap(int32_t page_index) { - VkDeviceSize blockSize = getSize() / totalPlaces; + VkDeviceSize blockSize = getAllocatedMemorySize() / totalPlaces; - PageMemMap map(getSize(), page_index); + PageMemMap map(getAllocatedMemorySize(), page_index); for (VkDeviceSize i : freePlaces) map.markFreeBlock(i, blockSize); return map.print(); @@ -184,7 +231,7 @@ bool FreeListPage::init(AbstractAllocator *allocator, SubAllocationMethod suball void FreeListPage::shutdown() { - G_ASSERT(freeList.checkEmpty(getSize())); + G_ASSERT(freeList.checkEmpty(getAllocatedMemorySize())); G_ASSERT(refs == 0); freeList.reset(); DeviceMemoryPage::shutdown(); @@ -223,7 +270,7 @@ void FreeListPage::free(ResourceMemory &target) String FreeListPage::printMemoryMap(uint32_t page_index) { - PageMemMap map(getSize(), page_index); + PageMemMap map(getAllocatedMemorySize(), page_index); freeList.iterate([&map](VkDeviceSize offset, VkDeviceSize size) { map.markFreeBlock(offset, size); }); return map.print(); } @@ -233,6 +280,7 @@ bool LinearOccupancyPage::init(AbstractAllocator *allocator, SubAllocationMethod if (!DeviceMemoryPage::init(allocator, suballoc_method, page_size)) return false; + usableSize = page_size; refs = 0; pushOffset = 0; return true; @@ -253,7 +301,7 @@ bool LinearOccupancyPage::occupy(ResourceMemory &target, const AllocationDesc &d VkDeviceSize targetOffset = (pushOffset + invAlign) & ~invAlign; VkDeviceSize newOffset = targetOffset + size; - if (newOffset < getSize()) + if (newOffset < usableSize) { useOffset(target, targetOffset); pushOffset = newOffset; @@ -272,11 +320,11 @@ void LinearOccupancyPage::free(ResourceMemory &) pushOffset = 0; } -VkDeviceSize LinearOccupancyPage::getUnusedMemorySize() { return getSize() - pushOffset; } +VkDeviceSize LinearOccupancyPage::getUnusedMemorySize() { return getAllocatedMemorySize() - pushOffset; } String LinearOccupancyPage::printMemoryMap(uint32_t page_index) { - PageMemMap map(getSize(), page_index); + PageMemMap map(getAllocatedMemorySize(), page_index); map.markFreeBlock(pushOffset, getUnusedMemorySize()); return map.print(); } \ No newline at end of file diff --git a/prog/engine/drv/drv3d_vulkan/device_memory_pages.h b/prog/engine/drv/drv3d_vulkan/device_memory_pages.h index 7b01d4955..253bfb0b7 100644 --- a/prog/engine/drv/drv3d_vulkan/device_memory_pages.h +++ b/prog/engine/drv/drv3d_vulkan/device_memory_pages.h @@ -21,6 +21,7 @@ class DeviceMemoryPage { SubAllocationMethod subType; DeviceMemory mem; + VulkanBufferHandle buffer; public: static uint32_t toAllocatorIndex(uint32_t cat, uint32_t page); @@ -34,7 +35,8 @@ class DeviceMemoryPage void useOffset(ResourceMemory &target, VkDeviceSize offset); bool isValid() { return !is_null(mem); } - VkDeviceSize getSize() { return mem.size; } + VkDeviceSize getAllocatedMemorySize() { return mem.size; } + VulkanDeviceMemoryHandle getDeviceMemoryHandle() { return mem.memory; } }; class FixedOccupancyPage : public DeviceMemoryPage @@ -77,6 +79,7 @@ class LinearOccupancyPage : public DeviceMemoryPage { uint32_t refs; VkDeviceSize pushOffset; + VkDeviceSize usableSize; public: bool init(AbstractAllocator *allocator, SubAllocationMethod suballoc_method, VkDeviceSize page_size); diff --git a/prog/engine/drv/drv3d_vulkan/device_resource.cpp b/prog/engine/drv/drv3d_vulkan/device_resource.cpp index 34287aabe..93abc7e3a 100644 --- a/prog/engine/drv/drv3d_vulkan/device_resource.cpp +++ b/prog/engine/drv/drv3d_vulkan/device_resource.cpp @@ -27,9 +27,12 @@ bool Resource::tryAllocMemory(const AllocationDesc &dsc) bool Resource::tryReuseHandle(const AllocationDesc &dsc) { - if (!dsc.isSharedHandleAllowed()) - return false; sharedHandle = tryAllocMemory(dsc); + if (!sharedHandle && memoryId != -1) + { + get_device().resources.freeMemory(memoryId); + memoryId = -1; + } return sharedHandle; } diff --git a/prog/engine/drv/drv3d_vulkan/device_resource.h b/prog/engine/drv/drv3d_vulkan/device_resource.h index d7d7ed7b0..0f951c28f 100644 --- a/prog/engine/drv/drv3d_vulkan/device_resource.h +++ b/prog/engine/drv/drv3d_vulkan/device_resource.h @@ -59,10 +59,21 @@ class ResourceAlgorithm if (!res.isHandleShared()) destroyVkObj(); + else + res.releaseSharedHandle(); res.freeMemory(); } + bool tryReuseHandle(AllocationDesc &allocDsc) + { + if (!allocDsc.isSharedHandleAllowed()) + return false; + + allocDsc.reqs.requirements = res.getSharedHandleMemoryReq(); + return res.tryReuseHandle(allocDsc); + } + bool allocVulkanResource(const typename ResourceImpl::Description &desc) { if (!res.isManaged()) @@ -72,7 +83,7 @@ class ResourceAlgorithm AllocationDesc allocDsc{res}; desc.fillAllocationDesc(allocDsc); - if (!res.tryReuseHandle(allocDsc)) + if (!tryReuseHandle(allocDsc)) { allocDsc.canUseSharedHandle = false; res.createVulkanObject(); diff --git a/prog/engine/drv/drv3d_vulkan/driver_defs.h b/prog/engine/drv/drv3d_vulkan/driver_defs.h index 484848e1f..5aa4765c9 100644 --- a/prog/engine/drv/drv3d_vulkan/driver_defs.h +++ b/prog/engine/drv/drv3d_vulkan/driver_defs.h @@ -53,7 +53,7 @@ const uint32_t MAX_CONST_REGISTERS = const uint32_t MAX_UNIFORM_BUFFER_RANGE = MAX_CONST_REGISTERS * SHADER_REGISTER_SIZE; constexpr uint32_t DEFAULT_WAIT_SPINS = 4000; -constexpr uint32_t MAX_DEBUG_MARKER_BUFFER_ENTRIES = 1024 * 2; +constexpr uint32_t MAX_DEBUG_MARKER_BUFFER_ENTRIES = 4096 * 2; constexpr float MINIMUM_REPRESENTABLE_D16 = 2e-5; constexpr float MINIMUM_REPRESENTABLE_D24 = 33e-8; diff --git a/prog/engine/drv/drv3d_vulkan/execution_markers.cpp b/prog/engine/drv/drv3d_vulkan/execution_markers.cpp index 75df3dd65..ec0722353 100644 --- a/prog/engine/drv/drv3d_vulkan/execution_markers.cpp +++ b/prog/engine/drv/drv3d_vulkan/execution_markers.cpp @@ -59,16 +59,16 @@ void ExecutionMarkers::check() #if VK_AMD_buffer_marker if (executionMarkerBuffer) { - auto ptr = reinterpret_cast(executionMarkerBuffer->dataPointer(0)); + auto ptr = reinterpret_cast(executionMarkerBuffer->ptrOffsetLoc(0)); debug("Checking execution makers - VK_AMD_buffer_marker:"); - debug("Next id would be: %u", commandIndex); + debug("Next id would be: %08lX", commandIndex); uint32_t maxValue = 0; for (uint32_t i = 0; i < MAX_DEBUG_MARKER_BUFFER_ENTRIES; ++i) { maxValue = max(maxValue, ptr[i]); } - debug("Max committed value is: %u", maxValue); - debug("Missing %u commits", commandIndex - maxValue); + debug("Max committed value is: %08lX", maxValue); + debug("Missing %08lX commits", commandIndex - maxValue); markAsPassedIfLessOrEquel(maxValue); return; } @@ -177,7 +177,7 @@ void ExecutionMarkers::write(VulkanCommandBufferHandle cb, VkPipelineStageFlagBi dbgInfo.commandIndex = indexValue; VULKAN_LOG_CALL(vkDev.vkCmdWriteBufferMarkerAMD(cb, stage, executionMarkerBuffer->getHandle(), - executionMarkerBuffer->dataOffset((indexValue % MAX_DEBUG_MARKER_BUFFER_ENTRIES) * sizeof(uint32_t)), indexValue)); + executionMarkerBuffer->bufOffsetLoc((indexValue % MAX_DEBUG_MARKER_BUFFER_ENTRIES) * sizeof(uint32_t)), indexValue)); return; } diff --git a/prog/engine/drv/drv3d_vulkan/image_resource.cpp b/prog/engine/drv/drv3d_vulkan/image_resource.cpp index 8440e7163..00f1f4c1b 100644 --- a/prog/engine/drv/drv3d_vulkan/image_resource.cpp +++ b/prog/engine/drv/drv3d_vulkan/image_resource.cpp @@ -177,6 +177,12 @@ MemoryRequirementInfo Image::getMemoryReq() return get_memory_requirements(dev, getHandle()); } +VkMemoryRequirements Image::getSharedHandleMemoryReq() +{ + fatal("vulkan: no image handle suballoc"); + return {}; +} + void Image::bindMemory() { G_ASSERT(getBaseHandle()); @@ -191,6 +197,8 @@ void Image::bindMemory() void Image::reuseHandle() { fatal("vulkan: no image handle suballoc"); } +void Image::releaseSharedHandle() { fatal("vulkan: no image handle suballoc"); } + void Image::shutdown() { cleanupReferences(); } bool Image::nonResidentCreation() @@ -264,7 +272,7 @@ void Image::fillImage2BufferCopyData(carray &cop for (uint32_t j = 0; j < desc.ici.mipLevels; ++j) { VkBufferImageCopy © = copies[j]; - copy = make_copy_info(desc.format, j, 0, desc.ici.arrayLayers, desc.ici.extent, targetBuffer->dataOffset(bufferOffset)); + copy = make_copy_info(desc.format, j, 0, desc.ici.arrayLayers, desc.ici.extent, targetBuffer->bufOffsetLoc(bufferOffset)); bufferOffset += desc.format.calculateImageSize(copy.imageExtent.width, copy.imageExtent.height, copy.imageExtent.depth, 1) * desc.ici.arrayLayers; diff --git a/prog/engine/drv/drv3d_vulkan/image_resource.h b/prog/engine/drv/drv3d_vulkan/image_resource.h index baa0e552a..880b707e1 100644 --- a/prog/engine/drv/drv3d_vulkan/image_resource.h +++ b/prog/engine/drv/drv3d_vulkan/image_resource.h @@ -112,8 +112,10 @@ class Image : public ImageImplBase, public ResourceExecutionSyncableExtend void destroyVulkanObject(); void createVulkanObject(); MemoryRequirementInfo getMemoryReq(); + VkMemoryRequirements getSharedHandleMemoryReq(); void bindMemory(); void reuseHandle(); + void releaseSharedHandle(); void evict(); void restoreFromSysCopy(); bool isEvictable(); diff --git a/prog/engine/drv/drv3d_vulkan/pipeline/compiler.cpp b/prog/engine/drv/drv3d_vulkan/pipeline/compiler.cpp index 69557389d..18652a265 100644 --- a/prog/engine/drv/drv3d_vulkan/pipeline/compiler.cpp +++ b/prog/engine/drv/drv3d_vulkan/pipeline/compiler.cpp @@ -103,6 +103,7 @@ void PipelineCompiler::init() timeBlock.start(); primaryWorker.start(); + primaryWorker.setAffinity(-1); } void PipelineCompiler::shutdown() @@ -227,6 +228,7 @@ void PipelineCompiler::startSecondaryWorkers() { secondaryWorkers[i] = eastl::make_unique(*this, i); secondaryWorkers[i]->start(); + secondaryWorkers[i]->setAffinity(-1); } // wait threads to start waitSecondaryWorkers(); diff --git a/prog/engine/drv/drv3d_vulkan/pipeline/main_pipelines.cpp b/prog/engine/drv/drv3d_vulkan/pipeline/main_pipelines.cpp index e64eb3a31..5065d247e 100644 --- a/prog/engine/drv/drv3d_vulkan/pipeline/main_pipelines.cpp +++ b/prog/engine/drv/drv3d_vulkan/pipeline/main_pipelines.cpp @@ -252,7 +252,18 @@ GraphicsPipeline::GraphicsPipeline(VulkanDevice &device, VulkanPipelineCacheHand csd.tesselation.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; csd.tesselation.pNext = NULL; csd.tesselation.flags = 0; - csd.tesselation.patchControlPoints = 4; + + // note: this is not totally correct approach, need to reflect from shader to be precise, but it is enough for now + switch (info.varDsc.topology) + { + case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: csd.tesselation.patchControlPoints = 1; break; + case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: + case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: csd.tesselation.patchControlPoints = 2; break; + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: csd.tesselation.patchControlPoints = 3; break; + default: csd.tesselation.patchControlPoints = 4; break; + } csd.raster.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; csd.raster.pNext = NULL; @@ -420,7 +431,8 @@ GraphicsPipeline::GraphicsPipeline(VulkanDevice &device, VulkanPipelineCacheHand csd.dynamicStates.pDynamicStates = grPipeDynamicStateList; csd.piasci = // - {VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, NULL, 0, info.varDsc.topology, VK_FALSE}; + {VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, NULL, 0, + layout->hasTC() ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : info.varDsc.topology, VK_FALSE}; unsigned stagesCount = 0; for (size_t i = 0; i < spirv::graphics::MAX_SETS; ++i) @@ -524,11 +536,15 @@ VulkanPipelineHandle GraphicsPipeline::createPipelineObject(CreationFeedback &cr { VulkanDevice &device = get_device().getVkDevice(); - if (compileScratch->parentPipe && !is_null(compileScratch->parentPipe->getCompiledHandle())) + if (compileScratch->parentPipe) { - compileScratch->gpci.flags |= VK_PIPELINE_CREATE_DERIVATIVE_BIT; - compileScratch->gpci.basePipelineIndex = -1; - compileScratch->gpci.basePipelineHandle = compileScratch->parentPipe->getHandle(); + VulkanPipelineHandle parentHandle = compileScratch->parentPipe->getCompiledHandle(); + if (!is_null(parentHandle)) + { + compileScratch->gpci.flags |= VK_PIPELINE_CREATE_DERIVATIVE_BIT; + compileScratch->gpci.basePipelineIndex = -1; + compileScratch->gpci.basePipelineHandle = parentHandle; + } } cr_feedback.chainWith(compileScratch->gpci, device); diff --git a/prog/engine/drv/drv3d_vulkan/pipeline/stage_state_base.cpp b/prog/engine/drv/drv3d_vulkan/pipeline/stage_state_base.cpp index f220ea35c..285d09807 100644 --- a/prog/engine/drv/drv3d_vulkan/pipeline/stage_state_base.cpp +++ b/prog/engine/drv/drv3d_vulkan/pipeline/stage_state_base.cpp @@ -174,7 +174,7 @@ void PipelineStageStateBase::setTbuffer(uint32_t unit, BufferRef buffer) G_ASSERTF(buffer, "vulkan: binding empty tReg as buffer, should be filtered at bind point!"); getBufferAsSampledImageRegister(unit).texelBuffer = buffer.getView(); getBufferAsSampledImageRegister(unit).type = VkAnyDescriptorInfo::TYPE_BUF_VIEW; - getReadOnlyBufferRegister(unit).buffer = {buffer.getHandle(), buffer.dataOffset(0), buffer.dataSize()}; + getReadOnlyBufferRegister(unit).buffer = {buffer.getHandle(), buffer.bufOffset(0), buffer.visibleDataSize}; getReadOnlyBufferRegister(unit).type = VkAnyDescriptorInfo::TYPE_BUF; } @@ -193,7 +193,7 @@ void PipelineStageStateBase::setUbuffer(uint32_t unit, BufferRef buffer) { getStorageBufferAsImageRegister(unit).texelBuffer = buffer.getView(); getStorageBufferAsImageRegister(unit).type = VkAnyDescriptorInfo::TYPE_BUF_VIEW; - getStorageBufferRegister(unit).buffer = {buffer.getHandle(), buffer.dataOffset(0), buffer.dataSize()}; + getStorageBufferRegister(unit).buffer = {buffer.getHandle(), buffer.bufOffset(0), buffer.visibleDataSize}; getStorageBufferRegister(unit).type = VkAnyDescriptorInfo::TYPE_BUF; } else @@ -212,7 +212,7 @@ void PipelineStageStateBase::setBbuffer(uint32_t unit, BufferRef buffer) if (buffer) { getConstBufferRegister(unit).buffer.buffer = buffer.getHandle(); - getConstBufferRegister(unit).buffer.range = buffer.dataSize(); + getConstBufferRegister(unit).buffer.range = buffer.visibleDataSize; getConstBufferRegister(unit).buffer.offset = 0; getConstBufferRegister(unit).type = VkAnyDescriptorInfo::TYPE_BUF; } @@ -379,7 +379,7 @@ void PipelineStageStateBase::checkForMissingBinds(const spirv::ShaderHeader &hdr { Buffer *dummyBuf = (Buffer *)dummy_resource_table[hdr.missingTableIndex[i]].resource; ctx.back.syncTrack.addBufferAccess(ExecutionSyncTracker::LogicAddress::forBufferOnExecStage(stage, RegisterType::T), - dummyBuf, {0, dummyBuf->dataSize()}); + dummyBuf, {dummyBuf->bufOffsetLoc(0), dummyBuf->getBlockSize()}); } break; @@ -388,7 +388,7 @@ void PipelineStageStateBase::checkForMissingBinds(const spirv::ShaderHeader &hdr { Buffer *dummyBuf = (Buffer *)dummy_resource_table[hdr.missingTableIndex[i]].resource; ctx.back.syncTrack.addBufferAccess(ExecutionSyncTracker::LogicAddress::forBufferOnExecStage(stage, RegisterType::U), - dummyBuf, {0, dummyBuf->dataSize()}); + dummyBuf, {dummyBuf->bufOffsetLoc(0), dummyBuf->getBlockSize()}); } break; default: break; diff --git a/prog/engine/drv/drv3d_vulkan/pipeline/stage_state_base.h b/prog/engine/drv/drv3d_vulkan/pipeline/stage_state_base.h index c41f08bd3..8d944d99e 100644 --- a/prog/engine/drv/drv3d_vulkan/pipeline/stage_state_base.h +++ b/prog/engine/drv/drv3d_vulkan/pipeline/stage_state_base.h @@ -142,7 +142,7 @@ void PipelineStageStateBase::apply(VulkanDevice &device, const ResourceDummySet for (uint32_t i = GCBshift; i < spirv::B_REGISTER_INDEX_MAX; ++i) if (header.bRegisterUseMask & (1ul << i)) - dynamicOffsets[dynamicOffsetCount++] = bRegisters[i] ? bRegisters[i].dataOffset(0) : 0; + dynamicOffsets[dynamicOffsetCount++] = bRegisters[i] ? bRegisters[i].bufOffset(0) : 0; checkForMissingBinds(header, dummy_resource_table, ctx, target_stage); diff --git a/prog/engine/drv/drv3d_vulkan/pipeline/variated_graphics.h b/prog/engine/drv/drv3d_vulkan/pipeline/variated_graphics.h index 772cc0894..f606a5ff4 100644 --- a/prog/engine/drv/drv3d_vulkan/pipeline/variated_graphics.h +++ b/prog/engine/drv/drv3d_vulkan/pipeline/variated_graphics.h @@ -97,6 +97,8 @@ class VariatedGraphicsPipeline : public DebugAttachedPipelinehasTE(); } + bool hasTesselationStage() const { return hasTessControlStage() && hasTessEvaluationStage(); } + bool pendingCompilation(); private: diff --git a/prog/engine/drv/drv3d_vulkan/query_pools.cpp b/prog/engine/drv/drv3d_vulkan/query_pools.cpp index c2af6a7c6..afa308260 100644 --- a/prog/engine/drv/drv3d_vulkan/query_pools.cpp +++ b/prog/engine/drv/drv3d_vulkan/query_pools.cpp @@ -65,7 +65,7 @@ ConditionalRenderingState SurveyQueryManager::startCondRender(uint32_t name) con auto *buf = surveyPool[poolIndex].dataStore; return ConditionalRenderingState // - {buf->getHandle(), buf->offset(static_cast(surveyId * sizeof(uint32_t)))}; + {BufferRef(buf, sizeof(uint32_t)), surveyId * sizeof(uint32_t)}; } void SurveyQueryManager::remove(uint32_t name) diff --git a/prog/engine/drv/drv3d_vulkan/raytrace_as_resource.cpp b/prog/engine/drv/drv3d_vulkan/raytrace_as_resource.cpp index a1562fe59..5f718b3d8 100644 --- a/prog/engine/drv/drv3d_vulkan/raytrace_as_resource.cpp +++ b/prog/engine/drv/drv3d_vulkan/raytrace_as_resource.cpp @@ -125,10 +125,18 @@ MemoryRequirementInfo RaytraceAccelerationStructure::getMemoryReq() return ret; } +VkMemoryRequirements RaytraceAccelerationStructure::getSharedHandleMemoryReq() +{ + fatal("vulkan: no shared handle mode for RT AS"); + return {}; +} + void RaytraceAccelerationStructure::bindMemory() {} void RaytraceAccelerationStructure::reuseHandle() { fatal("vulkan: no shared handle mode for RT AS"); } +void RaytraceAccelerationStructure::releaseSharedHandle() { fatal("vulkan: no shared handle mode for RT AS"); } + void RaytraceAccelerationStructure::evict() { fatal("vulkan: RT AS is not evictable"); } void RaytraceAccelerationStructure::restoreFromSysCopy() { fatal("vulkan: RT AS is not evictable"); } diff --git a/prog/engine/drv/drv3d_vulkan/raytrace_as_resource.h b/prog/engine/drv/drv3d_vulkan/raytrace_as_resource.h index 019614a86..5c9a06220 100644 --- a/prog/engine/drv/drv3d_vulkan/raytrace_as_resource.h +++ b/prog/engine/drv/drv3d_vulkan/raytrace_as_resource.h @@ -33,8 +33,10 @@ class RaytraceAccelerationStructure : public RaytraceASImplBase, public Resource void destroyVulkanObject(); void createVulkanObject(); MemoryRequirementInfo getMemoryReq(); + VkMemoryRequirements getSharedHandleMemoryReq(); void bindMemory(); void reuseHandle(); + void releaseSharedHandle(); void evict(); void restoreFromSysCopy(); bool isEvictable(); diff --git a/prog/engine/drv/drv3d_vulkan/render_pass_resource.cpp b/prog/engine/drv/drv3d_vulkan/render_pass_resource.cpp index 79adc86e9..ef0ed5bc7 100644 --- a/prog/engine/drv/drv3d_vulkan/render_pass_resource.cpp +++ b/prog/engine/drv/drv3d_vulkan/render_pass_resource.cpp @@ -50,10 +50,18 @@ MemoryRequirementInfo RenderPassResource::getMemoryReq() return ret; } +VkMemoryRequirements RenderPassResource::getSharedHandleMemoryReq() +{ + fatal("vulkan: no handle reuse for render pass"); + return {}; +} + void RenderPassResource::bindMemory() {} void RenderPassResource::reuseHandle() { fatal("vulkan: no handle reuse for render pass"); } +void RenderPassResource::releaseSharedHandle() { fatal("vulkan: no handle reuse for render pass"); } + void RenderPassResource::evict() { fatal("vulkan: render pass are not evictable"); } void RenderPassResource::restoreFromSysCopy() { fatal("vulkan: render pass are not evictable"); } diff --git a/prog/engine/drv/drv3d_vulkan/render_pass_resource.h b/prog/engine/drv/drv3d_vulkan/render_pass_resource.h index 5d35cb6e8..657d78716 100644 --- a/prog/engine/drv/drv3d_vulkan/render_pass_resource.h +++ b/prog/engine/drv/drv3d_vulkan/render_pass_resource.h @@ -58,8 +58,10 @@ class RenderPassResource : public RenderPassResourceImplBase void destroyVulkanObject(); void createVulkanObject(); MemoryRequirementInfo getMemoryReq(); + VkMemoryRequirements getSharedHandleMemoryReq(); void bindMemory(); void reuseHandle(); + void releaseSharedHandle(); void evict(); void restoreFromSysCopy(); bool isEvictable(); diff --git a/prog/engine/drv/drv3d_vulkan/resource_allocators.cpp b/prog/engine/drv/drv3d_vulkan/resource_allocators.cpp index e3f482f44..ab64a5fa0 100644 --- a/prog/engine/drv/drv3d_vulkan/resource_allocators.cpp +++ b/prog/engine/drv/drv3d_vulkan/resource_allocators.cpp @@ -87,6 +87,15 @@ void DedicatedAllocator::free(ResourceMemory &target) onWrongFree(target); } +VulkanDeviceMemoryHandle DedicatedAllocator::getDeviceMemoryHandle(ResourceMemory &target) +{ + // we should not ask dedicated allocator about memory handle as we already know it via ResourceMemory object! + G_ASSERTF(0, "vulkan: trying to get device memory handle from dedicated allocator!"); + if (target.allocatorIndex != -1) + return list[target.allocatorIndex].memory; + return VulkanDeviceMemoryHandle{}; +} + const AbstractAllocator::Stats DedicatedAllocator::getStats() { Stats ret; @@ -108,7 +117,8 @@ const AbstractAllocator::Stats DedicatedAllocator::getStats() ////////////////////////////// -void SuballocPow2Allocator::init() +template +void SuballocPow2Allocator::init() { const DataBlock *settings = ::dgs_get_settings()->getBlockByNameEx("vulkan")->getBlockByNameEx("allocators")->getBlockByNameEx("pow2"); @@ -146,14 +156,16 @@ void SuballocPow2Allocator::init() } } -void SuballocPow2Allocator::shutdown() +template +void SuballocPow2Allocator::shutdown() { for (PageListType &i : categories) i.shutdown(); clear_and_shrink(categories); } -bool SuballocPow2Allocator::alloc(ResourceMemory &target, const AllocationDesc &desc) +template +bool SuballocPow2Allocator::alloc(ResourceMemory &target, const AllocationDesc &desc) { VkDeviceSize resSize = desc.reqs.requirements.size; if (resSize > maxSize) @@ -179,7 +191,8 @@ bool SuballocPow2Allocator::alloc(ResourceMemory &target, const AllocationDesc & return cat.alloc(this, target, desc, catIdx, mixingGranularity, catSize); } -void SuballocPow2Allocator::free(ResourceMemory &target) +template +void SuballocPow2Allocator::free(ResourceMemory &target) { uint32_t &allocatorIndex = target.allocatorIndex; if (allocatorIndex != -1) @@ -192,14 +205,28 @@ void SuballocPow2Allocator::free(ResourceMemory &target) onWrongFree(target); } -const AbstractAllocator::Stats SuballocPow2Allocator::getStats() +template +VulkanDeviceMemoryHandle SuballocPow2Allocator::getDeviceMemoryHandle(ResourceMemory &target) +{ + G_ASSERTF(subAllocMethod != SubAllocationMethod::MEM_OFFSET, + "vulkan: trying to get device memory handle from raw memory allocator!"); + uint32_t allocatorIndex = target.allocatorIndex; + if (allocatorIndex != -1) + return categories[DeviceMemoryPage::getCatIdx(allocatorIndex)] + .list[DeviceMemoryPage::getPageIdx(allocatorIndex)] + .getDeviceMemoryHandle(); + return VulkanDeviceMemoryHandle{}; +} + +template +const AbstractAllocator::Stats SuballocPow2Allocator::getStats() { Stats ret; ret.vkAllocs = 0; ret.allocs = 0; ret.overhead = 0; ret.usage = 0; - ret.name = "pow2 mem offset allocator"; + ret.name = subAllocMethod == SubAllocationMethod::MEM_OFFSET ? "pow2 mem offset allocator" : "pow2 buf offset allocator"; ret.pageMap = ""; for (intptr_t i = 0; i < categories.size(); ++i) @@ -208,9 +235,16 @@ const AbstractAllocator::Stats SuballocPow2Allocator::getStats() return ret; } +namespace drv3d_vulkan +{ +template class SuballocPow2Allocator; +template class SuballocPow2Allocator; +} // namespace drv3d_vulkan + ////////////////////////////// -void SuballocFreeListAllocator::init() +template +void SuballocFreeListAllocator::init() { const DataBlock *settings = ::dgs_get_settings()->getBlockByNameEx("vulkan")->getBlockByNameEx("allocators")->getBlockByNameEx("freelist"); @@ -229,13 +263,15 @@ void SuballocFreeListAllocator::init() G_ASSERT(pageSize > maxElementSize); } -void SuballocFreeListAllocator::shutdown() +template +void SuballocFreeListAllocator::shutdown() { for (PageListType &i : pages) i.shutdown(); } -bool SuballocFreeListAllocator::alloc(ResourceMemory &target, const AllocationDesc &desc) +template +bool SuballocFreeListAllocator::alloc(ResourceMemory &target, const AllocationDesc &desc) { VkDeviceSize size = desc.reqs.requirements.size; if (size >= maxElementSize) @@ -245,7 +281,8 @@ bool SuballocFreeListAllocator::alloc(ResourceMemory &target, const AllocationDe return pages[bucket].alloc(this, target, desc, bucket, mixingGranularity); } -void SuballocFreeListAllocator::free(ResourceMemory &target) +template +void SuballocFreeListAllocator::free(ResourceMemory &target) { uint32_t &allocatorIndex = target.allocatorIndex; if (allocatorIndex != -1) @@ -258,14 +295,28 @@ void SuballocFreeListAllocator::free(ResourceMemory &target) onWrongFree(target); } -const AbstractAllocator::Stats SuballocFreeListAllocator::getStats() +template +VulkanDeviceMemoryHandle SuballocFreeListAllocator::getDeviceMemoryHandle(ResourceMemory &target) +{ + G_ASSERTF(subAllocMethod != SubAllocationMethod::MEM_OFFSET, + "vulkan: trying to get device memory handle from raw memory allocator!"); + uint32_t allocatorIndex = target.allocatorIndex; + if (allocatorIndex != -1) + return pages[DeviceMemoryPage::getCatIdx(allocatorIndex)] + .list[DeviceMemoryPage::getPageIdx(allocatorIndex)] + .getDeviceMemoryHandle(); + return VulkanDeviceMemoryHandle{}; +} + +template +const AbstractAllocator::Stats SuballocFreeListAllocator::getStats() { Stats ret; ret.vkAllocs = 0; ret.allocs = 0; ret.overhead = 0; ret.usage = 0; - ret.name = "free list mem offset allocator"; + ret.name = subAllocMethod == SubAllocationMethod::MEM_OFFSET ? "free list mem offset allocator" : "free list buf offset allocator"; ret.pageMap = ""; for (int i = BUCKET_SMALL; i < BUCKET_COUNT; ++i) @@ -273,9 +324,16 @@ const AbstractAllocator::Stats SuballocFreeListAllocator::getStats() return ret; } +namespace drv3d_vulkan +{ +template class SuballocFreeListAllocator; +template class SuballocFreeListAllocator; +} // namespace drv3d_vulkan + ////////////////////////////// -void SuballocRingedAllocator::init() +template +void SuballocRingedAllocator::init() { const DataBlock *settings = ::dgs_get_settings()->getBlockByNameEx("vulkan")->getBlockByNameEx("allocators")->getBlockByNameEx("ring"); @@ -289,9 +347,14 @@ void SuballocRingedAllocator::init() #endif } -void SuballocRingedAllocator::shutdown() { ring.shutdown(); } +template +void SuballocRingedAllocator::shutdown() +{ + ring.shutdown(); +} -bool SuballocRingedAllocator::alloc(ResourceMemory &target, const AllocationDesc &desc) +template +bool SuballocRingedAllocator::alloc(ResourceMemory &target, const AllocationDesc &desc) { // no point to keep 1 element, so allow 2 minimum if ((ring.size >> 1) <= desc.reqs.requirements.size) @@ -310,7 +373,8 @@ bool SuballocRingedAllocator::alloc(ResourceMemory &target, const AllocationDesc return ret; } -void SuballocRingedAllocator::checkIntegrity() +template +void SuballocRingedAllocator::checkIntegrity() { #if DAGOR_DBGLEVEL > 0 if (!allocFailures) @@ -330,7 +394,8 @@ void SuballocRingedAllocator::checkIntegrity() // we should catch all non temporals in ring before release } -void SuballocRingedAllocator::free(ResourceMemory &target) +template +void SuballocRingedAllocator::free(ResourceMemory &target) { if (target.allocatorIndex != -1) { @@ -342,14 +407,25 @@ void SuballocRingedAllocator::free(ResourceMemory &target) onWrongFree(target); } -const AbstractAllocator::Stats SuballocRingedAllocator::getStats() +template +VulkanDeviceMemoryHandle SuballocRingedAllocator::getDeviceMemoryHandle(ResourceMemory &target) +{ + G_ASSERTF(subAllocMethod != SubAllocationMethod::MEM_OFFSET, + "vulkan: trying to get device memory handle from raw memory allocator!"); + if (target.allocatorIndex != -1) + return ring.list[target.allocatorIndex].getDeviceMemoryHandle(); + return VulkanDeviceMemoryHandle{}; +} + +template +const AbstractAllocator::Stats SuballocRingedAllocator::getStats() { Stats ret; ret.vkAllocs = 0; ret.allocs = 0; ret.overhead = 0; ret.usage = 0; - ret.name = "ring mem offset allocator"; + ret.name = subAllocMethod == SubAllocationMethod::MEM_OFFSET ? "ring mem offset allocator" : "ring buf offset allocator"; ret.pageMap = ""; checkIntegrity(); @@ -357,6 +433,12 @@ const AbstractAllocator::Stats SuballocRingedAllocator::getStats() return ret; } +namespace drv3d_vulkan +{ +template class SuballocRingedAllocator; +template class SuballocRingedAllocator; +} // namespace drv3d_vulkan + ////////////////////////////// void ObjectBackedAllocator::shutdown() @@ -383,6 +465,8 @@ bool ObjectBackedAllocator::alloc(ResourceMemory &target, const AllocationDesc & void ObjectBackedAllocator::free(ResourceMemory &) { --count; } +VulkanDeviceMemoryHandle ObjectBackedAllocator::getDeviceMemoryHandle(ResourceMemory &) { return VulkanDeviceMemoryHandle{}; } + const AbstractAllocator::Stats ObjectBackedAllocator::getStats() { Stats ret; diff --git a/prog/engine/drv/drv3d_vulkan/resource_manager.cpp b/prog/engine/drv/drv3d_vulkan/resource_manager.cpp index 07ef39a27..b994d3185 100644 --- a/prog/engine/drv/drv3d_vulkan/resource_manager.cpp +++ b/prog/engine/drv/drv3d_vulkan/resource_manager.cpp @@ -73,10 +73,19 @@ bool evict_from_pool(ObjectPool &pool, VkDeviceSize &desired_size) } // namespace +VulkanDeviceMemoryHandle ResourceMemory::deviceMemorySlow() const +{ + Device &device = get_device(); + SharedGuardedObjectAutoLock resLock(device.resources); + + return device.resources.getDeviceMemoryHandle(index); +} + void ResourceManager::init(WinCritSec *memory_lock, const PhysicalDeviceSet &dev_set) { uint32_t memTypesCount = dev_set.memoryProperties.memoryTypeCount; allowMixedPages = dev_set.properties.limits.bufferImageGranularity <= 1024; + allowBufferSuballoc = get_device().getPerDriverPropertyBlock("bufferSuballocation")->getBool("enable", false); debug("vulkan: %s type mixed allocators", allowMixedPages ? "using" : "not using"); hotMemPushIdx = 0; sharedGuard = memory_lock; @@ -118,14 +127,6 @@ AllocationMethodPriorityList ResourceManager::getAllocationMethods(const Allocat // select possible methods and their priority // based on allocation desc AllocationMethodPriorityList ret; - if (desc.isSharedHandleAllowed()) - { - // we want to allocate from shared handle allocators - // but they are not yet ready - // ret.methods[ret.available++] = AllocationMethodName::BUFFER_SUBALLOC_SMALL_POW2_ALIGNED_PAGES; - // ret.methods[ret.available++] = AllocationMethodName::BUFFER_SUBALLOC_HEAP_FREE_LIST; - return ret; - } // if underlying memory is purely object baked if (desc.objectBaked) @@ -134,6 +135,23 @@ AllocationMethodPriorityList ResourceManager::getAllocationMethods(const Allocat return ret; } + if (desc.isSharedHandleAllowed()) + { + // we want to allocate from shared handle allocators + if (desc.obj.isBuffer() && allowBufferSuballoc) + { + if (desc.temporary) + ret.methods[ret.available++] = AllocationMethodName::BUFFER_SHARED_RINGED; + else + { + ret.methods[ret.available++] = AllocationMethodName::BUFFER_SHARED_SMALL_POW2_ALIGNED_PAGES; + ret.methods[ret.available++] = AllocationMethodName::BUFFER_SHARED_HEAP_FREE_LIST; + } + } + // must exit early, shared handle uses separate codepath in ResourceAlgorithm + return ret; + } + // we can allocate via suballoc of resource is not dedicated if (!desc.isDedicated()) { @@ -316,6 +334,12 @@ void ResourceManager::freeMemory(ResourceMemoryId memory_id) const ResourceMemory &ResourceManager::getMemory(ResourceMemoryId memory_id) { return resAllocationsPool[memory_id]; } +VulkanDeviceMemoryHandle ResourceManager::getDeviceMemoryHandle(ResourceMemoryId memory_id) +{ + ResourceMemory &mem = resAllocationsPool[memory_id]; + return perMemoryTypeMethods[(int)mem.memType].getDeviceMemoryHandle(mem); +} + bool ResourceManager::evictResourcesFor(VkDeviceSize desired_size) { debug("vulkan: trying to evict resources for %u Kb memory", desired_size >> 10); @@ -519,15 +543,19 @@ void ResourceManager::MethodsArray::init(uint32_t mem_type, VkDeviceSize mixing_ methods[(int)AllocationMethodName::BUFFER_SUBALLOC_SMALL_POW2_ALIGNED_PAGES] = new SuballocPow2Allocator(); methods[(int)AllocationMethodName::IMAGE_SUBALLOC_SMALL_POW2_ALIGNED_PAGES] = new SuballocPow2Allocator(); methods[(int)AllocationMethodName::RT_AS_SUBALLOC_SMALL_POW2_ALIGNED_PAGES] = new SuballocPow2Allocator(); + methods[(int)AllocationMethodName::BUFFER_SHARED_SMALL_POW2_ALIGNED_PAGES] = + new SuballocPow2Allocator(); methods[(int)AllocationMethodName::MIXED_SUBALLOC_HEAP_FREE_LIST] = new SuballocFreeListAllocator(); methods[(int)AllocationMethodName::BUFFER_SUBALLOC_HEAP_FREE_LIST] = new SuballocFreeListAllocator(); methods[(int)AllocationMethodName::IMAGE_SUBALLOC_HEAP_FREE_LIST] = new SuballocFreeListAllocator(); methods[(int)AllocationMethodName::RT_AS_SUBALLOC_HEAP_FREE_LIST] = new SuballocFreeListAllocator(); + methods[(int)AllocationMethodName::BUFFER_SHARED_HEAP_FREE_LIST] = new SuballocFreeListAllocator(); methods[(int)AllocationMethodName::MIXED_SUBALLOC_RINGED] = new SuballocRingedAllocator(); methods[(int)AllocationMethodName::BUFFER_SUBALLOC_RINGED] = new SuballocRingedAllocator(); methods[(int)AllocationMethodName::IMAGE_SUBALLOC_RINGED] = new SuballocRingedAllocator(); + methods[(int)AllocationMethodName::BUFFER_SHARED_RINGED] = new SuballocRingedAllocator(); for (AbstractAllocator *i : methods) { @@ -561,6 +589,11 @@ bool ResourceManager::MethodsArray::alloc(ResourceMemory &target, AllocationMeth void ResourceManager::MethodsArray::free(ResourceMemory &target) { methods[(int)target.allocator]->free(target); } +VulkanDeviceMemoryHandle ResourceManager::MethodsArray::getDeviceMemoryHandle(ResourceMemory &target) +{ + return methods[(int)target.allocator]->getDeviceMemoryHandle(target); +} + const AbstractAllocator::Stats ResourceManager::MethodsArray::printStats() { AbstractAllocator::Stats ret = {}; diff --git a/prog/engine/drv/drv3d_vulkan/resource_manager.h b/prog/engine/drv/drv3d_vulkan/resource_manager.h index 58879ae83..729507fae 100644 --- a/prog/engine/drv/drv3d_vulkan/resource_manager.h +++ b/prog/engine/drv/drv3d_vulkan/resource_manager.h @@ -28,6 +28,11 @@ enum class AllocationMethodName // for resources that does not allocate heap memory OBJECT_BACKED_MEMORY, + // allocators with shared handles + BUFFER_SHARED_SMALL_POW2_ALIGNED_PAGES, + BUFFER_SHARED_HEAP_FREE_LIST, + BUFFER_SHARED_RINGED, + COUNT, INVALID }; @@ -62,21 +67,13 @@ struct ResourceMemory VulkanDeviceMemoryHandle deviceMemory() const { - // TODO: - // some parts of code need base memory handle for shared handle allocation - // and this will fail here, need to properly handle without much looses G_ASSERT(isDeviceMemory()); return VulkanDeviceMemoryHandle(handle); } - bool isDeviceMemory() const - { - // TODO: enable this when buffer suballocs will use shared handle allocators - return true; - // (allocator != AllocationMethodName::BUFFER_SUBALLOC_HEAP_FREE_LIST) && - // (allocator != AllocationMethodName::BUFFER_SUBALLOC_RINGED) && - // (allocator != AllocationMethodName::BUFFER_SUBALLOC_SMALL_POW2_ALIGNED_PAGES); - } + VulkanDeviceMemoryHandle deviceMemorySlow() const; + + bool isDeviceMemory() const { return allocator < AllocationMethodName::BUFFER_SHARED_SMALL_POW2_ALIGNED_PAGES; } uint8_t *mappedPtrOffset(uint32_t ofs) const { return mappedPointer + offset + ofs; } @@ -133,6 +130,7 @@ class AbstractAllocator virtual bool alloc(ResourceMemory &target, const AllocationDesc &desc) = 0; virtual void free(ResourceMemory &target) = 0; + virtual VulkanDeviceMemoryHandle getDeviceMemoryHandle(ResourceMemory &target) = 0; virtual const Stats getStats() = 0; @@ -231,6 +229,7 @@ class DedicatedAllocator : public AbstractAllocator bool alloc(ResourceMemory &target, const AllocationDesc &desc) override; void free(ResourceMemory &target) override; + VulkanDeviceMemoryHandle getDeviceMemoryHandle(ResourceMemory &target) override; const Stats getStats() override; }; @@ -246,13 +245,15 @@ class ObjectBackedAllocator : public AbstractAllocator bool alloc(ResourceMemory &target, const AllocationDesc &desc) override; void free(ResourceMemory &target) override; + VulkanDeviceMemoryHandle getDeviceMemoryHandle(ResourceMemory &target) override; const Stats getStats() override; }; +template class SuballocPow2Allocator final : public AbstractAllocator { - typedef PageList PageListType; + typedef PageList PageListType; Tab categories; VkDeviceSize minSize; VkDeviceSize maxSize; @@ -265,13 +266,18 @@ class SuballocPow2Allocator final : public AbstractAllocator bool alloc(ResourceMemory &target, const AllocationDesc &desc) override; void free(ResourceMemory &target) override; + VulkanDeviceMemoryHandle getDeviceMemoryHandle(ResourceMemory &target) override; const Stats getStats() override; }; +extern template class SuballocPow2Allocator; +extern template class SuballocPow2Allocator; + +template class SuballocFreeListAllocator final : public AbstractAllocator { - typedef PageList PageListType; + typedef PageList PageListType; enum { @@ -291,13 +297,18 @@ class SuballocFreeListAllocator final : public AbstractAllocator bool alloc(ResourceMemory &target, const AllocationDesc &desc) override; void free(ResourceMemory &target) override; + VulkanDeviceMemoryHandle getDeviceMemoryHandle(ResourceMemory &target) override; const Stats getStats() override; }; +extern template class SuballocFreeListAllocator; +extern template class SuballocFreeListAllocator; + +template class SuballocRingedAllocator final : public AbstractAllocator { - typedef PageList PageListType; + typedef PageList PageListType; PageListType ring; #if DAGOR_DBGLEVEL > 0 @@ -314,6 +325,7 @@ class SuballocRingedAllocator final : public AbstractAllocator bool alloc(ResourceMemory &target, const AllocationDesc &desc) override; void free(ResourceMemory &target) override; + VulkanDeviceMemoryHandle getDeviceMemoryHandle(ResourceMemory &target) override; const Stats getStats() override; @@ -321,14 +333,8 @@ class SuballocRingedAllocator final : public AbstractAllocator void checkIntegrity(); }; -class BufSuballocPow2Allocator : public DedicatedAllocator -{}; - -class BufSuballocFreeListAllocator : public DedicatedAllocator -{}; - -class BufSuballocRingedAllocator : public DedicatedAllocator -{}; +extern template class SuballocRingedAllocator; +extern template class SuballocRingedAllocator; struct AllocationMethodPriorityList { @@ -362,11 +368,13 @@ class ResourceManager bool alloc(ResourceMemory &target, AllocationMethodPriorityList prio, const AllocationDesc &desc); void free(ResourceMemory &target); + VulkanDeviceMemoryHandle getDeviceMemoryHandle(ResourceMemory &target); const AbstractAllocator::Stats printStats(); }; bool allowMixedPages; + bool allowBufferSuballoc; AllocationMethodPriorityList getAllocationMethods(const AllocationDesc &desc); Tab perMemoryTypeMethods; @@ -456,6 +464,7 @@ class ResourceManager ResourceMemoryId allocMemory(const AllocationDesc &desc); void freeMemory(ResourceMemoryId memory_id); const ResourceMemory &getMemory(ResourceMemoryId memory_id); + VulkanDeviceMemoryHandle getDeviceMemoryHandle(ResourceMemoryId memory_id); template ResType *alloc(const typename ResType::Description desc, bool manage = true) diff --git a/prog/engine/drv/drv3d_vulkan/shader/debug_program.cpp b/prog/engine/drv/drv3d_vulkan/shader/debug_program.cpp index 67c9b3c5f..964f301c7 100644 --- a/prog/engine/drv/drv3d_vulkan/shader/debug_program.cpp +++ b/prog/engine/drv/drv3d_vulkan/shader/debug_program.cpp @@ -80,6 +80,82 @@ alignas(uint32_t) static const uint8_t debug_vert_program[] = // 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00}; +/* output of glsang for: +#version 450 +in layout(location = 0) vec3 attr_POS; +in layout(location = 3) vec4 attr_COL0; +out layout(location = 0) vec4 col; +uniform layout(set = 2, binding = 0,std140) ubo { +layout(offset = 0, column_major) mat4 mat_0_VF0; +}; + +void main() { +gl_Position = (vec4(attr_POS.x, attr_POS.y, attr_POS.z, 1.0)*mat_0_VF0); +col = attr_COL0; +}*/ +alignas(uint32_t) static const uint8_t debug_vert_program_bindless[] = // + {0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, + 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, + 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x06, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, + 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x43, + 0x6c, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00, 0x06, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x43, 0x75, 0x6c, 0x6c, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x12, 0x00, 0x00, 0x00, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x50, + 0x4f, 0x53, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x75, 0x62, 0x6f, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x74, 0x5f, 0x30, 0x5f, 0x56, 0x46, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x03, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x43, 0x4f, 0x4c, 0x30, 0x00, 0x00, 0x00, 0x48, 0x00, + 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, + 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x18, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x26, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, + 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x41, 0x00, + 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x90, 0x00, 0x05, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x27, 0x00, 0x00, 0x00, 0x25, 0x00, + 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00}; + /* output of glsang for: #version 450 in layout(location = 0) vec4 col; @@ -107,7 +183,7 @@ alignas(uint32_t) static const uint8_t debug_frag_program[] = // 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00}; -void ShaderProgramDatabase::initDebugProg(DeviceContext &dc) +void ShaderProgramDatabase::initDebugProg(bool has_bindless, DeviceContext &dc) { // insert debug input layout [will be 0] InputLayout il; @@ -142,8 +218,11 @@ void ShaderProgramDatabase::initDebugProg(DeviceContext &dc) spirv::ShaderHeader &spvHeader = smh.header; spvHeader.descriptorTypes[0] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; spvHeader.imageViewTypes[0] = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - spvHeader.descriptorCounts[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; - spvHeader.descriptorCounts[0].descriptorCount = 1; + uint32_t cbSet = 0; + if (has_bindless) + cbSet += spirv::bindless::MAX_SETS; + spvHeader.descriptorCounts[cbSet].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + spvHeader.descriptorCounts[cbSet].descriptorCount = 1; spvHeader.maxConstantCount = 4 * 4; spvHeader.bonesConstantsUsed = 4 * 4; //? spvHeader.bRegisterUseMask = 1; @@ -161,8 +240,10 @@ void ShaderProgramDatabase::initDebugProg(DeviceContext &dc) ShaderModuleBlob smb = {}; // needs to typecast or insert will extend each element from u8 to u32 - auto from = reinterpret_cast(debug_vert_program); - auto to = reinterpret_cast(debug_vert_program + sizeof(debug_vert_program)); + const uint8_t *vertDump = has_bindless ? debug_vert_program_bindless : debug_vert_program; + size_t vertDumpSz = has_bindless ? sizeof(debug_vert_program_bindless) : sizeof(debug_vert_program); + auto from = reinterpret_cast(vertDump); + auto to = reinterpret_cast(vertDump + vertDumpSz); smb.blob.insert(end(smb.blob), from, to); smb.hash = spirv::HashValue::calculate(smb.blob.data(), smb.blob.size()); diff --git a/prog/engine/drv/drv3d_vulkan/shader/program_database.cpp b/prog/engine/drv/drv3d_vulkan/shader/program_database.cpp index 6f2045c83..384de7c3b 100644 --- a/prog/engine/drv/drv3d_vulkan/shader/program_database.cpp +++ b/prog/engine/drv/drv3d_vulkan/shader/program_database.cpp @@ -247,10 +247,10 @@ void ShaderProgramDatabase::deleteShader(DeviceContext &ctx, ShaderID shader) shaders.remove(ctx, shader); } -void ShaderProgramDatabase::init(DeviceContext &ctx) +void ShaderProgramDatabase::init(bool has_bindless, DeviceContext &ctx) { initShaders(ctx); - initDebugProg(ctx); + initDebugProg(has_bindless, ctx); // set debug prog to states, unset shader is an error ctx.getFrontend().pipelineState.set(debugProgId); } diff --git a/prog/engine/drv/drv3d_vulkan/shader/program_database.h b/prog/engine/drv/drv3d_vulkan/shader/program_database.h index e2d9da81f..acd010dd6 100644 --- a/prog/engine/drv/drv3d_vulkan/shader/program_database.h +++ b/prog/engine/drv/drv3d_vulkan/shader/program_database.h @@ -159,7 +159,7 @@ class ShaderProgramDatabase public: ShaderProgramDatabase() = default; - void init(DeviceContext &ctx); + void init(bool has_bindless, DeviceContext &ctx); void shutdown() { @@ -338,7 +338,7 @@ class ShaderProgramDatabase eastl::optional getShaderCreationInfo(DeviceContext &ctx, const CombinedChunkModules &modules); - void initDebugProg(DeviceContext &dc); + void initDebugProg(bool has_bindless, DeviceContext &dc); void initShaders(DeviceContext &ctx); ProgramID debugProgId; diff --git a/prog/engine/drv/drv3d_vulkan/state.h b/prog/engine/drv/drv3d_vulkan/state.h index 2ea1ca70e..6cb31be80 100644 --- a/prog/engine/drv/drv3d_vulkan/state.h +++ b/prog/engine/drv/drv3d_vulkan/state.h @@ -105,13 +105,13 @@ struct State { auto alloc = ctx.copyToTempBuffer(TempBufferManager::TYPE_UNIFORM, registerSpaceSizes[STAGE_VS] * SHADER_REGISTER_SIZE, getRegisterSectionStart(STAGE_VS)); - ctx.setConstRegisterBuffer(alloc.get().buffer->getHandle(), alloc.dataOffset(), alloc.get().size, STAGE_VS); + ctx.setConstRegisterBuffer(alloc.get().buffer->getHandle(), alloc.bufOffset(), alloc.get().size, STAGE_VS); } if (dirtyState.test(DirtyState::PIXEL_CONST_REGISTERS)) { auto alloc = ctx.copyToTempBuffer(TempBufferManager::TYPE_UNIFORM, registerSpaceSizes[STAGE_PS] * SHADER_REGISTER_SIZE, getRegisterSectionStart(STAGE_PS)); - ctx.setConstRegisterBuffer(alloc.get().buffer->getHandle(), alloc.dataOffset(), alloc.get().size, STAGE_PS); + ctx.setConstRegisterBuffer(alloc.get().buffer->getHandle(), alloc.bufOffset(), alloc.get().size, STAGE_PS); } dirtyState &= unchangedMask; @@ -125,7 +125,7 @@ struct State { auto alloc = ctx.copyToTempBuffer(TempBufferManager::TYPE_UNIFORM, registerSpaceSizes[STAGE_CS] * SHADER_REGISTER_SIZE, getRegisterSectionStart(STAGE_CS)); - ctx.setConstRegisterBuffer(alloc.get().buffer->getHandle(), alloc.dataOffset(), alloc.get().size, STAGE_CS); + ctx.setConstRegisterBuffer(alloc.get().buffer->getHandle(), alloc.bufOffset(), alloc.get().size, STAGE_CS); } dirtyState &= ~computeMask; diff --git a/prog/engine/drv/drv3d_vulkan/state_field_graphics.cpp b/prog/engine/drv/drv3d_vulkan/state_field_graphics.cpp index 6a09d8c10..0aa01c702 100644 --- a/prog/engine/drv/drv3d_vulkan/state_field_graphics.cpp +++ b/prog/engine/drv/drv3d_vulkan/state_field_graphics.cpp @@ -218,7 +218,7 @@ void StateFieldGraphicsConditionalRenderingState::dumpLog(const FrontGraphicsSta if (data == ConditionalRenderingState{}) debug("conditional rendering: inactive"); else - debug("conditional rendering: active on buffer %" PRIu64 ", offset %d", generalize(data.buffer), data.offset); + debug("conditional rendering: active on buffer %" PRIu64 ", offset %d", generalize(data.buffer.getHandle()), data.offset); } template <> @@ -227,7 +227,7 @@ void StateFieldGraphicsConditionalRenderingScopeOpener::dumpLog(const BackGraphi if (data == ConditionalRenderingState{}) debug("conditional rendering opener: inactive"); else - debug("conditional rendering opener: active on buffer %" PRIu64 ", offset %d", generalize(data.buffer), data.offset); + debug("conditional rendering opener: active on buffer %" PRIu64 ", offset %d", generalize(data.buffer.getHandle()), data.offset); } template <> @@ -248,10 +248,12 @@ void StateFieldGraphicsProgram::applyTo(FrontGraphicsStateStorage &, ExecutionSt InputLayoutID layoutID = spdb.getGraphicsProgInputLayout(handle); if (layoutID != InputLayoutID::Null()) { - auto &newPipeline = get_device().pipeMan.get(handle); + VariatedGraphicsPipeline &newPipeline = get_device().pipeMan.get(handle); target.get().pipelineState.inputLayout = layoutID; target.set(&newPipeline); target.set(newPipeline.getLayout()); + target.set( + newPipeline.hasTesselationStage() ? true : false); target.set(1); return; } @@ -261,6 +263,7 @@ void StateFieldGraphicsProgram::applyTo(FrontGraphicsStateStorage &, ExecutionSt target.get().pipelineState.inputLayout = InputLayoutID::Null(); target.set(nullptr); target.set(nullptr); + target.set(false); target.set(1); } @@ -719,16 +722,16 @@ void StateFieldGraphicsIndexBuffer::applyTo(BackGraphicsStateStorage &, Executio return; target.back.syncTrack.addBufferAccess({VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_INDEX_READ_BIT}, data.buffer, - {data.dataOffset(0), data.dataSize()}); - VULKAN_LOG_CALL(target.vkDev.vkCmdBindIndexBuffer(target.frameCore, data.getHandle(), data.dataOffset(0), indexType)); + {data.bufOffset(0), data.visibleDataSize}); + VULKAN_LOG_CALL(target.vkDev.vkCmdBindIndexBuffer(target.frameCore, data.getHandle(), data.bufOffset(0), indexType)); } template <> void StateFieldGraphicsIndexBuffer::dumpLog(const BackGraphicsStateStorage &) const { if (data.buffer) - debug("IB: ptr %p handle %llu ofs %u name %s", data.buffer, generalize(data.getHandle()), data.dataOffset(0), - data.buffer->getDebugName()); + debug("IB: ptr %p handle %llu ofs %u range %u name %s", data.buffer, generalize(data.getHandle()), data.bufOffset(0), + data.visibleDataSize, data.buffer->getDebugName()); else debug("IB: none"); } @@ -940,11 +943,11 @@ void StateFieldGraphicsVertexBuffersBindArray::applyTo(BackGraphicsStateStorage for (uint32_t i = 0; i < cnt; ++i) { - // G_ASSERTF(offsets[i] >= resPtrs[i]->offset(0), + // G_ASSERTF(offsets[i] >= resPtrs[i]->bufOffsetLoc(0), // "vulkan: old discard index is referenced/invalid offset (zero offset %u specified %u) for vb[%u] %p:%s", - // resPtrs[i]->offset(0), offsets[i], i, resPtrs[i], resPtrs[i]->getDebugName()); + // resPtrs[i]->bufOffsetLoc(0), offsets[i], i, resPtrs[i], resPtrs[i]->getDebugName()); target.back.syncTrack.addBufferAccess({VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT}, resPtrs[i], - {offsets[i], resPtrs[i]->dataSize() - (offsets[i] % resPtrs[i]->dataSize())}); + {offsets[i], resPtrs[i]->getBlockSize() - (offsets[i] % resPtrs[i]->getBlockSize())}); } VULKAN_LOG_CALL(target.vkDev.vkCmdBindVertexBuffers(target.frameCore, 0, cnt, ary(buffers), offsets)); @@ -992,13 +995,15 @@ void StateFieldGraphicsPrimitiveTopology::applyTo(BackGraphicsStateStorage &stat if (!state.basePipeline.ptr) return; + VkPrimitiveTopology actual = useTessOverride ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : data; bool hasGS = state.basePipeline.ptr->hasGeometryStage(); - bool hasTesselation = state.basePipeline.ptr->hasTessControlStage() && state.basePipeline.ptr->hasTessEvaluationStage(); - if (!validate_primitive_topology(data, hasGS, hasTesselation)) + bool hasTesselation = state.basePipeline.ptr->hasTesselationStage(); + + if (!validate_primitive_topology(actual, hasGS, hasTesselation)) { logerr("Invalid primitive topology %s for draw call encountered. Geometry stage active %s, " "Tessellation stage active %s.", - formatPrimitiveTopology(data), hasGS ? "yes" : "no", hasTesselation ? "yes" : "no"); + formatPrimitiveTopology(actual), hasGS ? "yes" : "no", hasTesselation ? "yes" : "no"); } #else G_UNUSED(state); @@ -1008,7 +1013,7 @@ void StateFieldGraphicsPrimitiveTopology::applyTo(BackGraphicsStateStorage &stat template <> void StateFieldGraphicsPrimitiveTopology::dumpLog(const BackGraphicsStateStorage &) const { - debug("primTopo: %s", formatPrimitiveTopology(data)); + debug("primTopo: %s tessOverride: %s", formatPrimitiveTopology(data), useTessOverride ? "yes" : "no"); } void StateFieldGraphicsFlush::syncTLayoutsToRenderPass(BackGraphicsStateStorage &state, ExecutionContext &target) const @@ -1064,6 +1069,7 @@ void StateFieldGraphicsFlush::applyDescriptors(BackGraphicsStateStorage &state, if (withGS) { + ctx.stageState[STAGE_VS].invalidateState(); ctx.stageState[STAGE_VS].apply(vkDev, drvDev.getDummyResourceTable(), ctx.frame->index, regs.gs(), target, STAGE_VS, [&target, layoutHandle](VulkanDescriptorSetHandle set, const uint32_t *offsets, uint32_t offset_count) // { @@ -1075,6 +1081,7 @@ void StateFieldGraphicsFlush::applyDescriptors(BackGraphicsStateStorage &state, if (withTC) { + ctx.stageState[STAGE_VS].invalidateState(); ctx.stageState[STAGE_VS].apply(vkDev, drvDev.getDummyResourceTable(), ctx.frame->index, regs.tc(), target, STAGE_VS, [&target, layoutHandle](VulkanDescriptorSetHandle set, const uint32_t *offsets, uint32_t offset_count) // { @@ -1086,6 +1093,7 @@ void StateFieldGraphicsFlush::applyDescriptors(BackGraphicsStateStorage &state, if (withTE) { + ctx.stageState[STAGE_VS].invalidateState(); ctx.stageState[STAGE_VS].apply(vkDev, drvDev.getDummyResourceTable(), ctx.frame->index, regs.te(), target, STAGE_VS, [&target, layoutHandle](VulkanDescriptorSetHandle set, const uint32_t *offsets, uint32_t offset_count) // { @@ -1094,6 +1102,9 @@ void StateFieldGraphicsFlush::applyDescriptors(BackGraphicsStateStorage &state, ary(&set), offset_count, offsets)); }); } + // as we are sharing VS stage state, invalidate it in order to not break up followup rendering + if (withTE || withTC || withGS) + ctx.stageState[STAGE_VS].invalidateState(); } void StateFieldGraphicsFlush::applyBarriers(BackGraphicsStateStorage &state, ExecutionContext &target) const diff --git a/prog/engine/drv/drv3d_vulkan/state_field_graphics.h b/prog/engine/drv/drv3d_vulkan/state_field_graphics.h index 53f963013..6655eaf8b 100644 --- a/prog/engine/drv/drv3d_vulkan/state_field_graphics.h +++ b/prog/engine/drv/drv3d_vulkan/state_field_graphics.h @@ -55,7 +55,7 @@ struct ConditionalRenderingState struct InvalidateTag {}; - VulkanBufferHandle buffer{}; + BufferRef buffer{}; VkDeviceSize offset{0}; friend bool operator==(const This &left, const This &right) { return left.buffer == right.buffer && left.offset == right.offset; } @@ -478,7 +478,7 @@ struct StateFieldGraphicsVertexBuffersBindArray : TrackedStateFieldBasegetHandle(); - offsets[0] = bsa.buffer->dataOffset(bsa.offset); + offsets[0] = bsa.buffer->bufOffsetLoc(bsa.offset); countMask |= 1 << 0; } bool diff(const BufferSubAllocation &) const { return true; } @@ -489,7 +489,7 @@ struct StateFieldGraphicsVertexBuffersBindArray : TrackedStateFieldBase {}; -struct StateFieldGraphicsPrimitiveTopology : TrackedStateFieldBase, TrackedStateFieldGenericSmallPOD +struct StateFieldGraphicsPrimitiveTopology : TrackedStateFieldBase { + using TessOverride = bool; + TessOverride useTessOverride; + VkPrimitiveTopology data; + template void reset(StorageType &) { data = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + useTessOverride = false; } + void set(VkPrimitiveTopology value) { data = value; } + bool diff(VkPrimitiveTopology value) const { return data != value; } + + void set(TessOverride value) { useTessOverride = value; } + bool diff(TessOverride value) const { return useTessOverride != value; } + VULKAN_TRACKED_STATE_FIELD_CB_DEFENITIONS(); }; diff --git a/prog/engine/drv/drv3d_vulkan/state_field_resource_binds.cpp b/prog/engine/drv/drv3d_vulkan/state_field_resource_binds.cpp index f7cf5faf3..22ce42ce7 100644 --- a/prog/engine/drv/drv3d_vulkan/state_field_resource_binds.cpp +++ b/prog/engine/drv/drv3d_vulkan/state_field_resource_binds.cpp @@ -526,7 +526,7 @@ void ImmediateConstBuffer::flushWrites() G_ASSERTF(buf, "vulkan: ImmediateConstBuffer: buffer or offset changed independently to each other"); VkDeviceSize absOffset = (offset - 1) * blockSize; - buf->markNonCoherentRange(buf->dataOffset(0), absOffset, true); + buf->markNonCoherentRangeLoc(0, absOffset, true); } } @@ -544,13 +544,13 @@ BufferRef ImmediateConstBuffer::push(const uint32_t *data) buf = get_device().createBuffer(element_size, DeviceMemoryClass::DEVICE_RESIDENT_HOST_WRITE_ONLY_BUFFER, initial_blocks, BufferMemoryFlags::NONE); - blockSize = buf->dataSize(); + blockSize = buf->getBlockSize(); offset = 0; ring[ringIdx] = buf; } VkDeviceSize absOffset = offset * blockSize; - memcpy(buf->dataPointer(absOffset), data, element_size); + memcpy(buf->ptrOffsetLoc(absOffset), data, element_size); BufferRef ret(buf); ret.discardIndex = offset; diff --git a/prog/engine/drv/drv3d_vulkan/swapchain.cpp b/prog/engine/drv/drv3d_vulkan/swapchain.cpp index 1a8f86ccd..2e72db87d 100644 --- a/prog/engine/drv/drv3d_vulkan/swapchain.cpp +++ b/prog/engine/drv/drv3d_vulkan/swapchain.cpp @@ -295,7 +295,7 @@ Swapchain::ChangeResult Swapchain::changeSwapchain(FrameInfo &frame) sci.queueFamilyIndexCount = 0; sci.pQueueFamilyIndices = nullptr; sci.clipped = VK_FALSE; - sci.oldSwapchain = handle; + sci.oldSwapchain = reuseHandle ? handle : VulkanSwapchainKHRHandle{}; auto caps = querySurfaceCaps(); @@ -650,6 +650,9 @@ bool Swapchain::init(const SwapchainMode &initial_mode) activeMode = initial_mode; handle = VulkanNullHandle(); + reuseHandle = device.getPerDriverPropertyBlock("reuseSwapchainHandle")->getBool("allow", true); + debug("vulkan: swapchain: %s reuse handle", reuseHandle ? "allow" : "disallow"); + #if _TARGET_ANDROID { char sdkVerS[PROP_VALUE_MAX + 1]; @@ -887,24 +890,6 @@ void Swapchain::present(ExecutionContext &ctx) if (!offscreenBuffer) colorTarget = nullptr; changeSwapState(offscreenBuffer ? SWP_DELAYED_ACQUIRE : SWP_EARLY_ACQUIRE); - -#if _TARGET_ANDROID - // only Android 10+ trigger suboptimals, on others we must poll (or do other stuff) - if (preRotation) - { - ++surfaceRotationPolling; - if ((surfaceRotationPolling % SURFACE_ROTATION_POLLING_INTERVAL) == 0 && preRotationProcessed && !is_null(activeMode.surface)) - { - VkSurfaceCapabilitiesKHR caps = querySurfaceCaps(); - if (preRotationAngle != surfaceTransformToAngle(caps.currentTransform)) - { - // should be ok to just drop into headless - destroyOffscreenBuffer(ctx.back.contextState.frame.get()); - changeSwapState(SWP_HEADLESS); - } - } - } -#endif } else { diff --git a/prog/engine/drv/drv3d_vulkan/swapchain.h b/prog/engine/drv/drv3d_vulkan/swapchain.h index 204776dbf..5823d0138 100644 --- a/prog/engine/drv/drv3d_vulkan/swapchain.h +++ b/prog/engine/drv/drv3d_vulkan/swapchain.h @@ -131,6 +131,9 @@ class Swapchain bool swappyInitialized = false; #endif + // saved global configuration + bool reuseHandle = true; + Image *offscreenBuffer = nullptr; Image *depthStencilImage = nullptr; Image *lastRenderedImage = nullptr; diff --git a/prog/engine/drv/drv3d_vulkan/temp_buffers.cpp b/prog/engine/drv/drv3d_vulkan/temp_buffers.cpp index 28e2fc3fa..8a07376ab 100644 --- a/prog/engine/drv/drv3d_vulkan/temp_buffers.cpp +++ b/prog/engine/drv/drv3d_vulkan/temp_buffers.cpp @@ -20,7 +20,7 @@ BufferSubAllocation TempBufferManager::allocate(Device &device, uint32_t unalign auto ref = eastl::find_if(begin(buffers), end(buffers), [=](const TempBufferInfo &info) // { - auto space = info.buffer->dataSize() - info.fill; + auto space = info.buffer->getBlockSize() - info.fill; return space >= size; }); if (ref == end(buffers)) diff --git a/prog/engine/drv/drv3d_vulkan/temp_buffers.h b/prog/engine/drv/drv3d_vulkan/temp_buffers.h index c3cfff844..c08e2a8da 100644 --- a/prog/engine/drv/drv3d_vulkan/temp_buffers.h +++ b/prog/engine/drv/drv3d_vulkan/temp_buffers.h @@ -108,7 +108,7 @@ class TempBufferHolder void flushWrite() { - subAlloc.buffer->markNonCoherentRange(dataOffset(), subAlloc.size, true); + subAlloc.buffer->markNonCoherentRangeLoc(subAlloc.offset, subAlloc.size, true); #if DAGOR_DBGLEVEL > 0 writesFlushed = true; #endif @@ -116,9 +116,9 @@ class TempBufferHolder const BufferSubAllocation &get() { return subAlloc; } - uint32_t dataOffset() { return subAlloc.buffer->dataOffset(subAlloc.offset); } + uint32_t bufOffset() { return subAlloc.buffer->bufOffsetLoc(subAlloc.offset); } - void *getPtr() { return subAlloc.buffer->dataPointer(subAlloc.offset); } + void *getPtr() { return subAlloc.buffer->ptrOffsetLoc(subAlloc.offset); } }; } // namespace drv3d_vulkan diff --git a/prog/engine/drv/drv3d_vulkan/texture.cpp b/prog/engine/drv/drv3d_vulkan/texture.cpp index 4b8460c8a..6ae5edbf3 100644 --- a/prog/engine/drv/drv3d_vulkan/texture.cpp +++ b/prog/engine/drv/drv3d_vulkan/texture.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include <3d/ddsFormat.h> #include @@ -42,83 +43,6 @@ using namespace drv3d_vulkan; namespace { - -uint32_t texfmt_to_d3dformat(/*D3DFORMAT*/ uint32_t fmt) -{ - switch (fmt) - { - case TEXFMT_DEFAULT: return drv3d_vulkan::D3DFMT_A8R8G8B8; - case TEXFMT_R8G8B8A8: return drv3d_vulkan::D3DFMT_A8B8G8R8; - case TEXFMT_A2B10G10R10: return drv3d_vulkan::D3DFMT_A2B10G10R10; - case TEXFMT_A16B16G16R16: return drv3d_vulkan::D3DFMT_A16B16G16R16; - case TEXFMT_A16B16G16R16F: return drv3d_vulkan::D3DFMT_A16B16G16R16F; - case TEXFMT_A32B32G32R32F: return drv3d_vulkan::D3DFMT_A32B32G32R32F; - case TEXFMT_G16R16: return drv3d_vulkan::D3DFMT_G16R16; - case TEXFMT_V16U16: return drv3d_vulkan::D3DFMT_V16U16; - case TEXFMT_L16: return drv3d_vulkan::D3DFMT_L16; - case TEXFMT_A8: return drv3d_vulkan::D3DFMT_A8; - case TEXFMT_R8: return drv3d_vulkan::D3DFMT_L8; - case TEXFMT_A8L8: return drv3d_vulkan::D3DFMT_A8L8; - case TEXFMT_G16R16F: return drv3d_vulkan::D3DFMT_G16R16F; - case TEXFMT_G32R32F: return drv3d_vulkan::D3DFMT_G32R32F; - case TEXFMT_R16F: return drv3d_vulkan::D3DFMT_R16F; - case TEXFMT_R32F: return drv3d_vulkan::D3DFMT_R32F; - case TEXFMT_DXT1: return drv3d_vulkan::D3DFMT_DXT1; - case TEXFMT_DXT3: return drv3d_vulkan::D3DFMT_DXT3; - case TEXFMT_DXT5: return drv3d_vulkan::D3DFMT_DXT5; - case TEXFMT_A4R4G4B4: return drv3d_vulkan::D3DFMT_A4R4G4B4; // dxgi 1.2 - case TEXFMT_A1R5G5B5: return drv3d_vulkan::D3DFMT_A1R5G5B5; - case TEXFMT_R5G6B5: return drv3d_vulkan::D3DFMT_R5G6B5; - case TEXFMT_ATI1N: return _MAKE4C('ATI1'); - case TEXFMT_ATI2N: return _MAKE4C('ATI2'); - } - G_ASSERTF(0, "can't convert tex format: %d", fmt); - return drv3d_vulkan::D3DFMT_A8R8G8B8; -} - -uint32_t auto_mip_levels_count(uint32_t w, uint32_t h, uint32_t mnsz) -{ - uint32_t lev = 1; - while (w > mnsz && h > mnsz) - { - lev++; - w >>= 1; - h >>= 1; - } - return lev; -} - -eastl::tuple fixup_tex_params(int w, int h, int32_t flg, int levels) -{ - const bool rt = 0 == (TEXCF_RTARGET & flg); - auto fmt = TEXFMT_MASK & flg; - - if (rt) - { - if (0 != (TEXCF_SRGBWRITE & flg)) - { - if ((TEXFMT_A8R8G8B8 != fmt)) - { - // TODO verify this requirement - if (0 != (TEXCF_SRGBREAD & flg)) - { - debug("vulkan: Adding TEXCF_SRGBREAD to texture flags, because chosen format needs it"); - flg |= TEXCF_SRGBREAD; - } - } - } - } - - if (0 == levels) - { - levels = auto_mip_levels_count(w, h, rt ? 1 : 4); - debug("vulkan: Auto compute for texture mip levels yielded %d", levels); - } - - // update format info if it had changed - return eastl::make_tuple((flg & ~TEXFMT_MASK) | fmt, levels); -} - bool create_tex2d(BaseTex::D3DTextures &tex, BaseTex *bt_in, uint32_t w, uint32_t h, uint32_t levels, bool cube, BaseTex::ImageMem *initial_data, int array_size = 1, bool temp_alloc = false) { @@ -210,12 +134,12 @@ bool create_tex2d(BaseTex::D3DTextures &tex, BaseTex *bt_in, uint32_t w, uint32_ { BaseTex::ImageMem &src = initial_data[desc.mips * i + j]; VkBufferImageCopy © = copies[j]; - copy = make_copy_info(desc.format, j, i, 1, {desc.size.width, desc.size.height, 1}, tex.stagingBuffer->dataOffset(offset)); + copy = make_copy_info(desc.format, j, i, 1, {desc.size.width, desc.size.height, 1}, tex.stagingBuffer->bufOffsetLoc(offset)); - memcpy(tex.stagingBuffer->dataPointer(offset), src.ptr, src.memSize); + memcpy(tex.stagingBuffer->ptrOffsetLoc(offset), src.ptr, src.memSize); offset += src.memSize; } - tex.stagingBuffer->markNonCoherentRange(flushStart, offset - flushStart, true); + tex.stagingBuffer->markNonCoherentRangeLoc(flushStart, offset - flushStart, true); device.getContext().copyBufferToImage(tex.stagingBuffer, tex.image, desc.mips, copies.data(), true); } @@ -252,16 +176,16 @@ bool create_tex2d(BaseTex::D3DTextures &tex, BaseTex *bt_in, uint32_t w, uint32_ if (tempStage) tex.useStaging(desc.format, desc.size.width, desc.size.height, desc.size.depth, 1, 1, true); - uint32_t size = tex.stagingBuffer->dataSize(); - memset(tex.stagingBuffer->dataPointer(0), 0, size); - tex.stagingBuffer->markNonCoherentRange(0, size, true); + uint32_t size = tex.stagingBuffer->getBlockSize(); + memset(tex.stagingBuffer->ptrOffsetLoc(0), 0, size); + tex.stagingBuffer->markNonCoherentRangeLoc(0, size, true); carray copies; for (uint32_t i = 0; i < desc.arrays; ++i) { for (uint32_t j = 0; j < desc.mips; ++j) - copies[j] = make_copy_info(desc.format, j, i, 1, {desc.size.width, desc.size.height, 1}, tex.stagingBuffer->dataOffset(0)); + copies[j] = make_copy_info(desc.format, j, i, 1, {desc.size.width, desc.size.height, 1}, tex.stagingBuffer->bufOffsetLoc(0)); device.getContext().copyBufferToImage(tex.stagingBuffer, tex.image, desc.mips, copies.data(), false); } @@ -353,13 +277,13 @@ bool create_tex3d(BaseTex::D3DTextures &tex, BaseTex *bt_in, uint32_t w, uint32_ { VkBufferImageCopy © = copies[j]; copy = - make_copy_info(desc.format, j, 0, 1, {desc.size.width, desc.size.height, desc.size.depth}, stage->dataOffset(bufferOffset)); + make_copy_info(desc.format, j, 0, 1, {desc.size.width, desc.size.height, desc.size.depth}, stage->bufOffsetLoc(bufferOffset)); uint32_t imgSize = desc.format.calculateImageSize(copy.imageExtent.width, copy.imageExtent.height, copy.imageExtent.depth, 1); - memcpy(stage->dataPointer(bufferOffset), initial_data[j].ptr, imgSize); + memcpy(stage->ptrOffsetLoc(bufferOffset), initial_data[j].ptr, imgSize); bufferOffset += imgSize; } - stage->markNonCoherentRange(0, size, true); + stage->markNonCoherentRangeLoc(0, size, true); device.getContext().copyBufferToImage(stage, tex.image, levels, copies.data(), true); device.getContext().destroyBuffer(stage); } @@ -388,12 +312,12 @@ bool create_tex3d(BaseTex::D3DTextures &tex, BaseTex *bt_in, uint32_t w, uint32_ uint32_t size = desc.format.calculateImageSize(desc.size.width, desc.size.height, desc.size.depth, 1); auto stage = device.createBuffer(size, DeviceMemoryClass::HOST_RESIDENT_HOST_READ_WRITE_BUFFER, 1, BufferMemoryFlags::TEMP); stage->setStagingDebugName(tex.image); - memset(stage->dataPointer(0), 0, size); - stage->markNonCoherentRange(0, size, true); + memset(stage->ptrOffsetLoc(0), 0, size); + stage->markNonCoherentRangeLoc(0, size, true); carray copies; for (uint32_t j = 0; j < levels; ++j) - copies[j] = make_copy_info(desc.format, j, 0, 1, {desc.size.width, desc.size.height, desc.size.depth}, stage->dataOffset(0)); + copies[j] = make_copy_info(desc.format, j, 0, 1, {desc.size.width, desc.size.height, desc.size.depth}, stage->bufOffsetLoc(0)); device.getContext().copyBufferToImage(stage, tex.image, levels, copies.data(), false); device.getContext().destroyBuffer(stage); @@ -712,8 +636,6 @@ int BaseTex::generateMips() return 1; } -static constexpr int TEX_COPIED = 1 << 30; - void BaseTex::D3DTextures::useStaging(FormatStore fmt, int32_t w, int32_t h, int32_t d, int32_t levels, uint16_t arrays, bool temporary /*=false*/) { @@ -909,7 +831,7 @@ int BaseTex::lockimg(void **p, int &stride, int lev, unsigned flags) for (uint32_t j = 0; j < mipLevels; ++j) { VkBufferImageCopy © = copies[j]; - copy = make_copy_info(getFormat(), j, 0, layers, {width, height, 1}, tex.stagingBuffer->dataOffset(bufferOffset)); + copy = make_copy_info(getFormat(), j, 0, layers, {width, height, 1}, tex.stagingBuffer->bufOffsetLoc(bufferOffset)); bufferOffset += getFormat().calculateImageSize(copy.imageExtent.width, copy.imageExtent.height, copy.imageExtent.depth, 1) * layers; @@ -975,7 +897,7 @@ int BaseTex::lockimg(void **p, int &stride, int lev, unsigned flags) tex.useStaging(getFormat(), width, height, getDepthSlices(), mipLevels, getArrayCount(), stagingIsTemporary); } - lockMsr.ptr = tex.stagingBuffer->dataPointer(offset); + lockMsr.ptr = tex.stagingBuffer->ptrOffsetLoc(offset); lockMsr.rowPitch = getFormat().calculateRowPitch(max(width >> lev, 1)); lockMsr.slicePitch = getFormat().calculateSlicePich(max(width >> lev, 1), max(height >> lev, 1)); @@ -1004,7 +926,7 @@ int BaseTex::lockimg(void **p, int &stride, int lev, unsigned flags) waitEvent.reset(); } - tex.stagingBuffer->markNonCoherentRange(offset, lockMsr.slicePitch * getArrayCount(), false); + tex.stagingBuffer->markNonCoherentRangeLoc(offset, lockMsr.slicePitch * getArrayCount(), false); *p = lockMsr.ptr; stride = getFormat().calculateRowPitch(width >> lev); @@ -1032,11 +954,11 @@ int BaseTex::unlockimg() for (uint32_t j = 0; j < mipLevels; ++j) { VkBufferImageCopy © = copies[j]; - copy = make_copy_info(getFormat(), j, 0, 1, {width, height, depth}, tex.stagingBuffer->dataOffset(bufferOffset)); + copy = make_copy_info(getFormat(), j, 0, 1, {width, height, depth}, tex.stagingBuffer->bufOffsetLoc(bufferOffset)); bufferOffset += getFormat().calculateImageSize(copy.imageExtent.width, copy.imageExtent.height, copy.imageExtent.depth, 1); } - tex.stagingBuffer->markNonCoherentRange(0, bufferOffset, true); + tex.stagingBuffer->markNonCoherentRangeLoc(0, bufferOffset, true); get_device().getContext().copyBufferToImage(tex.stagingBuffer, tex.image, mipLevels, copies.data(), false); return 1; } @@ -1070,15 +992,17 @@ int BaseTex::unlockimg() if (lockFlags & TEXLOCK_DISCARD) { VkBufferImageCopy copy = - make_copy_info(getFormat(), lockedLevel, 0, 1, {width, height, depth}, tex.stagingBuffer->dataOffset(0)); + make_copy_info(getFormat(), lockedLevel, 0, 1, {width, height, depth}, tex.stagingBuffer->bufOffsetLoc(0)); uint32_t dirtySize = getFormat().calculateImageSize(copy.imageExtent.width, copy.imageExtent.height, copy.imageExtent.depth, 1); - tex.stagingBuffer->markNonCoherentRange(0, dirtySize, true); + tex.stagingBuffer->markNonCoherentRangeLoc(0, dirtySize, true); get_device().getContext().copyBufferToImageOrdered(tex.stagingBuffer, tex.image, 1, ©); tex.destroyStaging(); } - else if ((lockFlags & (TEXLOCK_RWMASK | TEXLOCK_UPDATEFROMSYSTEX)) != 0 && !(lockFlags & TEXLOCK_DONOTUPDATEON9EXBYDEFAULT)) + else if ((lockFlags & TEXLOCK_DONOTUPDATEON9EXBYDEFAULT) != 0) + unlockImageUploadSkipped = true; + else if ((lockFlags & (TEXLOCK_RWMASK | TEXLOCK_UPDATEFROMSYSTEX)) != 0) { carray copies; VkDeviceSize bufferOffset = 0; @@ -1086,17 +1010,26 @@ int BaseTex::unlockimg() for (uint32_t j = 0; j < mipLevels; ++j) { VkBufferImageCopy © = copies[j]; - copy = make_copy_info(getFormat(), j, 0, 1, {width, height, depth}, tex.stagingBuffer->dataOffset(bufferOffset)); + copy = make_copy_info(getFormat(), j, 0, 1, {width, height, depth}, tex.stagingBuffer->bufOffsetLoc(bufferOffset)); bufferOffset += getFormat().calculateImageSize(copy.imageExtent.width, copy.imageExtent.height, copy.imageExtent.depth, 1); } - tex.stagingBuffer->markNonCoherentRange(0, bufferOffset, true); - get_device().getContext().copyBufferToImage(tex.stagingBuffer, tex.image, mipLevels, copies.data(), false); + tex.stagingBuffer->markNonCoherentRangeLoc(0, bufferOffset, true); + // Sometimes we use TEXLOCK_DONOTUPDATEON9EXBYDEFAULT flag and don't copy locked subresource on unlock. + // Copy all mips is required after that action. + const eastl::span fullResource{copies.data(), mipLevels}; + const eastl::span oneSubresource{&copies[lockedLevel], 1}; + const auto uploadRegions = unlockImageUploadSkipped ? fullResource : oneSubresource; + get_device().getContext().copyBufferToImage(tex.stagingBuffer, tex.image, uploadRegions.size(), uploadRegions.data(), false); + unlockImageUploadSkipped = false; } } if ((lockFlags & TEXLOCK_DELSYSMEMCOPY) && !(cflg & TEXCF_DYNAMIC)) + { + G_ASSERT(!unlockImageUploadSkipped); tex.destroyStaging(); + } lockFlags = 0; return 1; @@ -1109,9 +1042,9 @@ int BaseTex::unlockimg() if (lockFlags & TEXLOCK_WRITE) { VkBufferImageCopy copy = - make_copy_info(getFormat(), lockedLevel, lockedLayer, 1, {width, height, 1}, tex.stagingBuffer->dataOffset(0)); + make_copy_info(getFormat(), lockedLevel, lockedLayer, 1, {width, height, 1}, tex.stagingBuffer->bufOffsetLoc(0)); - tex.stagingBuffer->markNonCoherentRange(0, tex.stagingBuffer->dataSize(), true); + tex.stagingBuffer->markNonCoherentRangeLoc(0, tex.stagingBuffer->getBlockSize(), true); context.copyBufferToImage(tex.stagingBuffer, tex.image, 1, ©, false); } tex.destroyStaging(); @@ -1152,7 +1085,7 @@ int BaseTex::lockimg(void **p, int &stride, int face, int lev, unsigned flags) tex.useStaging(format, levelWidth, levelHeight, 1, 1, 1, true); if (flags & TEXLOCK_READ) { - VkBufferImageCopy copy = make_copy_info(format, lev, face, 1, {width, height, 1}, tex.stagingBuffer->dataOffset(0)); + VkBufferImageCopy copy = make_copy_info(format, lev, face, 1, {width, height, 1}, tex.stagingBuffer->bufOffsetLoc(0)); if (p) { @@ -1174,8 +1107,8 @@ int BaseTex::lockimg(void **p, int &stride, int face, int lev, unsigned flags) context.wait(); waitEvent.reset(); - tex.stagingBuffer->markNonCoherentRange(0, tex.stagingBuffer->dataSize(), false); - *p = tex.stagingBuffer->dataPointer(0); + tex.stagingBuffer->markNonCoherentRangeLoc(0, tex.stagingBuffer->getBlockSize(), false); + *p = tex.stagingBuffer->ptrOffsetLoc(0); stride = format.calculateRowPitch(levelWidth); } } @@ -1211,16 +1144,16 @@ int BaseTex::lockbox(void **data, int &row_pitch, int &slice_pitch, int level, u // only get a buffer large enough to hold the locked level tex.useStaging(format, levelWidth, levelHeight, levelDepth, 1, 1, true); - *data = tex.stagingBuffer->dataPointer(0); + *data = tex.stagingBuffer->ptrOffsetLoc(0); if (flags & TEXLOCK_READ) { - VkBufferImageCopy copy = make_copy_info(format, level, 0, 1, {width, height, depth}, tex.stagingBuffer->dataOffset(0)); + VkBufferImageCopy copy = make_copy_info(format, level, 0, 1, {width, height, depth}, tex.stagingBuffer->bufOffsetLoc(0)); context.copyImageToBuffer(tex.image, tex.stagingBuffer, 1, ©, nullptr); blockingReadbackWait(); - tex.stagingBuffer->markNonCoherentRange(0, tex.stagingBuffer->dataSize(), false); + tex.stagingBuffer->markNonCoherentRangeLoc(0, tex.stagingBuffer->getBlockSize(), false); } row_pitch = format.calculateRowPitch(levelWidth); slice_pitch = format.calculateSlicePich(levelWidth, levelHeight); @@ -1281,9 +1214,9 @@ int BaseTex::unlockbox() if (lockFlags & TEXLOCK_WRITE) { VkBufferImageCopy copy = - make_copy_info(getFormat(), lockedLevel, 0, 1, {width, height, depth}, tex.stagingBuffer->dataOffset(0)); + make_copy_info(getFormat(), lockedLevel, 0, 1, {width, height, depth}, tex.stagingBuffer->bufOffsetLoc(0)); - tex.stagingBuffer->markNonCoherentRange(0, tex.stagingBuffer->dataSize(), true); + tex.stagingBuffer->markNonCoherentRangeLoc(0, tex.stagingBuffer->getBlockSize(), true); context.copyBufferToImage(tex.stagingBuffer, tex.image, 1, ©, false); } @@ -1313,7 +1246,7 @@ Texture *d3d::create_tex(TexImage32 *img, int w, int h, int flg, int levels, con w = clamp(w, dd.mintexw, dd.maxtexw); h = clamp(h, dd.mintexh, dd.maxtexh); - eastl::tie(flg, levels) = fixup_tex_params(w, h, flg, levels); + eastl::tie(flg, levels) = add_srgb_read_flag_and_count_mips(w, h, flg, levels); if (img) { @@ -1422,7 +1355,7 @@ CubeTexture *d3d::create_cubetex(int size, int flg, int levels, const char *stat const Driver3dDesc &dd = d3d::get_driver_desc(); size = get_bigger_pow2(clamp(size, dd.mincubesize, dd.maxcubesize)); - eastl::tie(flg, levels) = fixup_tex_params(size, size, flg, levels); + eastl::tie(flg, levels) = add_srgb_read_flag_and_count_mips(size, size, flg, levels); auto tex = allocate_texture(RES3D_CUBETEX, flg); tex->setParams(size, size, 1, levels, stat_name); @@ -1443,7 +1376,7 @@ VolTexture *d3d::create_voltex(int w, int h, int d, int flg, int levels, const c return nullptr; } - eastl::tie(flg, levels) = fixup_tex_params(w, h, flg, levels); + eastl::tie(flg, levels) = add_srgb_read_flag_and_count_mips(w, h, flg, levels); auto tex = allocate_texture(RES3D_VOLTEX, flg); tex->setParams(w, h, d, levels, stat_name); @@ -1485,7 +1418,7 @@ VolTexture *d3d::create_voltex(int w, int h, int d, int flg, int levels, const c ArrayTexture *d3d::create_array_tex(int w, int h, int d, int flg, int levels, const char *stat_name) { - eastl::tie(flg, levels) = fixup_tex_params(w, h, flg, levels); + eastl::tie(flg, levels) = add_srgb_read_flag_and_count_mips(w, h, flg, levels); auto tex = allocate_texture(RES3D_ARRTEX, flg); tex->setParams(w, h, d, levels, stat_name); @@ -1500,7 +1433,7 @@ ArrayTexture *d3d::create_array_tex(int w, int h, int d, int flg, int levels, co ArrayTexture *d3d::create_cube_array_tex(int side, int d, int flg, int levels, const char *stat_name) { - eastl::tie(flg, levels) = fixup_tex_params(side, side, flg, levels); + eastl::tie(flg, levels) = add_srgb_read_flag_and_count_mips(side, side, flg, levels); auto tex = allocate_texture(RES3D_ARRTEX, flg); tex->setParams(side, side, d, levels, stat_name); diff --git a/prog/engine/drv/drv3d_vulkan/texture.h b/prog/engine/drv/drv3d_vulkan/texture.h index e125c168d..714791234 100644 --- a/prog/engine/drv/drv3d_vulkan/texture.h +++ b/prog/engine/drv/drv3d_vulkan/texture.h @@ -200,6 +200,7 @@ struct BaseTex final : public BaseTexture bool delayedCreate = false; bool preallocBeforeLoad = false; bool isArrayCube = false; + bool unlockImageUploadSkipped = false; uint16_t width = 0; uint16_t height = 0; diff --git a/prog/engine/drv/drv3d_vulkan/vulkan.cpp b/prog/engine/drv/drv3d_vulkan/vulkan.cpp index 95f681147..9b91967d0 100644 --- a/prog/engine/drv/drv3d_vulkan/vulkan.cpp +++ b/prog/engine/drv/drv3d_vulkan/vulkan.cpp @@ -857,7 +857,7 @@ bool d3d::init_video(void *hinst, main_wnd_f *wnd_proc, const char *wcname, int } api_state.adjustCaps(); - api_state.shaderProgramDatabase.init(api_state.device.getContext()); + api_state.shaderProgramDatabase.init(api_state.driverDesc.caps.hasBindless, api_state.device.getContext()); { // vulkan have limited memory swapping support now @@ -1265,14 +1265,6 @@ int d3d::driver_command(int command, void *par1, void *par2, void *par3) // case DRV3D_COMMAND_GET_SECONDARY_BACKBUFFER: // break; case DRV3D_COMMAND_GET_VENDOR: return drv3d_vulkan::api_state.device.getDeviceVendor(); break; - case DRV3D_COMMAND_GET_RESOLUTION: - if (par1 && par2) - { - *((int *)par1) = api_state.windowState.settings.resolutionX; - *((int *)par2) = api_state.windowState.settings.resolutionY; - return 1; - } - break; case DRV3D_COMMAND_GET_FRAMERATE_LIMITING_FACTOR: { return api_state.lastLimitingFactor; @@ -2296,7 +2288,7 @@ void *d3d::fast_capture_screen(int &w, int &h, int &stride_bytes, int &format) device.getContext().captureScreen(api_state.screenCaptureStagingBuffer); device.getContext().wait(); - return api_state.screenCaptureStagingBuffer->dataPointer(0); + return api_state.screenCaptureStagingBuffer->ptrOffsetLoc(0); } void d3d::end_fast_capture_screen() diff --git a/prog/engine/drv/hid_nulldrv/ms_null.cpp b/prog/engine/drv/hid_nulldrv/ms_null.cpp index 71afeec27..bc3f29d0b 100644 --- a/prog/engine/drv/hid_nulldrv/ms_null.cpp +++ b/prog/engine/drv/hid_nulldrv/ms_null.cpp @@ -59,3 +59,5 @@ IGenPointingClassDrv *HumanInput::createNullMouseClassDriver() memset(&raw_state_pnt, 0, sizeof(raw_state_pnt)); return &drv; } + +void mouse_api_SetFullscreenMode(int, int) {} diff --git a/prog/engine/drv/vr_device/screenMask.sh b/prog/engine/drv/vr_device/screenMask.dshl similarity index 94% rename from prog/engine/drv/vr_device/screenMask.sh rename to prog/engine/drv/vr_device/screenMask.dshl index f27970c55..4e1195ca9 100644 --- a/prog/engine/drv/vr_device/screenMask.sh +++ b/prog/engine/drv/vr_device/screenMask.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" shader openxr_screen_mask { diff --git a/prog/engine/gameRes/animCharGameRes.cpp b/prog/engine/gameRes/animCharGameRes.cpp index 312163648..5a1acc38a 100644 --- a/prog/engine/gameRes/animCharGameRes.cpp +++ b/prog/engine/gameRes/animCharGameRes.cpp @@ -204,6 +204,7 @@ class AnimCharGameResFactory final : public GameResourceFactory eastl::vector resData; Tab gameRes; + bool warnAboutMissingAnimRes = true; int findResData(int res_id) const @@ -422,7 +423,7 @@ class AnimCharGameResFactory final : public GameResourceFactory { int res_id_ = ref_ids[i]; a2d_list[i] = (AnimV20::AnimData *)::get_game_resource(res_id_); - G_ASSERTF(!(i == 0 && !a2d_list[i] && is_ignoring_unavailable_resources()), + G_ASSERTF(!(i == 0 && !a2d_list[i] && is_ignoring_unavailable_resources()) || !warnAboutMissingAnimRes, "%s can't load animation #0 to ignore unavailable resources (see log)", __FUNCTION__); if (!a2d_list[i] && is_ignoring_unavailable_resources() && i) { @@ -431,7 +432,7 @@ class AnimCharGameResFactory final : public GameResourceFactory nodesWithIgnoredAnimation.push_back(i); } #if DAGOR_DBGLEVEL > 0 - if (!a2d_list[i]) + if (!a2d_list[i] && warnAboutMissingAnimRes) { String res_name; get_game_resource_name(res_id_, res_name); @@ -477,15 +478,15 @@ class AnimCharGameResFactory final : public GameResourceFactory IMPLEMENT_DUMP_RESOURCES_REF_COUNT(gameRes, resId, refCount) }; - static InitOnDemand char_factory; static InitOnDemand bnl_factory; -void register_animchar_gameres_factory() +void register_animchar_gameres_factory(bool warn_about_missing_anim) { bnl_factory.demandInit(); ::add_factory(bnl_factory); char_factory.demandInit(); + char_factory->warnAboutMissingAnimRes = warn_about_missing_anim; ::add_factory(char_factory); } diff --git a/prog/engine/gameRes/gameResSystem.cpp b/prog/engine/gameRes/gameResSystem.cpp index dae01d5bb..dcb0bdc21 100644 --- a/prog/engine/gameRes/gameResSystem.cpp +++ b/prog/engine/gameRes/gameResSystem.cpp @@ -730,7 +730,16 @@ bool GameResPackInfo::processGrData() sleep_msec(0); gameres_cs.reLock(cnt); } - G_ASSERTF_BREAK(grData, "grData unexpectedly became %p", grData); + + if (!grData) + { + if (is_ignoring_unavailable_resources()) + { + debug("grData became NULL"); + break; + } + G_ASSERTF_BREAK(grData, "grData unexpectedly became %p", grData); + } } debug_ctx("processed data from GRP %s", (char *)fileName); @@ -1142,7 +1151,14 @@ void load_game_resource_pack(int res_id) if (resRestrictionList.size() && !resRestrictionList.get(res_id)) { - logerr("res_id=%d <%s> is not present in res restriction list", res_id, resNameMap.getName(res_id)); + String logStr(120, "res_id=%d <%s> is not present in res restriction list", res_id, resNameMap.getName(res_id)); + if (::is_ignoring_unavailable_resources()) + { + debug("%s - skip resPackId:%i", logStr.c_str(), resPackId); + resPackId = -1; + } + else + logerr(logStr.c_str()); resRestrictionList.set(res_id); // for the case when we ignore next fatal in fatal handler resRestrictionList.set(grMap[info->grMapIdx].id.resId); clearLoadedPacksList(); diff --git a/prog/engine/imgui/imgui.sh b/prog/engine/imgui/imgui.dshl similarity index 97% rename from prog/engine/imgui/imgui.sh rename to prog/engine/imgui/imgui.dshl index a7f7d1772..35e34d397 100644 --- a/prog/engine/imgui/imgui.sh +++ b/prog/engine/imgui/imgui.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" float4 imgui_mvp_0; float4 imgui_mvp_1; diff --git a/prog/engine/ioSys/dataBlock/blk_to_json.cpp b/prog/engine/ioSys/dataBlock/blk_to_json.cpp index effb92b66..5b8a3e3b6 100644 --- a/prog/engine/ioSys/dataBlock/blk_to_json.cpp +++ b/prog/engine/ioSys/dataBlock/blk_to_json.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include // sprintf namespace diff --git a/prog/engine/kernel/dagorHwExcept.cpp b/prog/engine/kernel/dagorHwExcept.cpp index 470dd6c99..682bc2d85 100644 --- a/prog/engine/kernel/dagorHwExcept.cpp +++ b/prog/engine/kernel/dagorHwExcept.cpp @@ -5,11 +5,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -21,47 +23,217 @@ #include "debugPrivate.h" #include -static constexpr int EXCEPT_BUF_SZ = 2048; +#pragma comment(lib, "shlwapi.lib") +static constexpr int EXCEPT_BUF_SZ = 2048; static char common_buf[EXCEPT_BUF_SZ]; +const uintptr_t REGS_DUMP_MEMORY_FORWARD = 224; +const uintptr_t REGS_DUMP_MEMORY_BACK = 32; +const uintptr_t REGS_PTR_DUMP_SIZE = sizeof(uintptr_t) * 10; +const uintptr_t PTR_DUMP_SIZE = sizeof(uintptr_t) * 6; +const uintptr_t REG_SCAN_PTR_DATA_SIZE = sizeof(uintptr_t) * 16; +const uintptr_t STACK_SCAN_PTR_DATA_SIZE = sizeof(uintptr_t) * 6; +const uintptr_t MAX_VECTOR_ELEMENTS = 1024; +const uintptr_t VECTOR_PTR_DUMP_SIZE = 1024; +const uintptr_t VECTOR_MAX_ELEM_SIZE = 96; // enough for phys contacts data +const uintptr_t STRIPPED_STACK_SIZE = 256; + +struct MemoryRange +{ + uintptr_t from = 0; + uintptr_t to = 0; + bool contain(uint64_t addr) const { return addr >= from && addr < to; } +}; + +struct MinidumpThreadData +{ + uintptr_t threadId = 0; + bool needScanMem = false; + uint32_t scannedRegs = 0; +#if _TARGET_64BIT + static const uint32_t regsCount = 16; +#else + static const uint32_t regsCount = 7; +#endif + uintptr_t regs[16]{}; + uintptr_t stackPtr = 0; + MemoryRange stack; + + void setRegisters(const CONTEXT &ctx) + { +#if _TARGET_64BIT + stackPtr = ctx.Rsp; + const int64_t *regsSrc = (int64_t *)&ctx.Rax; +#else + stackPtr = ctx.Esp; + const int32_t *regsSrc = (int32_t *)&ctx.Edi; +#endif + for (uint32_t i = 0; i < regsCount; i++) + regs[i] = regsSrc[i]; + } +}; + struct MinidumpExceptionData { PMINIDUMP_EXCEPTION_INFORMATION excInfo = nullptr; - uint64_t stackBase = 0; // crashed thread - uint64_t stackEnd = 0; - uint64_t baseOfImage = 0; // module containing this file - uint64_t endOfImage = 0; - int scannedRegs = 0; + MinidumpThreadData excThread; + MinidumpThreadData mainThread; + MemoryRange image; // main module containing this file + MemoryRange code; + + MemoryRange ntdll; + MemoryRange user32; + MemoryRange kernel32; + MemoryRange kernelBase; + MemoryRange videoDriver; + + uint32_t memAddQueueSize = 0; + MemoryRange memAddQueue[16]; + uint32_t memRemoveQueueSize = 0; + MemoryRange memRemoveQueue[128]; +}; - struct MemoryRange +static BOOL get_vector_at_addr(uintptr_t addr, uintptr_t end, uint32_t &out_vector_size, uint32_t &out_data_size) +{ + struct DagVectorData // das::Array has same layout { - uint64_t base; + uintptr_t data; uint32_t size; + uint32_t capacity; + bool validateCounters() const { return size > 0 && size <= capacity && capacity <= MAX_VECTOR_ELEMENTS; } }; - uint32_t memRemoveQueueSize = 0; - MemoryRange memRemoveQueue[32]{}; -}; + const DagVectorData *dv = (const DagVectorData *)addr; + if (addr + sizeof(DagVectorData) <= end && dv->validateCounters()) + { + out_vector_size = sizeof(DagVectorData); + out_data_size = min(VECTOR_PTR_DUMP_SIZE, dv->size * VECTOR_MAX_ELEM_SIZE); + return TRUE; + } + + struct DagVectorWithAllocData + { + uintptr_t data; + uintptr_t allocator; + uint32_t size; + uint32_t capacity; + bool validateCounters() const { return size > 0 && size <= capacity && capacity <= MAX_VECTOR_ELEMENTS; } + }; + const DagVectorWithAllocData *va = (const DagVectorWithAllocData *)addr; + if (addr + sizeof(DagVectorWithAllocData) <= end && va->validateCounters()) + { + out_vector_size = sizeof(DagVectorWithAllocData); + out_data_size = min(VECTOR_PTR_DUMP_SIZE, va->size * VECTOR_MAX_ELEM_SIZE); + return TRUE; + } + + struct EastlVectorData + { + uintptr_t data; + uintptr_t end; + uintptr_t capacityEnd; + bool validateCounters() const { return data < end && end <= capacityEnd && capacityEnd - data < 10000; } + }; + const EastlVectorData *ev = (const EastlVectorData *)addr; + if (addr + sizeof(EastlVectorData) <= end && ev->validateCounters()) + { + out_vector_size = sizeof(EastlVectorData); + out_data_size = min(VECTOR_PTR_DUMP_SIZE, ev->end - ev->data); + return TRUE; + } + + return FALSE; +} + +static BOOL get_memory_range_for_dump(uintptr_t addr, uintptr_t bytes_fwd, uintptr_t bytes_back, const MinidumpExceptionData *data, + MemoryRange &range, bool &is_rw_data) +{ + if (addr < 0x100000 || uint64_t(addr) >> 48 || int32_t(addr) == -1) + return FALSE; + if (data->excThread.stack.contain(addr) || data->mainThread.stack.contain(addr)) + return FALSE; + if (data->code.contain(addr)) // exclude game code (assume it's not changed) + return FALSE; + if (data->ntdll.contain(addr) || data->user32.contain(addr) || data->kernel32.contain(addr) || data->kernelBase.contain(addr)) + return FALSE; + if (data->videoDriver.contain(addr)) + return FALSE; + MEMORY_BASIC_INFORMATION mem; + if (VirtualQuery((void *)addr, &mem, sizeof(mem)) && mem.State & MEM_COMMIT) + { + if (mem.Protect == PAGE_READONLY && data->image.contain(addr)) // exclude known constants + return FALSE; + uintptr_t start = max(addr - bytes_back, (uintptr_t)mem.BaseAddress); + uintptr_t end = min(addr + bytes_fwd, (uintptr_t)mem.BaseAddress + (uintptr_t)mem.RegionSize); + if (addr >= start && addr < end) + { + range.from = start; + range.to = end; + is_rw_data = mem.Protect == PAGE_READWRITE; + return TRUE; + } + } + return FALSE; +} static BOOL dump_memory(uintptr_t addr, uintptr_t bytes_fwd, uintptr_t bytes_back, MinidumpExceptionData *data, - PMINIDUMP_CALLBACK_OUTPUT callback_output) + PMINIDUMP_CALLBACK_OUTPUT callback_output, uint32_t scan_ptr_data_size, uint32_t scan_ptr_dump_len) +{ + MemoryRange range; + bool isRwData = false; + if (get_memory_range_for_dump(addr, bytes_fwd, bytes_back, data, range, isRwData)) + { + callback_output->MemoryBase = int64_t(intptr_t(range.from)); // sign extend for win32 + callback_output->MemorySize = ULONG(range.to - range.from); + if (isRwData && !(addr & sizeof(uintptr_t) - 1)) + { + uintptr_t end = min(addr + scan_ptr_data_size, range.to); + for (uintptr_t m = addr; m < end; m += sizeof(uintptr_t)) + { + uintptr_t dumpPtr = *(uintptr_t *)m; + uint32_t dumpLen = scan_ptr_dump_len; + uint32_t vectorSize = 0; + if (get_vector_at_addr(m, end, vectorSize, dumpLen)) + vectorSize -= sizeof(uintptr_t); + if (get_memory_range_for_dump(dumpPtr, dumpLen, 0, data, range, isRwData)) + { + m += vectorSize; // skip vector if pointer valid + if (data->memAddQueueSize >= countof(data->memAddQueue)) + { + logerr("memAddQueue overflow (%i)", countof(data->memAddQueue)); + break; + } + data->memAddQueue[data->memAddQueueSize++] = range; + } + } + } + return TRUE; + } + return FALSE; +} + +static BOOL dump_thread_memory(MinidumpExceptionData *data, MinidumpThreadData &thread, PMINIDUMP_CALLBACK_OUTPUT callback_output) { - bool isStack = addr >= data->stackEnd && addr < data->stackBase; - bool isInGameModule = addr >= data->baseOfImage && addr < data->endOfImage; - if (addr > 0x100000 && !(uint64_t(addr) >> 48) && !isStack) + while (thread.scannedRegs < thread.regsCount) { - MEMORY_BASIC_INFORMATION mem; - if (VirtualQuery((void *)addr, &mem, sizeof(mem))) + uintptr_t regValue = thread.regs[thread.scannedRegs++]; + if (dump_memory(regValue, REGS_DUMP_MEMORY_FORWARD, REGS_DUMP_MEMORY_BACK, data, callback_output, REG_SCAN_PTR_DATA_SIZE, + REGS_PTR_DUMP_SIZE)) + return TRUE; + } + if (thread.stackPtr >= thread.stack.from) + { + while (thread.stackPtr < thread.stack.to) { - uintptr_t start = max(addr - bytes_back, (uintptr_t)mem.BaseAddress); - uintptr_t end = min(addr + bytes_fwd, (uintptr_t)mem.BaseAddress + (uintptr_t)mem.RegionSize); - const int dataProt = PAGE_READONLY | PAGE_READWRITE; - const int codeProt = PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE; - bool excludeAsKnownCode = (mem.Protect & codeProt) && isInGameModule; - if ((mem.State & MEM_COMMIT) && (mem.Protect & (dataProt | codeProt)) && !excludeAsKnownCode && end > start) + uintptr_t addr = *(uintptr_t *)thread.stackPtr; + uint32_t len = PTR_DUMP_SIZE; + uint32_t vectorSize = 0; + if (get_vector_at_addr(thread.stackPtr, thread.stack.to, vectorSize, len)) + vectorSize -= sizeof(uintptr_t); + thread.stackPtr += sizeof(uintptr_t); + if (dump_memory(addr, len, 0 /*back*/, data, callback_output, STACK_SCAN_PTR_DATA_SIZE, PTR_DUMP_SIZE)) { - callback_output->MemoryBase = int64_t(intptr_t(start)); - callback_output->MemorySize = end - start; + thread.stackPtr += vectorSize; // skip vector if .data valid return TRUE; } } @@ -71,19 +243,19 @@ static BOOL dump_memory(uintptr_t addr, uintptr_t bytes_fwd, uintptr_t bytes_bac static BOOL minidump_memory_callback(MinidumpExceptionData *data, PMINIDUMP_CALLBACK_OUTPUT callback_output) { -#if _TARGET_64BIT - const int regsToScan = 16; - const uint64_t *regsBase = (uint64_t *)&data->excInfo->ExceptionPointers->ContextRecord->Rax; -#else - const int regsToScan = 7; - const uint32_t *regsBase = (uint32_t *)&data->excInfo->ExceptionPointers->ContextRecord->Edi; -#endif - while (data->scannedRegs < regsToScan) + if (data->memAddQueueSize) { - uintptr_t regValue = regsBase[data->scannedRegs++]; - if (dump_memory(regValue, 128 /*fwd*/, 32 /*back*/, data, callback_output)) - return TRUE; + MemoryRange range = data->memAddQueue[--data->memAddQueueSize]; + callback_output->MemoryBase = int64_t(intptr_t(range.from)); + callback_output->MemorySize = ULONG(range.to - range.from); + G_ASSERT(callback_output->MemorySize > 0 && callback_output->MemorySize <= 1024); + return TRUE; } + if (data->excThread.needScanMem && dump_thread_memory(data, data->excThread, callback_output)) + return TRUE; + if (data->mainThread.needScanMem && dump_thread_memory(data, data->mainThread, callback_output)) + return TRUE; + G_ASSERT(!data->memAddQueueSize); return FALSE; } @@ -97,8 +269,38 @@ static BOOL CALLBACK minidump_callback(PVOID callback_param, const PMINIDUMP_CAL if (uint64_t(&minidump_callback) > callback_input->Module.BaseOfImage && uint64_t(&minidump_callback) < callback_input->Module.BaseOfImage + callback_input->Module.SizeOfImage) { - data->baseOfImage = callback_input->Module.BaseOfImage; - data->endOfImage = callback_input->Module.BaseOfImage + callback_input->Module.SizeOfImage; + data->image.from = callback_input->Module.BaseOfImage; + data->image.to = callback_input->Module.BaseOfImage + callback_input->Module.SizeOfImage; + + const IMAGE_DOS_HEADER *dos = (const IMAGE_DOS_HEADER *)data->image.from; + const IMAGE_NT_HEADERS *pe = (const IMAGE_NT_HEADERS *)((char *)data->image.from + dos->e_lfanew); + data->code.from = data->image.from + pe->OptionalHeader.BaseOfCode; + data->code.to = data->code.from + pe->OptionalHeader.SizeOfCode; + } + else if (StrStrIW(callback_input->Module.FullPath, L"ntdll.dll")) + { + data->ntdll.from = callback_input->Module.BaseOfImage; + data->ntdll.to = callback_input->Module.BaseOfImage + callback_input->Module.SizeOfImage; + } + else if (StrStrIW(callback_input->Module.FullPath, L"user32.dll")) + { + data->user32.from = callback_input->Module.BaseOfImage; + data->user32.to = callback_input->Module.BaseOfImage + callback_input->Module.SizeOfImage; + } + else if (StrStrIW(callback_input->Module.FullPath, L"kernel32.dll")) + { + data->kernel32.from = callback_input->Module.BaseOfImage; + data->kernel32.to = callback_input->Module.BaseOfImage + callback_input->Module.SizeOfImage; + } + else if (StrStrIW(callback_input->Module.FullPath, L"kernelbase.dll")) + { + data->kernelBase.from = callback_input->Module.BaseOfImage; + data->kernelBase.to = callback_input->Module.BaseOfImage + callback_input->Module.SizeOfImage; + } + else if (StrStrIW(callback_input->Module.FullPath, L"nvwgf2um") || StrStrIW(callback_input->Module.FullPath, L"atidxx")) + { + data->videoDriver.from = callback_input->Module.BaseOfImage; + data->videoDriver.to = callback_input->Module.BaseOfImage + callback_input->Module.SizeOfImage; } // Here is common filter effective in most cases, but I prefer to have full memory map // if (!(callback_output->ModuleWriteFlags & ModuleReferencedByMemory)) @@ -108,10 +310,12 @@ static BOOL CALLBACK minidump_callback(PVOID callback_param, const PMINIDUMP_CAL case IncludeThreadCallback: { bool saveStack = true; + bool allThreads = true; if (callback_input->IncludeThread.ThreadId == data->excInfo->ThreadId || callback_input->IncludeThread.ThreadId == get_main_thread_id() || - DaThread::isDaThreadWinUnsafe(callback_input->IncludeThread.ThreadId, saveStack)) + DaThread::isDaThreadWinUnsafe(callback_input->IncludeThread.ThreadId, saveStack) || allThreads) { + saveStack &= !is_watchdog_thread(callback_input->IncludeThread.ThreadId); callback_output->ThreadWriteFlags = ThreadWriteThread | ThreadWriteContext; if (saveStack) callback_output->ThreadWriteFlags |= ThreadWriteStack; @@ -127,9 +331,9 @@ static BOOL CALLBACK minidump_callback(PVOID callback_param, const PMINIDUMP_CAL case RemoveMemoryCallback: if (data->memRemoveQueueSize) { - MinidumpExceptionData::MemoryRange range = data->memRemoveQueue[--data->memRemoveQueueSize]; - callback_output->MemoryBase = range.base; - callback_output->MemorySize = range.size; + MemoryRange range = data->memRemoveQueue[--data->memRemoveQueueSize]; + callback_output->MemoryBase = int64_t(intptr_t(range.from)); + callback_output->MemorySize = ULONG(range.to - range.from); return TRUE; } return FALSE; @@ -138,25 +342,31 @@ static BOOL CALLBACK minidump_callback(PVOID callback_param, const PMINIDUMP_CAL case ThreadExCallback: if (callback_input->Thread.ThreadId == data->excInfo->ThreadId) { - data->stackBase = callback_input->Thread.StackBase; - data->stackEnd = callback_input->Thread.StackEnd; + data->excThread.stack.from = callback_input->Thread.StackEnd; + data->excThread.stack.to = callback_input->Thread.StackBase; + } + else if (callback_input->Thread.ThreadId == data->mainThread.threadId) + { + data->mainThread.stack.from = callback_input->Thread.StackEnd; + data->mainThread.stack.to = callback_input->Thread.StackBase; + data->mainThread.setRegisters(callback_input->Thread.Context); } if (!(callback_output->ThreadWriteFlags & ThreadWriteStack)) { // ThreadWriteContext saves stack, so we need to strip it manually #if _TARGET_64BIT - uint64_t sp = callback_input->Thread.Context.Rsp; + uintptr_t sp = callback_input->Thread.Context.Rsp; #else - uint64_t sp = int64_t(intptr_t(callback_input->Thread.Context.Esp)); + uintptr_t sp = int64_t(intptr_t(callback_input->Thread.Context.Esp)); #endif - uint64_t base = sp + 128; - uint32_t size = uint32_t(uintptr_t(callback_input->Thread.StackBase) - uintptr_t(base)); - if (int(size) > 0) + uintptr_t from = sp + STRIPPED_STACK_SIZE; + uintptr_t to = uintptr_t(callback_input->Thread.StackBase); + if (to > from) { if (data->memRemoveQueueSize < countof(data->memRemoveQueue)) - data->memRemoveQueue[data->memRemoveQueueSize++] = MinidumpExceptionData::MemoryRange{base, size}; + data->memRemoveQueue[data->memRemoveQueueSize++] = MemoryRange{from, to}; else - callback_output->ThreadWriteFlags = 0; + callback_output->ThreadWriteFlags = ThreadWriteThread; } } return TRUE; @@ -204,14 +414,18 @@ static void __cdecl hard_except_handler_named(EXCEPTION_POINTERS *eptr, char *bu if (INVALID_HANDLE_VALUE != hDumpFile) { MINIDUMP_EXCEPTION_INFORMATION minidumpExcInfo = {::GetCurrentThreadId(), eptr, FALSE}; - MINIDUMP_TYPE minidump_type = (MINIDUMP_TYPE)(MiniDumpScanMemory | MiniDumpWithIndirectlyReferencedMemory); MinidumpExceptionData param; param.excInfo = &minidumpExcInfo; + param.excThread.threadId = minidumpExcInfo.ThreadId; + param.excThread.needScanMem = !is_watchdog_thread(minidumpExcInfo.ThreadId); + param.excThread.setRegisters(*eptr->ContextRecord); + param.mainThread.threadId = get_main_thread_id(); + param.mainThread.needScanMem = param.mainThread.threadId != param.excThread.threadId; MINIDUMP_CALLBACK_INFORMATION mci; mci.CallbackRoutine = minidump_callback; mci.CallbackParam = (void *)¶m; - if (MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hDumpFile, minidump_type, &minidumpExcInfo, NULL, &mci)) + if (MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &minidumpExcInfo, NULL, &mci)) { debug_internal::dbgCrashDumpPath[0] = 0; // no more dumps } diff --git a/prog/engine/kernel/logimpl.cpp b/prog/engine/kernel/logimpl.cpp index 3d8004bbb..6cad711eb 100644 --- a/prog/engine/kernel/logimpl.cpp +++ b/prog/engine/kernel/logimpl.cpp @@ -125,11 +125,11 @@ static FILE *ios_global_fp = NULL; static file_ptr_t xbox_debug_file = NULL; #endif -#define PFUN(fmt, ...) \ - do \ - { \ - _snprintf(buf + buf_used_len, sizeof(vlog_buf) - buf_used_len, fmt, ##__VA_ARGS__); \ - buf_used_len += i_strlen(buf + buf_used_len); \ +#define PFUN(fmt, ...) \ + do \ + { \ + snprintf(buf + buf_used_len, sizeof(vlog_buf) - buf_used_len, fmt, ##__VA_ARGS__); \ + buf_used_len += i_strlen(buf + buf_used_len); \ } while (0) #define LOG_TAIL_BUF (_TARGET_XBOX || _TARGET_C1 || _TARGET_C2 || _TARGET_ANDROID || _TARGET_IOS) diff --git a/prog/engine/math/math3d.cpp b/prog/engine/math/math3d.cpp index 402fface7..11f3c8152 100644 --- a/prog/engine/math/math3d.cpp +++ b/prog/engine/math/math3d.cpp @@ -338,6 +338,8 @@ static void adjoint(const T *in, TMatrix4D *out) * det A */ +bool is_invertible(const TMatrix4 &mat) { return fabs(det4x4(mat)) > 1e-15f; } + bool inverse44(const TMatrix4 &in, TMatrix4 &result, float &det) { int i, j; @@ -390,7 +392,7 @@ TMatrix4 inverse44(const TMatrix4 &in) float det; if (!inverse44(in, result, det)) { - G_ASSERTF(0, "Non-singular matrix, no inverse!"); + G_ASSERTF(0, "Singular matrix, no inverse!"); return TMatrix4::IDENT; } return result; diff --git a/prog/engine/memory/physMem.cpp b/prog/engine/memory/physMem.cpp index cc085d29b..6e45a4aaf 100644 --- a/prog/engine/memory/physMem.cpp +++ b/prog/engine/memory/physMem.cpp @@ -25,8 +25,9 @@ static uint32_t total_allocated_pages = 0; // protected by phys_map critsec static uint32_t max_allocated_pages = 0; // protected by phys_map critsec static TabWithLock phys_map(midmem_ptr()); -void *alloc_phys_mem(size_t size, size_t alignment, uint32_t prot_flags, bool cpu_cached) +void *alloc_phys_mem(size_t size, size_t alignment, uint32_t prot_flags, bool cpu_cached, bool log_failure) { + G_UNUSED(log_failure); G_ASSERT(size != 0); #if _TARGET_ANDROID | _TARGET_PC_WIN | _TARGET_XBOX | _TARGET_C3 diff --git a/prog/engine/osApiWrappers/messageBox/jamfile b/prog/engine/osApiWrappers/messageBox/jamfile index d11bd54ac..c32de081a 100644 --- a/prog/engine/osApiWrappers/messageBox/jamfile +++ b/prog/engine/osApiWrappers/messageBox/jamfile @@ -21,8 +21,13 @@ if $(Platform) in win32 win64 { ; CPPopt += -Wno-error ; } else if $(Platform) in linux64 { - AddIncludes += $(_DEVTOOL)/fltk-1.3.3 ; - AddLibs += -lX11 $(_DEVTOOL)/fltk-1.3.3/lib/libfltk-minimal.a ; + AddLibs += -lX11 ; + if [ GLOB $(_DEVTOOL) : fltk-1.3.3 ] { + AddIncludes += $(_DEVTOOL)/fltk-1.3.3 ; + AddLibs += -lX11 $(_DEVTOOL)/fltk-1.3.3/lib/libfltk-minimal.a ; + } else { + AddLibs += -lX11 -lfltk ; + } Sources += linuxMessageBox.cpp ; } else if $(Platform) in ps4 ps5 { Sources += sonyMessageBox.cpp ; diff --git a/prog/engine/osApiWrappers/miscApi.cpp b/prog/engine/osApiWrappers/miscApi.cpp index a78d53ed2..310c487c4 100644 --- a/prog/engine/osApiWrappers/miscApi.cpp +++ b/prog/engine/osApiWrappers/miscApi.cpp @@ -363,7 +363,7 @@ bool detect_os_compatibility_mode(char *os_real_name, size_t os_real_name_size) if (os_real_name != NULL) { SNPRINTF(os_real_name, os_real_name_size, "Windows %s v%d.%d", - osvi.wProductType == VER_NT_WORKSTATION ? "Workstation" : "Server", dllVersionMajor, dllVersionMinor); + osvi.wProductType == VER_NT_WORKSTATION ? "Workstation" : "Server", (int)dllVersionMajor, (int)dllVersionMinor); } return true; } diff --git a/prog/engine/shaders/scriptSElem.cpp b/prog/engine/shaders/scriptSElem.cpp index e7d54f328..26694cc9b 100644 --- a/prog/engine/shaders/scriptSElem.cpp +++ b/prog/engine/shaders/scriptSElem.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include <3d/dag_texIdSet.h> #include @@ -1237,47 +1238,20 @@ void ScriptedShaderElement::exec_stcode(dag::ConstSpan cod, const shaderbin } } - int start = 0, end, mask = 1; while (fsh_c_mask) { - while (!(fsh_c_mask & mask)) - { - start++; - mask <<= 1; - } - end = start + 1; - mask <<= 1; - while (fsh_c_mask & mask) - { - end++; - mask <<= 1; - } - fsh_c_mask &= ~(mask - 1); - + auto start = __ctz_unsafe(fsh_c_mask); + auto end = __ctz(fsh_c_mask + (1u << start)); + fsh_c_mask &= uint64_t(eastl::numeric_limits::max()) << end; d3d::set_ps_const(start, fsh_const + start * 4, end - start); - start = end; } - start = 0; - mask = 1; while (vpr_c_mask) { - while (!(vpr_c_mask & mask)) - { - start++; - mask <<= 1; - } - end = start + 1; - mask <<= 1; - while (vpr_c_mask & mask) - { - end++; - mask <<= 1; - } - vpr_c_mask &= ~(mask - 1); - + auto start = __ctz_unsafe(vpr_c_mask); + auto end = __ctz(vpr_c_mask + (1u << start)); + vpr_c_mask &= uint64_t(eastl::numeric_limits::max()) << end; d3d::set_vs_const(start, vpr_const + start * 4, end - start); - start = end; } MEASURE_STCODE_PERF_END; diff --git a/prog/engine/shaders/shaders.cpp b/prog/engine/shaders/shaders.cpp index 86d421a73..c71da56d1 100644 --- a/prog/engine/shaders/shaders.cpp +++ b/prog/engine/shaders/shaders.cpp @@ -621,6 +621,22 @@ static d3d::shadermodel::Version forceFSH = d3d::smAny; d3d::shadermodel::Version getMaxFSHVersion() { return forceFSH; } void limitMaxFSHVersion(d3d::shadermodel::Version f) { forceFSH = f; } +void dump_shader_statistics() +{ +#if DAGOR_DBGLEVEL > 0 + if (dgs_get_settings()->getBlockByNameEx("debug")->getBool("dumpShaderStatistics", false)) + { + auto game_name = dgs_get_settings()->getStr("contactsGameId"); + String dump_name(64, ".logs~%s/game", game_name); + char fname[DAGOR_MAX_PATH]; + build_shaderdump_filename(fname, dump_name, d3d::smAny); + strcat(fname, ".stat"); + dump_shader_statistics(fname); + debug("Shader statistics has been dumped to %s", fname); + } +#endif +} + class ShadersRestartProc : public SRestartProc { public: @@ -682,18 +698,7 @@ class ShadersRestartProc : public SRestartProc void shutdown() { -#if DAGOR_DBGLEVEL > 0 - if (dgs_get_settings()->getBlockByNameEx("debug")->getBool("dumpShaderStatistics", false)) - { - auto game_name = dgs_get_settings()->getStr("contactsGameId"); - String dump_name(64, ".logs~%s/game", game_name); - char fname[DAGOR_MAX_PATH]; - build_shaderdump_filename(fname, dump_name, maxFshVer); - strcat(fname, ".stat"); - dump_shader_statistics(fname); - debug("Shader statistics has been dumped to %s", fname); - } -#endif + dump_shader_statistics(); del_restart_proc(&drvResetRp); close_vdecl(); diff --git a/prog/engine/sharedInclude/phys/physSysInst.inc.cpp b/prog/engine/sharedInclude/phys/physSysInst.inc.cpp index a85ba33f1..c6f7050fa 100644 --- a/prog/engine/sharedInclude/phys/physSysInst.inc.cpp +++ b/prog/engine/sharedInclude/phys/physSysInst.inc.cpp @@ -407,7 +407,15 @@ PhysSystemInstance::Body::Body(PhysicsResource::Body &res_body, PhysWorld *world pbcd.materialId = PhysMat::getMaterial(matId).physBodyMaterial; pbcd.addToWorld = tm != nullptr; - body.reset(new PhysBody(world, res_body.mass, &coll, tm ? ((*tm) * res_body.tm) : res_body.tm, pbcd)); + TMatrix physBodyTm = tm ? ((*tm) * res_body.tm) : res_body.tm; + if (tm != nullptr) + { + physBodyTm.setcol(0, normalize(physBodyTm.getcol(0))); + physBodyTm.setcol(1, normalize(physBodyTm.getcol(1))); + physBodyTm.setcol(2, normalize(physBodyTm.getcol(2))); + } + + body.reset(new PhysBody(world, res_body.mass, &coll, physBodyTm, pbcd)); coll.clear(); } diff --git a/prog/engine/startup/applyCmdline.cpp b/prog/engine/startup/applyCmdline.cpp index 7df0e726f..77b7fabde 100644 --- a/prog/engine/startup/applyCmdline.cpp +++ b/prog/engine/startup/applyCmdline.cpp @@ -50,8 +50,15 @@ void dgs_apply_command_line_arg_to_blk(DataBlock *target, const char *value, con OverrideFilter gen_default_override_filter(const SettingsHashMap *changed_settings) { - return [changed_settings](const char *setting) { - if (!changed_settings) + static SettingsHashMap accumulatedChangedSettings; + if (changed_settings) + { + for (int i = 0; i < changed_settings->nameCount(); i++) + accumulatedChangedSettings.addNameId(changed_settings->getName(i)); + } + const SettingsHashMap *accumulatedChangedSettingsPtr = &accumulatedChangedSettings; + return [accumulatedChangedSettingsPtr](const char *setting) { + if (accumulatedChangedSettingsPtr->nameCount() == 0) return true; char tmpOpt[256]; strncpy(tmpOpt, setting, sizeof(tmpOpt)); @@ -60,7 +67,7 @@ OverrideFilter gen_default_override_filter(const SettingsHashMap *changed_settin if (!nameEnd) return true; *nameEnd = '\0'; - return changed_settings->getNameId(tmpOpt) < 0; + return accumulatedChangedSettingsPtr->getNameId(tmpOpt) < 0; }; } diff --git a/prog/engine/startup/loadSettings.cpp b/prog/engine/startup/loadSettings.cpp index 4c1e48d55..f3ff464ef 100644 --- a/prog/engine/startup/loadSettings.cpp +++ b/prog/engine/startup/loadSettings.cpp @@ -110,7 +110,7 @@ void dgs_load_settings_blk_ex(bool apply_cmd, const char *settings_blk_fn, const if (apply_cmd) { OverrideFilter filter = gen_default_override_filter(changed_settings); - dgs_apply_command_line_to_config(&cfg, changed_settings ? &filter : nullptr); + dgs_apply_command_line_to_config(&cfg, &filter); } if (!cfg.isEmpty()) diff --git a/prog/gameLibs/asyncHTTPClient/curl.cpp b/prog/gameLibs/asyncHTTPClient/curl.cpp index 14af4cc3f..4368d03b7 100644 --- a/prog/gameLibs/asyncHTTPClient/curl.cpp +++ b/prog/gameLibs/asyncHTTPClient/curl.cpp @@ -533,6 +533,11 @@ static void move_queue_to_active_requests_nolock() static constexpr uint8_t MAX_ACTIVE_REQUESTS = 32; #endif +#if _TARGET_XBOX + if (!xbox::has_network_access()) + return; +#endif + if (queue_mutex) { WinAutoLock lock(*queue_mutex); @@ -735,11 +740,6 @@ static eastl::unique_ptr g_poll_thread; void poll() { -#if _TARGET_XBOX - if (!xbox::has_network_access()) - return; -#endif - if (g_poll_thread && g_poll_thread->thread_id != get_current_thread_id()) return; diff --git a/prog/gameLibs/daGI/shaders/daGIList.blk b/prog/gameLibs/daGI/shaders/daGIList.blk index a4e78f25c..196c0769c 100644 --- a/prog/gameLibs/daGI/shaders/daGIList.blk +++ b/prog/gameLibs/daGI/shaders/daGIList.blk @@ -1,16 +1,16 @@ include "../../daGI25D/shaders/daGI25DList.blk" - file:t = "../../textureUtil/shaders/clear_volmap.sh" - file:t = "fill_windows.sh" - file:t = "fill_walls.sh" - file:t = "dagi_first_visible_volmap_calc.sh" - file:t = "screen_space_volmap_initial.sh" - file:t = "screen_space_volmap_copy.sh" - file:t = "screen_space_volmap_clear.sh" - file:t = "screen_space_volmap.sh" - file:t = "dagi_main_volmap_calc.sh" - file:t = "dagi_volmap_culling.sh" - file:t = "volmap_move_y.sh" - file:t = "dagi_debug_scene.sh" - file:t = "dagi_debug_volmap.sh" - file:t = "dagi_scene_voxels.sh" - file:t = "dagi_envi_cube.sh" + file:t = "../../textureUtil/shaders/clear_volmap.dshl" + file:t = "fill_windows.dshl" + file:t = "fill_walls.dshl" + file:t = "dagi_first_visible_volmap_calc.dshl" + file:t = "screen_space_volmap_initial.dshl" + file:t = "screen_space_volmap_copy.dshl" + file:t = "screen_space_volmap_clear.dshl" + file:t = "screen_space_volmap.dshl" + file:t = "dagi_main_volmap_calc.dshl" + file:t = "dagi_volmap_culling.dshl" + file:t = "volmap_move_y.dshl" + file:t = "dagi_debug_scene.dshl" + file:t = "dagi_debug_volmap.dshl" + file:t = "dagi_scene_voxels.dshl" + file:t = "dagi_envi_cube.dshl" diff --git a/prog/gameLibs/daGI/shaders/dagi_alternate_reflections.sh b/prog/gameLibs/daGI/shaders/dagi_alternate_reflections.dshl similarity index 98% rename from prog/gameLibs/daGI/shaders/dagi_alternate_reflections.sh rename to prog/gameLibs/daGI/shaders/dagi_alternate_reflections.dshl index c9da1cfb7..6cc20665f 100644 --- a/prog/gameLibs/daGI/shaders/dagi_alternate_reflections.sh +++ b/prog/gameLibs/daGI/shaders/dagi_alternate_reflections.dshl @@ -1,5 +1,5 @@ -include "frustum.sh" -include "dagi_reflections.sh" +include "frustum.dshl" +include "dagi_reflections.dshl" macro DAGI_ALTERNATE_REFLECTIONS(code) if (gi_quality >= colored) diff --git a/prog/gameLibs/daGI/shaders/dagi_debug_scene.sh b/prog/gameLibs/daGI/shaders/dagi_debug_scene.dshl similarity index 98% rename from prog/gameLibs/daGI/shaders/dagi_debug_scene.sh rename to prog/gameLibs/daGI/shaders/dagi_debug_scene.dshl index 5f4a4a934..f705ef8a3 100644 --- a/prog/gameLibs/daGI/shaders/dagi_debug_scene.sh +++ b/prog/gameLibs/daGI/shaders/dagi_debug_scene.dshl @@ -1,9 +1,9 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "frustum.sh" -include "gbuffer.sh" -include "dagi_scene_voxels_common.sh" -//include "sample_voxels.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" +include "gbuffer.dshl" +include "dagi_scene_voxels_common.dshl" +//include "sample_voxels.dshl" int ssgi_debug_rasterize_scene = 0; interval ssgi_debug_rasterize_scene:raycast<1, exact_voxels<2, lit_voxels; diff --git a/prog/gameLibs/daGI/shaders/dagi_debug_volmap.sh b/prog/gameLibs/daGI/shaders/dagi_debug_volmap.dshl similarity index 97% rename from prog/gameLibs/daGI/shaders/dagi_debug_volmap.sh rename to prog/gameLibs/daGI/shaders/dagi_debug_volmap.dshl index f1b82236d..59a3a35d5 100644 --- a/prog/gameLibs/daGI/shaders/dagi_debug_volmap.sh +++ b/prog/gameLibs/daGI/shaders/dagi_debug_volmap.dshl @@ -1,10 +1,10 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "frustum.sh" -include "gbuffer.sh" -include "dagi_volmap_gi.sh" -include "dagi_scene_voxels_common.sh" -//include "sample_voxels.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" +include "gbuffer.dshl" +include "dagi_volmap_gi.dshl" +include "dagi_scene_voxels_common.dshl" +//include "sample_voxels.dshl" hlsl { #include "dagi_common_types.hlsli" diff --git a/prog/gameLibs/daGI/shaders/dagi_envi_cube.sh b/prog/gameLibs/daGI/shaders/dagi_envi_cube.dshl similarity index 99% rename from prog/gameLibs/daGI/shaders/dagi_envi_cube.sh rename to prog/gameLibs/daGI/shaders/dagi_envi_cube.dshl index d31567ac7..68eb90ab0 100644 --- a/prog/gameLibs/daGI/shaders/dagi_envi_cube.sh +++ b/prog/gameLibs/daGI/shaders/dagi_envi_cube.dshl @@ -1,4 +1,4 @@ -include "hardware_defines.sh" +include "hardware_defines.dshl" //todo: instead of two-step reduction with fixed amount of groups, we can just use atomic adds (InterlockedAdd) (and 6 uint3 instead of 6 float3 for intermediate results + 1 uint for total count of groups) //2nd dispatch just converts from 16.16 (or, say, 12.20) to 6*float3 //this would allow up to almost infinite scaling (from one group to many, as needed (but to keep inside the range of fixed point) ), simplifies 2nd step (very simple, instead of averaging) diff --git a/prog/gameLibs/daGI/shaders/dagi_first_visible_volmap_calc.sh b/prog/gameLibs/daGI/shaders/dagi_first_visible_volmap_calc.dshl similarity index 94% rename from prog/gameLibs/daGI/shaders/dagi_first_visible_volmap_calc.sh rename to prog/gameLibs/daGI/shaders/dagi_first_visible_volmap_calc.dshl index 6dcccaa34..41dd052c1 100644 --- a/prog/gameLibs/daGI/shaders/dagi_first_visible_volmap_calc.sh +++ b/prog/gameLibs/daGI/shaders/dagi_first_visible_volmap_calc.dshl @@ -1,12 +1,12 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "frustum.sh" -include "dagi_volmap_gi.sh" -include "dagi_scene_voxels_common.sh" -include "dagi_inline_raytrace.sh" -include "dagi_helpers.sh" -//include "gpu_occlusion.sh" -//include "sample_voxels.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" +include "dagi_volmap_gi.dshl" +include "dagi_scene_voxels_common.dshl" +include "dagi_inline_raytrace.dshl" +include "dagi_helpers.dshl" +//include "gpu_occlusion.dshl" +//include "sample_voxels.dshl" hlsl { #include "dagi_common_types.hlsli" } diff --git a/prog/gameLibs/daGI/shaders/dagi_inline_raytrace.sh b/prog/gameLibs/daGI/shaders/dagi_inline_raytrace.dshl similarity index 98% rename from prog/gameLibs/daGI/shaders/dagi_inline_raytrace.sh rename to prog/gameLibs/daGI/shaders/dagi_inline_raytrace.dshl index 66b1286cc..087d6966a 100644 --- a/prog/gameLibs/daGI/shaders/dagi_inline_raytrace.sh +++ b/prog/gameLibs/daGI/shaders/dagi_inline_raytrace.dshl @@ -1,10 +1,10 @@ -include "dagi_volmap_gi.sh" -include "gbuffer.sh" -include "skyLight.sh" -include "gi_dynamic_light_helper.sh" -include "globtm.sh" -include "static_shadow.sh" -include "csm.sh" +include "dagi_volmap_gi.dshl" +include "gbuffer.dshl" +include "skyLight.dshl" +include "gi_dynamic_light_helper.dshl" +include "globtm.dshl" +include "static_shadow.dshl" +include "csm.dshl" int ssgi_total_scene_mark_dipatch = 8192; int ssgi_current_frame; diff --git a/prog/gameLibs/daGI/shaders/dagi_main_volmap_calc.sh b/prog/gameLibs/daGI/shaders/dagi_main_volmap_calc.dshl similarity index 96% rename from prog/gameLibs/daGI/shaders/dagi_main_volmap_calc.sh rename to prog/gameLibs/daGI/shaders/dagi_main_volmap_calc.dshl index cd98cacc6..f0bd34f39 100644 --- a/prog/gameLibs/daGI/shaders/dagi_main_volmap_calc.sh +++ b/prog/gameLibs/daGI/shaders/dagi_main_volmap_calc.dshl @@ -1,12 +1,12 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "frustum.sh" -include "dagi_volmap_gi.sh" -include "dagi_scene_voxels_common.sh" -include "dagi_inline_raytrace.sh" -include "dagi_helpers.sh" -//include "gpu_occlusion.sh" -//include "sample_voxels.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" +include "dagi_volmap_gi.dshl" +include "dagi_scene_voxels_common.dshl" +include "dagi_inline_raytrace.dshl" +include "dagi_helpers.dshl" +//include "gpu_occlusion.dshl" +//include "sample_voxels.dshl" hlsl { #include "dagi_common_types.hlsli" } diff --git a/prog/gameLibs/daGI/shaders/dagi_quality.sh b/prog/gameLibs/daGI/shaders/dagi_quality.dshl similarity index 100% rename from prog/gameLibs/daGI/shaders/dagi_quality.sh rename to prog/gameLibs/daGI/shaders/dagi_quality.dshl diff --git a/prog/gameLibs/daGI/shaders/dagi_reflections.sh b/prog/gameLibs/daGI/shaders/dagi_reflections.dshl similarity index 99% rename from prog/gameLibs/daGI/shaders/dagi_reflections.sh rename to prog/gameLibs/daGI/shaders/dagi_reflections.dshl index 0cf9864e4..685bb9bd1 100644 --- a/prog/gameLibs/daGI/shaders/dagi_reflections.sh +++ b/prog/gameLibs/daGI/shaders/dagi_reflections.dshl @@ -1,4 +1,4 @@ -include "dagi_scene_voxels_common.sh" +include "dagi_scene_voxels_common.dshl" macro GET_REFLECTIONS_FROM_GI(code) hlsl(code) { diff --git a/prog/gameLibs/daGI/shaders/dagi_scene_common_write.sh b/prog/gameLibs/daGI/shaders/dagi_scene_common_write.dshl similarity index 98% rename from prog/gameLibs/daGI/shaders/dagi_scene_common_write.sh rename to prog/gameLibs/daGI/shaders/dagi_scene_common_write.dshl index edc985b56..e1c81d159 100644 --- a/prog/gameLibs/daGI/shaders/dagi_scene_common_write.sh +++ b/prog/gameLibs/daGI/shaders/dagi_scene_common_write.dshl @@ -1,4 +1,4 @@ -include "dagi_scene_voxels_common.sh" +include "dagi_scene_voxels_common.dshl" float4 scene_voxels_invalid_start; float4 scene_voxels_invalid_width; diff --git a/prog/gameLibs/daGI/shaders/dagi_scene_voxels.sh b/prog/gameLibs/daGI/shaders/dagi_scene_voxels.dshl similarity index 98% rename from prog/gameLibs/daGI/shaders/dagi_scene_voxels.sh rename to prog/gameLibs/daGI/shaders/dagi_scene_voxels.dshl index 7108cd33b..a712bc016 100644 --- a/prog/gameLibs/daGI/shaders/dagi_scene_voxels.sh +++ b/prog/gameLibs/daGI/shaders/dagi_scene_voxels.dshl @@ -1,10 +1,10 @@ -include "viewVecVS.sh" -include "frustum.sh" -include "dagi_scene_voxels_common.sh" -include "dagi_scene_common_write.sh" -include "dagi_volmap_gi.sh" -include "dagi_helpers.sh" -include "dagi_light_helpers.sh" +include "viewVecVS.dshl" +include "frustum.dshl" +include "dagi_scene_voxels_common.dshl" +include "dagi_scene_common_write.dshl" +include "dagi_volmap_gi.dshl" +include "dagi_helpers.dshl" +include "dagi_light_helpers.dshl" int ssgi_current_frame; int has_physobj_in_cascade; diff --git a/prog/gameLibs/daGI/shaders/dagi_scene_voxels_common.sh b/prog/gameLibs/daGI/shaders/dagi_scene_voxels_common.dshl similarity index 98% rename from prog/gameLibs/daGI/shaders/dagi_scene_voxels_common.sh rename to prog/gameLibs/daGI/shaders/dagi_scene_voxels_common.dshl index 6b0af1166..4c39fcc45 100644 --- a/prog/gameLibs/daGI/shaders/dagi_scene_voxels_common.sh +++ b/prog/gameLibs/daGI/shaders/dagi_scene_voxels_common.dshl @@ -14,13 +14,13 @@ float4 scene_voxels_bmax2; //float4 constant_ambient_light = (0.0, 0.0,0,0.0); //float inv_constant_ambient_dist_sq = 1./(10*10); //float inv_constant_ambient_dist_ofs = -0.01; -include "dagi_walls.sh" -include "dagi_windows.sh" -include "dagi_volmap_gi.sh" -include "static_shadow.sh" -include "dagi_scene_voxels_common_25d.sh" -include "csm.sh" -include "other_gi_ray_cast.sh" +include "dagi_walls.dshl" +include "dagi_windows.dshl" +include "dagi_volmap_gi.dshl" +include "static_shadow.dshl" +include "dagi_scene_voxels_common_25d.dshl" +include "csm.dshl" +include "other_gi_ray_cast.dshl" macro SAMPLE_VOXELS(code) (code) { diff --git a/prog/gameLibs/daGI/shaders/dagi_volmap_culling.sh b/prog/gameLibs/daGI/shaders/dagi_volmap_culling.dshl similarity index 96% rename from prog/gameLibs/daGI/shaders/dagi_volmap_culling.sh rename to prog/gameLibs/daGI/shaders/dagi_volmap_culling.dshl index 16f8e3b97..6bde0b3f7 100644 --- a/prog/gameLibs/daGI/shaders/dagi_volmap_culling.sh +++ b/prog/gameLibs/daGI/shaders/dagi_volmap_culling.dshl @@ -1,10 +1,10 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "frustum.sh" -include "dagi_volmap_gi.sh" -include "dagi_scene_voxels_common.sh" -include "dagi_helpers.sh" -include "gpu_occlusion.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" +include "dagi_volmap_gi.dshl" +include "dagi_scene_voxels_common.dshl" +include "dagi_helpers.dshl" +include "gpu_occlusion.dshl" hlsl { #include "dagi_common_types.hlsli" diff --git a/prog/gameLibs/daGI/shaders/dagi_volmap_gi.sh b/prog/gameLibs/daGI/shaders/dagi_volmap_gi.dshl similarity index 99% rename from prog/gameLibs/daGI/shaders/dagi_volmap_gi.sh rename to prog/gameLibs/daGI/shaders/dagi_volmap_gi.dshl index 38ef14746..83b2f7d1c 100644 --- a/prog/gameLibs/daGI/shaders/dagi_volmap_gi.sh +++ b/prog/gameLibs/daGI/shaders/dagi_volmap_gi.dshl @@ -1,6 +1,6 @@ -include "hardware_defines.sh" -include "dagi_scene_voxels_common.sh" -include "dagi_quality.sh" +include "hardware_defines.dshl" +include "dagi_scene_voxels_common.dshl" +include "dagi_quality.dshl" texture gi_ambient_volmap; texture ssgi_ambient_volmap_temporal; diff --git a/prog/gameLibs/daGI/shaders/dagi_walls.sh b/prog/gameLibs/daGI/shaders/dagi_walls.dshl similarity index 100% rename from prog/gameLibs/daGI/shaders/dagi_walls.sh rename to prog/gameLibs/daGI/shaders/dagi_walls.dshl diff --git a/prog/gameLibs/daGI/shaders/dagi_windows.sh b/prog/gameLibs/daGI/shaders/dagi_windows.dshl similarity index 100% rename from prog/gameLibs/daGI/shaders/dagi_windows.sh rename to prog/gameLibs/daGI/shaders/dagi_windows.dshl diff --git a/prog/gameLibs/daGI/shaders/debug_inline_rt.sh b/prog/gameLibs/daGI/shaders/debug_inline_rt.dshl similarity index 92% rename from prog/gameLibs/daGI/shaders/debug_inline_rt.sh rename to prog/gameLibs/daGI/shaders/debug_inline_rt.dshl index 913e4242d..de6732420 100644 --- a/prog/gameLibs/daGI/shaders/debug_inline_rt.sh +++ b/prog/gameLibs/daGI/shaders/debug_inline_rt.dshl @@ -1,8 +1,8 @@ -include "sky_shader_global.sh" -include "dagi_scene_voxels_common.sh" -include "dagi_inline_raytrace.sh" -include "viewVecVS.sh" -include "dagi_volmap_gi.sh" +include "sky_shader_global.dshl" +include "dagi_scene_voxels_common.dshl" +include "dagi_inline_raytrace.dshl" +include "viewVecVS.dshl" +include "dagi_volmap_gi.dshl" int debug_inline_rt_raydist = 0; interval debug_inline_rt_raydist: off<1, on; diff --git a/prog/gameLibs/daGI/shaders/fill_walls.sh b/prog/gameLibs/daGI/shaders/fill_walls.dshl similarity index 98% rename from prog/gameLibs/daGI/shaders/fill_walls.sh rename to prog/gameLibs/daGI/shaders/fill_walls.dshl index 6e3f9c7fe..860693fd8 100644 --- a/prog/gameLibs/daGI/shaders/fill_walls.sh +++ b/prog/gameLibs/daGI/shaders/fill_walls.dshl @@ -1,5 +1,5 @@ -include "sky_shader_global.sh" -include "dagi_scene_voxels_common.sh" +include "sky_shader_global.dshl" +include "dagi_scene_voxels_common.dshl" //int current_walls_count; diff --git a/prog/gameLibs/daGI/shaders/fill_windows.sh b/prog/gameLibs/daGI/shaders/fill_windows.dshl similarity index 98% rename from prog/gameLibs/daGI/shaders/fill_windows.sh rename to prog/gameLibs/daGI/shaders/fill_windows.dshl index cbd7a9ebd..2f4bd8136 100644 --- a/prog/gameLibs/daGI/shaders/fill_windows.sh +++ b/prog/gameLibs/daGI/shaders/fill_windows.dshl @@ -1,5 +1,5 @@ -include "sky_shader_global.sh" -include "dagi_scene_voxels_common.sh" +include "sky_shader_global.dshl" +include "dagi_scene_voxels_common.dshl" //int current_windows_count; buffer windows_grid_ind; diff --git a/prog/gameLibs/daGI/shaders/gi_dynamic_light_helper.sh b/prog/gameLibs/daGI/shaders/gi_dynamic_light_helper.dshl similarity index 100% rename from prog/gameLibs/daGI/shaders/gi_dynamic_light_helper.sh rename to prog/gameLibs/daGI/shaders/gi_dynamic_light_helper.dshl diff --git a/prog/gameLibs/daGI/shaders/octahedral_distances.sh b/prog/gameLibs/daGI/shaders/octahedral_distances.dshl similarity index 97% rename from prog/gameLibs/daGI/shaders/octahedral_distances.sh rename to prog/gameLibs/daGI/shaders/octahedral_distances.dshl index 452ec5f33..442855d17 100644 --- a/prog/gameLibs/daGI/shaders/octahedral_distances.sh +++ b/prog/gameLibs/daGI/shaders/octahedral_distances.dshl @@ -1,6 +1,6 @@ -include "sky_shader_global.sh" -include "dagi_volmap_gi.sh" -include "dagi_scene_voxels_common_25d.sh" +include "sky_shader_global.dshl" +include "dagi_volmap_gi.dshl" +include "dagi_scene_voxels_common_25d.dshl" define_macro_if_not_defined INIT_VOXELS_HEIGHTMAP_HELPERS(code) hlsl(code) { diff --git a/prog/gameLibs/daGI/shaders/other_gi_ray_cast.sh b/prog/gameLibs/daGI/shaders/other_gi_ray_cast.dshl similarity index 84% rename from prog/gameLibs/daGI/shaders/other_gi_ray_cast.sh rename to prog/gameLibs/daGI/shaders/other_gi_ray_cast.dshl index c7008146f..a50750af6 100644 --- a/prog/gameLibs/daGI/shaders/other_gi_ray_cast.sh +++ b/prog/gameLibs/daGI/shaders/other_gi_ray_cast.dshl @@ -1,6 +1,6 @@ //this is project-dependent implementation //if you have way to exactly raycast distance to walls (i.e RTX with collision, or sdf) -//put other_gi_ray_cast.sh in your app folder with this macro +//put other_gi_ray_cast.dshl in your app folder with this macro // macro OTHER_GI_RAY_CAST_DIST(code) // hlsl(code) { // #define HAS_OTHER_RAY_DIST 1 diff --git a/prog/gameLibs/daGI/shaders/screen_space_volmap.sh b/prog/gameLibs/daGI/shaders/screen_space_volmap.dshl similarity index 97% rename from prog/gameLibs/daGI/shaders/screen_space_volmap.sh rename to prog/gameLibs/daGI/shaders/screen_space_volmap.dshl index f9424cf5e..ade500f3b 100644 --- a/prog/gameLibs/daGI/shaders/screen_space_volmap.sh +++ b/prog/gameLibs/daGI/shaders/screen_space_volmap.dshl @@ -1,11 +1,11 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "frustum.sh" -include "dagi_volmap_gi.sh" -include "dagi_scene_voxels_common.sh" -include "dagi_helpers.sh" -//include "gpu_occlusion.sh" -//include "sample_voxels.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" +include "dagi_volmap_gi.dshl" +include "dagi_scene_voxels_common.dshl" +include "dagi_helpers.dshl" +//include "gpu_occlusion.dshl" +//include "sample_voxels.dshl" hlsl { #include "dagi_common_types.hlsli" } diff --git a/prog/gameLibs/daGI/shaders/screen_space_volmap_clear.sh b/prog/gameLibs/daGI/shaders/screen_space_volmap_clear.dshl similarity index 92% rename from prog/gameLibs/daGI/shaders/screen_space_volmap_clear.sh rename to prog/gameLibs/daGI/shaders/screen_space_volmap_clear.dshl index 6d06d70b0..ae9f78bc3 100644 --- a/prog/gameLibs/daGI/shaders/screen_space_volmap_clear.sh +++ b/prog/gameLibs/daGI/shaders/screen_space_volmap_clear.dshl @@ -1,12 +1,12 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "frustum.sh" -include "dagi_volmap_gi.sh" -include "dagi_scene_voxels_common.sh" -include "dagi_helpers.sh" -include "dagi_volmap_common_25d.sh" -//include "gpu_occlusion.sh" -//include "sample_voxels.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" +include "dagi_volmap_gi.dshl" +include "dagi_scene_voxels_common.dshl" +include "dagi_helpers.dshl" +include "dagi_volmap_common_25d.dshl" +//include "gpu_occlusion.dshl" +//include "sample_voxels.dshl" hlsl { #include "dagi_common_types.hlsli" } diff --git a/prog/gameLibs/daGI/shaders/screen_space_volmap_copy.sh b/prog/gameLibs/daGI/shaders/screen_space_volmap_copy.dshl similarity index 96% rename from prog/gameLibs/daGI/shaders/screen_space_volmap_copy.sh rename to prog/gameLibs/daGI/shaders/screen_space_volmap_copy.dshl index 6b730cfb7..64faeabaa 100644 --- a/prog/gameLibs/daGI/shaders/screen_space_volmap_copy.sh +++ b/prog/gameLibs/daGI/shaders/screen_space_volmap_copy.dshl @@ -1,11 +1,11 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "frustum.sh" -include "dagi_volmap_gi.sh" -include "dagi_scene_voxels_common.sh" -include "dagi_helpers.sh" -//include "gpu_occlusion.sh" -//include "sample_voxels.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" +include "dagi_volmap_gi.dshl" +include "dagi_scene_voxels_common.dshl" +include "dagi_helpers.dshl" +//include "gpu_occlusion.dshl" +//include "sample_voxels.dshl" hlsl { #include "dagi_common_types.hlsli" } diff --git a/prog/gameLibs/daGI/shaders/screen_space_volmap_initial.sh b/prog/gameLibs/daGI/shaders/screen_space_volmap_initial.dshl similarity index 97% rename from prog/gameLibs/daGI/shaders/screen_space_volmap_initial.sh rename to prog/gameLibs/daGI/shaders/screen_space_volmap_initial.dshl index 49ec27ced..26613be38 100644 --- a/prog/gameLibs/daGI/shaders/screen_space_volmap_initial.sh +++ b/prog/gameLibs/daGI/shaders/screen_space_volmap_initial.dshl @@ -1,10 +1,10 @@ -include "sky_shader_global.sh" -include "dagi_volmap_gi.sh" -include "dagi_scene_voxels_common.sh" -include "dagi_inline_raytrace.sh" -include "dagi_helpers.sh" -include "dagi_volmap_common_25d.sh" -//include "sample_voxels.sh" +include "sky_shader_global.dshl" +include "dagi_volmap_gi.dshl" +include "dagi_scene_voxels_common.dshl" +include "dagi_inline_raytrace.dshl" +include "dagi_helpers.dshl" +include "dagi_volmap_common_25d.dshl" +//include "sample_voxels.dshl" hlsl { #include "dagi_common_types.hlsli" } diff --git a/prog/gameLibs/daGI/shaders/volmap_move_y.sh b/prog/gameLibs/daGI/shaders/volmap_move_y.dshl similarity index 99% rename from prog/gameLibs/daGI/shaders/volmap_move_y.sh rename to prog/gameLibs/daGI/shaders/volmap_move_y.dshl index b1a434d86..ff79d93f2 100644 --- a/prog/gameLibs/daGI/shaders/volmap_move_y.sh +++ b/prog/gameLibs/daGI/shaders/volmap_move_y.dshl @@ -1,4 +1,4 @@ -include "dagi_volmap_gi.sh" +include "dagi_volmap_gi.dshl" float4 ssgi_copy_y_indices0; float4 ssgi_copy_y_indices1; diff --git a/prog/gameLibs/daGI/shaders/volmap_move_y_octahedral.sh b/prog/gameLibs/daGI/shaders/volmap_move_y_octahedral.dshl similarity index 100% rename from prog/gameLibs/daGI/shaders/volmap_move_y_octahedral.sh rename to prog/gameLibs/daGI/shaders/volmap_move_y_octahedral.dshl diff --git a/prog/gameLibs/daGI25D/irradiance.cpp b/prog/gameLibs/daGI25D/irradiance.cpp index f4680e53a..9475ee3bf 100644 --- a/prog/gameLibs/daGI25D/irradiance.cpp +++ b/prog/gameLibs/daGI25D/irradiance.cpp @@ -74,7 +74,8 @@ void Irradiance::init(bool scalar_ao, float xz_size, float y_size) void Irradiance::invalidate() { toroidalOrigin += IPoint2{10000, -10000}; - d3d::resource_barrier({volmap.getVolTex(), RB_RO_SRV | RB_STAGE_PIXEL, 0, 0}); + if (volmap.getVolTex()) + d3d::resource_barrier({volmap.getVolTex(), RB_RO_SRV | RB_STAGE_PIXEL, 0, 0}); } void Irradiance::close() diff --git a/prog/gameLibs/daGI25D/shaders/daGI25Dlist.blk b/prog/gameLibs/daGI25D/shaders/daGI25Dlist.blk index e0e307be8..aa65a3a35 100644 --- a/prog/gameLibs/daGI25D/shaders/daGI25Dlist.blk +++ b/prog/gameLibs/daGI25D/shaders/daGI25Dlist.blk @@ -1,4 +1,4 @@ - file:t = "dagi_debug_scene_25d.sh" - file:t = "dagi_scene_voxels_25d.sh" - file:t = "dagi_volmap_25d.sh" - file:t = "dagi_debug_volmap_25d.sh" + file:t = "dagi_debug_scene_25d.dshl" + file:t = "dagi_scene_voxels_25d.dshl" + file:t = "dagi_volmap_25d.dshl" + file:t = "dagi_debug_volmap_25d.dshl" diff --git a/prog/gameLibs/daGI25D/shaders/dagi_debug_scene_25d.sh b/prog/gameLibs/daGI25D/shaders/dagi_debug_scene_25d.dshl similarity index 97% rename from prog/gameLibs/daGI25D/shaders/dagi_debug_scene_25d.sh rename to prog/gameLibs/daGI25D/shaders/dagi_debug_scene_25d.dshl index 276e3fd9a..db4109111 100644 --- a/prog/gameLibs/daGI25D/shaders/dagi_debug_scene_25d.sh +++ b/prog/gameLibs/daGI25D/shaders/dagi_debug_scene_25d.dshl @@ -1,10 +1,10 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "frustum.sh" -include "gbuffer.sh" -include "dagi_quality.sh" -include "dagi_raycast_voxels_25d.sh" -//include "sample_voxels.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" +include "gbuffer.dshl" +include "dagi_quality.dshl" +include "dagi_raycast_voxels_25d.dshl" +//include "sample_voxels.dshl" int ssgi_debug_rasterize_scene = 0; interval ssgi_debug_rasterize_scene:raycast<1, exact_voxels<2, lit_voxels; diff --git a/prog/gameLibs/daGI25D/shaders/dagi_debug_volmap_25d.sh b/prog/gameLibs/daGI25D/shaders/dagi_debug_volmap_25d.dshl similarity index 93% rename from prog/gameLibs/daGI25D/shaders/dagi_debug_volmap_25d.sh rename to prog/gameLibs/daGI25D/shaders/dagi_debug_volmap_25d.dshl index c864e3ff6..87b469aac 100644 --- a/prog/gameLibs/daGI25D/shaders/dagi_debug_volmap_25d.sh +++ b/prog/gameLibs/daGI25D/shaders/dagi_debug_volmap_25d.dshl @@ -1,11 +1,11 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "frustum.sh" -include "gbuffer.sh" -include "dagi_volmap_common_25d.sh" -include "dagi_scene_voxels_common_25d.sh" -include "dagi_raycast_voxels_25d.sh" -//include "sample_voxels.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" +include "gbuffer.dshl" +include "dagi_volmap_common_25d.dshl" +include "dagi_scene_voxels_common_25d.dshl" +include "dagi_raycast_voxels_25d.dshl" +//include "sample_voxels.dshl" hlsl { #include "dagi_volmap_consts_25d.hlsli" diff --git a/prog/gameLibs/daGI25D/shaders/dagi_raycast_voxels_25d.sh b/prog/gameLibs/daGI25D/shaders/dagi_raycast_voxels_25d.dshl similarity index 99% rename from prog/gameLibs/daGI25D/shaders/dagi_raycast_voxels_25d.sh rename to prog/gameLibs/daGI25D/shaders/dagi_raycast_voxels_25d.dshl index 1c884510e..91e9e034a 100644 --- a/prog/gameLibs/daGI25D/shaders/dagi_raycast_voxels_25d.sh +++ b/prog/gameLibs/daGI25D/shaders/dagi_raycast_voxels_25d.dshl @@ -1,4 +1,4 @@ -include "dagi_scene_voxels_common_25d.sh" +include "dagi_scene_voxels_common_25d.dshl" macro RAY_CAST_VOXELS_25D(code) INIT_VOXELS_25D(code) USE_VOXELS_25D(code) diff --git a/prog/gameLibs/daGI25D/shaders/dagi_scene_25d_common_write.sh b/prog/gameLibs/daGI25D/shaders/dagi_scene_25d_common_write.dshl similarity index 97% rename from prog/gameLibs/daGI25D/shaders/dagi_scene_25d_common_write.sh rename to prog/gameLibs/daGI25D/shaders/dagi_scene_25d_common_write.dshl index 88229b688..7465f5587 100644 --- a/prog/gameLibs/daGI25D/shaders/dagi_scene_25d_common_write.sh +++ b/prog/gameLibs/daGI25D/shaders/dagi_scene_25d_common_write.dshl @@ -1,5 +1,5 @@ -include "dagi_scene_voxels_common_25d.sh" -include "dagi_quality.sh" +include "dagi_scene_voxels_common_25d.dshl" +include "dagi_quality.dshl" float4 scene_25d_voxels_invalid_coord_box; int voxels_25d_no = 6; diff --git a/prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_25d.sh b/prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_25d.dshl similarity index 97% rename from prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_25d.sh rename to prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_25d.dshl index 676a71590..6ff44d32e 100644 --- a/prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_25d.sh +++ b/prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_25d.dshl @@ -1,5 +1,5 @@ -include "dagi_scene_voxels_common_25d.sh" -include "dagi_quality.sh" +include "dagi_scene_voxels_common_25d.dshl" +include "dagi_quality.dshl" float4 scene_25d_voxels_invalid_start_width; diff --git a/prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_common_25d.sh b/prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_common_25d.dshl similarity index 97% rename from prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_common_25d.sh rename to prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_common_25d.dshl index eb0635688..399e12921 100644 --- a/prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_common_25d.sh +++ b/prog/gameLibs/daGI25D/shaders/dagi_scene_voxels_common_25d.dshl @@ -1,6 +1,6 @@ -include "hardware_defines.sh" -include "gi_heightmap_25d.sh" -include "gbuffer.sh" +include "hardware_defines.dshl" +include "gi_heightmap_25d.dshl" +include "gbuffer.dshl" buffer scene_25d_buf; float4 scene_25d_voxels_origin; float4 scene_25d_voxels_size; diff --git a/prog/gameLibs/daGI25D/shaders/dagi_volmap_25d.sh b/prog/gameLibs/daGI25D/shaders/dagi_volmap_25d.dshl similarity index 98% rename from prog/gameLibs/daGI25D/shaders/dagi_volmap_25d.sh rename to prog/gameLibs/daGI25D/shaders/dagi_volmap_25d.dshl index e87fb7f89..1989ca874 100644 --- a/prog/gameLibs/daGI25D/shaders/dagi_volmap_25d.sh +++ b/prog/gameLibs/daGI25D/shaders/dagi_volmap_25d.dshl @@ -1,9 +1,9 @@ -include "sky_shader_global.sh" -//include "ssgi_helpers.sh" -//include "sample_voxels.sh" -include "dagi_raycast_voxels_25d.sh" -include "dagi_volmap_common_25d.sh" -include "gi_25d_light_helper.sh" +include "sky_shader_global.dshl" +//include "ssgi_helpers.dshl" +//include "sample_voxels.dshl" +include "dagi_raycast_voxels_25d.dshl" +include "dagi_volmap_common_25d.dshl" +include "gi_25d_light_helper.dshl" hlsl { #include "dagi_volmap_consts_25d.hlsli" } diff --git a/prog/gameLibs/daGI25D/shaders/dagi_volmap_common_25d.sh b/prog/gameLibs/daGI25D/shaders/dagi_volmap_common_25d.dshl similarity index 99% rename from prog/gameLibs/daGI25D/shaders/dagi_volmap_common_25d.sh rename to prog/gameLibs/daGI25D/shaders/dagi_volmap_common_25d.dshl index 2b75c1d7e..747f4e276 100644 --- a/prog/gameLibs/daGI25D/shaders/dagi_volmap_common_25d.sh +++ b/prog/gameLibs/daGI25D/shaders/dagi_volmap_common_25d.dshl @@ -1,5 +1,5 @@ -include "gi_heightmap_25d.sh" -include "dagi_quality.sh" +include "gi_heightmap_25d.dshl" +include "dagi_quality.dshl" texture gi_25d_volmap; float4 gi_25d_volmap_origin; diff --git a/prog/gameLibs/daRg/shaders/dargPanelRendererShaders.sh b/prog/gameLibs/daRg/shaders/dargPanelRendererShaders.dshl similarity index 97% rename from prog/gameLibs/daRg/shaders/dargPanelRendererShaders.sh rename to prog/gameLibs/daRg/shaders/dargPanelRendererShaders.dshl index 923ec1c3a..96e7a8560 100644 --- a/prog/gameLibs/daRg/shaders/dargPanelRendererShaders.sh +++ b/prog/gameLibs/daRg/shaders/dargPanelRendererShaders.dshl @@ -1,8 +1,8 @@ -include "shader_global.sh" -include "gbuffer.sh" -include "taa_inc.sh" -include "static_shadow.sh" -include "vr_multiview.sh" +include "shader_global.dshl" +include "gbuffer.dshl" +include "taa_inc.dshl" +include "static_shadow.dshl" +include "vr_multiview.dshl" texture panel_texture; float panel_brightness; diff --git a/prog/gameLibs/daSkies2/clouds2.h b/prog/gameLibs/daSkies2/clouds2.h index 21bee85b0..ddb92a772 100644 --- a/prog/gameLibs/daSkies2/clouds2.h +++ b/prog/gameLibs/daSkies2/clouds2.h @@ -850,21 +850,10 @@ struct CloudsRenderer taaUseCompute &= use_compute.get(); #endif - struct MyScopeRenderTarget - { - Driver3dRenderTarget prevRT; - bool should; - MyScopeRenderTarget(bool should_) : should(should_) - { - if (should) - d3d_get_render_target(prevRT); - } - ~MyScopeRenderTarget() - { - if (should) - d3d_set_render_target(prevRT); - } - } scoped(!useCompute || !taaUseCompute); + eastl::optional rtScope; + if (!useCompute || !taaUseCompute) + rtScope.emplace(); + renderTiledDist(data); int depthLevels = 1; int level = getNotLesserDepthLevel(data, depthLevels, depth.getTex2D()); @@ -1856,6 +1845,7 @@ struct Clouds2 light.init(); cloudsForm.init(); calcCloudsAlt(); + useHole = use_hole; if (use_hole) initHole(); @@ -2100,6 +2090,9 @@ struct Clouds2 void setUseHole(bool set) { useHole = set; } void resetHole(const Point3 &hole_target, const float &hole_density) { + if (!useHole) + return; + holeTarget = hole_target; holeDensity = hole_density; holeFound = false; diff --git a/prog/gameLibs/daSkies2/shaders/applyPanorama.sh b/prog/gameLibs/daSkies2/shaders/applyPanorama.dshl similarity index 96% rename from prog/gameLibs/daSkies2/shaders/applyPanorama.sh rename to prog/gameLibs/daSkies2/shaders/applyPanorama.dshl index 2d8352076..6a9f19dfe 100644 --- a/prog/gameLibs/daSkies2/shaders/applyPanorama.sh +++ b/prog/gameLibs/daSkies2/shaders/applyPanorama.dshl @@ -1,14 +1,14 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "clouds2/clouds_alt_fraction.sh" -include "panorama.sh" -include "writeToTex.sh" -include "skies_special_vision.sh" -include "tonemapHelpers/use_full_tonemap_lut_inc.sh" -include "use_custom_fog_sky.sh" -include "lightningFlashPanorama.sh" -include "brunetonSky.sh" -include "rgbm_inc.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "clouds2/clouds_alt_fraction.dshl" +include "panorama.dshl" +include "writeToTex.dshl" +include "skies_special_vision.dshl" +include "tonemapHelpers/use_full_tonemap_lut_inc.dshl" +include "use_custom_fog_sky.dshl" +include "lightningFlashPanorama.dshl" +include "brunetonSky.dshl" +include "rgbm_inc.dshl" hlsl(ps) { #define INFINITE_TRACE_DIST 320000.0f @@ -85,7 +85,7 @@ shader applyCloudsPanorama USE_CUSTOM_FOG_SKY(ps) hlsl(ps) { - //TODO: there is similar function in panorama.sh but it does not return modified view + //TODO: there is similar function in panorama.dshl but it does not return modified view float2 get_panorama_uv(float3 origin, inout float3 view) { float cloudDist = max(distanceToClouds0(origin, view), 1000); diff --git a/prog/gameLibs/daSkies2/shaders/applySkies.sh b/prog/gameLibs/daSkies2/shaders/applySkies.dshl similarity index 82% rename from prog/gameLibs/daSkies2/shaders/applySkies.sh rename to prog/gameLibs/daSkies2/shaders/applySkies.dshl index fecf8f5ab..de1c8d742 100644 --- a/prog/gameLibs/daSkies2/shaders/applySkies.sh +++ b/prog/gameLibs/daSkies2/shaders/applySkies.dshl @@ -1,7 +1,7 @@ -include "postfx_inc.sh" -include "sky_shader_global.sh" -include "skies_special_vision.sh" -include "vr_reprojection.sh" +include "postfx_inc.dshl" +include "sky_shader_global.dshl" +include "skies_special_vision.dshl" +include "vr_reprojection.dshl" texture lowres_sky; shader applySkies diff --git a/prog/gameLibs/daSkies2/shaders/atmosphere.sh b/prog/gameLibs/daSkies2/shaders/atmosphere.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/atmosphere.sh rename to prog/gameLibs/daSkies2/shaders/atmosphere.dshl diff --git a/prog/gameLibs/daSkies2/shaders/brunetonSkies.sh b/prog/gameLibs/daSkies2/shaders/brunetonSkies.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/brunetonSkies.sh rename to prog/gameLibs/daSkies2/shaders/brunetonSkies.dshl diff --git a/prog/gameLibs/daSkies2/shaders/brunetonSky.sh b/prog/gameLibs/daSkies2/shaders/brunetonSky.dshl similarity index 99% rename from prog/gameLibs/daSkies2/shaders/brunetonSky.sh rename to prog/gameLibs/daSkies2/shaders/brunetonSky.dshl index 1c111f13a..5c8e5c85f 100644 --- a/prog/gameLibs/daSkies2/shaders/brunetonSky.sh +++ b/prog/gameLibs/daSkies2/shaders/brunetonSky.dshl @@ -1,5 +1,5 @@ -include "atmosphere.sh" -include_optional "skiesSettings.sh" +include "atmosphere.dshl" +include_optional "skiesSettings.dshl" float4 skies_primary_sun_light_dir = (0,0.4,0.6,0); diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/base_distance_to_clouds.sh b/prog/gameLibs/daSkies2/shaders/clouds2/base_distance_to_clouds.dshl similarity index 97% rename from prog/gameLibs/daSkies2/shaders/clouds2/base_distance_to_clouds.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/base_distance_to_clouds.dshl index 31a880ded..8195e9511 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/base_distance_to_clouds.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/base_distance_to_clouds.dshl @@ -1,4 +1,4 @@ -include "clouds_alt_fraction.sh" +include "clouds_alt_fraction.dshl" texture cloud_layers_altitudes_tex; hlsl { diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/cloud_volume_mask.sh b/prog/gameLibs/daSkies2/shaders/clouds2/cloud_volume_mask.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/clouds2/cloud_volume_mask.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/cloud_volume_mask.dshl diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/cloudsBaseMSLighting.sh b/prog/gameLibs/daSkies2/shaders/clouds2/cloudsBaseMSLighting.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/clouds2/cloudsBaseMSLighting.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/cloudsBaseMSLighting.dshl diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/cloudsDensity.sh b/prog/gameLibs/daSkies2/shaders/clouds2/cloudsDensity.dshl similarity index 99% rename from prog/gameLibs/daSkies2/shaders/clouds2/cloudsDensity.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/cloudsDensity.dshl index 0c09bbe66..670b95463 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/cloudsDensity.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/cloudsDensity.dshl @@ -1,6 +1,6 @@ -include "clouds_weather.sh" -include "clouds_erosion_lut.sh" -include "clouds_alt_fraction.sh" +include "clouds_weather.dshl" +include "clouds_erosion_lut.dshl" +include "clouds_alt_fraction.dshl" texture gen_cloud_shape; texture gen_cloud_detail; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/cloudsLighting.sh b/prog/gameLibs/daSkies2/shaders/clouds2/cloudsLighting.dshl similarity index 98% rename from prog/gameLibs/daSkies2/shaders/clouds2/cloudsLighting.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/cloudsLighting.dshl index f19870a48..16cca6f80 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/cloudsLighting.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/cloudsLighting.dshl @@ -1,4 +1,4 @@ -include "cloudsBaseMSLighting.sh" +include "cloudsBaseMSLighting.dshl" float clouds_forward_eccentricity = 0.8; float clouds_back_eccentricity = -0.5;//clouds_back_eccentricity = -0.5 if we use constant lerp param. @@ -78,7 +78,7 @@ macro CLOUDS_MULTIPLE_SCATTERING(code) } endmacro -include "cloudsDensity.sh" +include "cloudsDensity.dshl" macro CLOUDS_LIGHTING_COMMON(code) CLOUDS_LIGHTING_COMMON_MATH(code) diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/cloudsShadowVolume.sh b/prog/gameLibs/daSkies2/shaders/clouds2/cloudsShadowVolume.dshl similarity index 97% rename from prog/gameLibs/daSkies2/shaders/clouds2/cloudsShadowVolume.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/cloudsShadowVolume.dshl index b626bbf82..4502b84ea 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/cloudsShadowVolume.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/cloudsShadowVolume.dshl @@ -1,4 +1,4 @@ -include "clouds_weather.sh" +include "clouds_weather.dshl" texture clouds_shadows_volume; macro INIT_CLOUDS_SHADOWS_VOLUME(code) diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_alt_fraction.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_alt_fraction.dshl similarity index 98% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_alt_fraction.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_alt_fraction.dshl index abf3b5f61..11b642d9b 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_alt_fraction.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_alt_fraction.dshl @@ -1,4 +1,4 @@ -include "clouds_hole_pos_tex.sh" +include "clouds_hole_pos_tex.dshl" float4 clouds_origin_offset; float clouds_start_altitude2; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_close_layer_outside.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_close_layer_outside.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_close_layer_outside.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_close_layer_outside.dshl diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_density_height_lut.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_density_height_lut.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_density_height_lut.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_density_height_lut.dshl diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_erosion_lut.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_erosion_lut.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_erosion_lut.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_erosion_lut.dshl diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_field_gen.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_field_gen.dshl similarity index 96% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_field_gen.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_field_gen.dshl index 8a09b60ad..e86e47898 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_field_gen.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_field_gen.dshl @@ -1,9 +1,9 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "distanceToClouds2.sh" -include "clouds_density_height_lut.sh" -include "cloudsDensity.sh" -include "writeToTex.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "distanceToClouds2.dshl" +include "clouds_density_height_lut.dshl" +include "cloudsDensity.dshl" +include "writeToTex.dshl" float4 clouds_field_res;//.xy - xz&y of res, .zw - xz&y of target res @@ -201,7 +201,7 @@ macro USE_GEN_CLOUD_FIELD(stage) } endmacro -include "bc_compression_inc.sh" +include "bc_compression_inc.dshl" shader gen_cloud_field_cmpr { USE_GEN_CLOUD_FIELD(cs) diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_hole_gen.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_hole_gen.dshl similarity index 99% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_hole_gen.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_hole_gen.dshl index 113dc0005..d296f7978 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_hole_gen.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_hole_gen.dshl @@ -1,6 +1,6 @@ -include "hardware_defines.sh" -include "cloudsShadowVolume.sh" -include "postfx_inc.sh" +include "hardware_defines.dshl" +include "cloudsShadowVolume.dshl" +include "postfx_inc.dshl" float4 clouds_hole_target_alt; float4 clouds_hole_light_dir; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_hole_pos_tex.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_hole_pos_tex.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_hole_pos_tex.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_hole_pos_tex.dshl diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_2d_gen.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_2d_gen.dshl similarity index 93% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_2d_gen.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_2d_gen.dshl index c5c5ff894..b0afdcc7a 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_2d_gen.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_2d_gen.dshl @@ -1,7 +1,7 @@ -include "sky_shader_global.sh" -include "writeToTex.sh" -include "cloudsShadowVolume.sh" -include "cloudsLighting.sh" +include "sky_shader_global.dshl" +include "writeToTex.dshl" +include "cloudsShadowVolume.dshl" +include "cloudsLighting.dshl" shader build_shadows_2d_ps diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_volume_gen.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_volume_gen.dshl similarity index 98% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_volume_gen.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_volume_gen.dshl index 0d26a70a5..b680978ec 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_volume_gen.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_shadow_volume_gen.dshl @@ -1,10 +1,10 @@ -include "cloudsLighting.sh" -include "cloudsShadowVolume.sh" -include "skyLight.sh" -//include "sky_shader_global.sh" +include "cloudsLighting.dshl" +include "cloudsShadowVolume.dshl" +include "skyLight.dshl" +//include "sky_shader_global.dshl" //same as: -include "hardware_defines.sh" -include "writeToTex.sh" +include "hardware_defines.dshl" +include "writeToTex.dshl" hlsl { float clampedPow(float X,float Y) { return pow(max(abs(X),0.000001f),Y); } diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_sun_light.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_sun_light.dshl similarity index 96% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_sun_light.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_sun_light.dshl index 49fad3601..4fa27b83e 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_sun_light.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_sun_light.dshl @@ -1,4 +1,4 @@ -include "clouds_alt_fraction.sh" +include "clouds_alt_fraction.dshl" texture clouds_light_color; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_tiled_dist.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_tiled_dist.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_tiled_dist.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_tiled_dist.dshl diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_trace_ray.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_trace_ray.dshl similarity index 96% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_trace_ray.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_trace_ray.dshl index ef4b8baad..bb97aa82c 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_trace_ray.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_trace_ray.dshl @@ -1,7 +1,7 @@ -include "hardware_defines.sh" -include "cloudsDensity.sh" -include "base_distance_to_clouds.sh" -include "writeToTex.sh" +include "hardware_defines.dshl" +include "cloudsDensity.dshl" +include "base_distance_to_clouds.dshl" +include "writeToTex.dshl" float skies_planet_radius = 6360; float4 world_view_pos; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_volume_gen.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_volume_gen.dshl similarity index 96% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_volume_gen.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_volume_gen.dshl index 985ae9490..93bced8d0 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_volume_gen.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_volume_gen.dshl @@ -1,7 +1,7 @@ -include "shader_global.sh" -include "viewVecVS.sh" -include "cloudsDensity.sh" -include "writeToTex.sh" +include "shader_global.dshl" +include "viewVecVS.dshl" +include "cloudsDensity.dshl" +include "writeToTex.dshl" int skies_has_clouds=1; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/clouds_weather.sh b/prog/gameLibs/daSkies2/shaders/clouds2/clouds_weather.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/clouds2/clouds_weather.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/clouds_weather.dshl diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/compress_voltex.sh b/prog/gameLibs/daSkies2/shaders/clouds2/compress_voltex.dshl similarity index 97% rename from prog/gameLibs/daSkies2/shaders/clouds2/compress_voltex.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/compress_voltex.dshl index 5d4662b73..949ecdb5e 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/compress_voltex.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/compress_voltex.dshl @@ -1,6 +1,6 @@ -include "hardware_defines.sh" -include "bc_compression_inc.sh" -include "writeToTex.sh" +include "hardware_defines.dshl" +include "bc_compression_inc.dshl" +include "writeToTex.dshl" texture compress_voltex_bc4_source; texture clouds_gen_mips_3d_source; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/daClouds2.sh b/prog/gameLibs/daSkies2/shaders/clouds2/daClouds2.dshl similarity index 99% rename from prog/gameLibs/daSkies2/shaders/clouds2/daClouds2.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/daClouds2.dshl index 2fbf6981b..0c65f6bc0 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/daClouds2.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/daClouds2.dshl @@ -1,17 +1,17 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "distanceToClouds2.sh" -include "cloudsShadowVolume.sh" -include "clouds_density_height_lut.sh" -include "clouds_tiled_dist.sh" -include "clouds_close_layer_outside.sh" -include "cloudsDensity.sh" -include "cloudsLighting.sh" -include "clouds_sun_light.sh" -include "panorama.sh" -include "skies_special_vision.sh" -include "renderSkiesInc.sh" -include "tonemapHelpers/use_full_tonemap_lut_inc.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "distanceToClouds2.dshl" +include "cloudsShadowVolume.dshl" +include "clouds_density_height_lut.dshl" +include "clouds_tiled_dist.dshl" +include "clouds_close_layer_outside.dshl" +include "cloudsDensity.dshl" +include "cloudsLighting.dshl" +include "clouds_sun_light.dshl" +include "panorama.dshl" +include "skies_special_vision.dshl" +include "renderSkiesInc.dshl" +include "tonemapHelpers/use_full_tonemap_lut_inc.dshl" texture clouds_field_volume_low; float4 clouds_field_res;//.xy - xz&y of res, .zw - xz&y of target res @@ -1049,7 +1049,7 @@ shader clouds2_temporal_cs, clouds2_close_temporal_cs//, clouds2_direct_cs } texture sky_panorama_tex; -include "use_strata_clouds.sh" +include "use_strata_clouds.dshl" float4 clouds_panorama_subpixel; float4 clouds_panorama_temp_res; float4 clouds_panorama_tex_res; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/daCloudsApply.sh b/prog/gameLibs/daSkies2/shaders/clouds2/daCloudsApply.dshl similarity index 97% rename from prog/gameLibs/daSkies2/shaders/clouds2/daCloudsApply.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/daCloudsApply.dshl index be07a9b3f..25fd3fc67 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/daCloudsApply.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/daCloudsApply.dshl @@ -1,12 +1,12 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "clouds_tiled_dist.sh" -include "clouds_close_layer_outside.sh" -include "skies_special_vision.sh" -include "distanceToClouds2.sh" -include "vr_reprojection.sh" -include "use_custom_fog_sky.sh" -include "flexible_scale_rasterization.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "clouds_tiled_dist.dshl" +include "clouds_close_layer_outside.dshl" +include "skies_special_vision.dshl" +include "distanceToClouds2.dshl" +include "vr_reprojection.dshl" +include "use_custom_fog_sky.dshl" +include "flexible_scale_rasterization.dshl" float min_ground_offset; texture clouds_color; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/daCloudsTaa.sh b/prog/gameLibs/daSkies2/shaders/clouds2/daCloudsTaa.dshl similarity index 98% rename from prog/gameLibs/daSkies2/shaders/clouds2/daCloudsTaa.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/daCloudsTaa.dshl index 0e386a120..585d8f098 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/daCloudsTaa.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/daCloudsTaa.dshl @@ -1,8 +1,8 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "distanceToClouds2.sh" -include "clouds_tiled_dist.sh" -include "clouds_close_layer_outside.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "distanceToClouds2.dshl" +include "clouds_tiled_dist.dshl" +include "clouds_close_layer_outside.dshl" float4 globtm_no_ofs_psf_0; float4 globtm_no_ofs_psf_1; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/distanceToClouds2.sh b/prog/gameLibs/daSkies2/shaders/clouds2/distanceToClouds2.dshl similarity index 96% rename from prog/gameLibs/daSkies2/shaders/clouds2/distanceToClouds2.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/distanceToClouds2.dshl index 1dcc866cf..d772399a0 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/distanceToClouds2.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/distanceToClouds2.dshl @@ -1,4 +1,4 @@ -include "base_distance_to_clouds.sh" +include "base_distance_to_clouds.dshl" macro DISTANCE_TO_CLOUDS2(code) BASE_DISTANCE_TO_CLOUDS(code) diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/downsampleCloudsField.sh b/prog/gameLibs/daSkies2/shaders/clouds2/downsampleCloudsField.dshl similarity index 98% rename from prog/gameLibs/daSkies2/shaders/clouds2/downsampleCloudsField.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/downsampleCloudsField.dshl index b701ee771..b67dd24ae 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/downsampleCloudsField.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/downsampleCloudsField.dshl @@ -1,8 +1,8 @@ -include "sky_shader_global.sh" -include "clouds_tiled_dist.sh" -include "writeToTex.sh" -include "globtm.sh" -include "clouds_hole_pos_tex.sh" +include "sky_shader_global.dshl" +include "clouds_tiled_dist.dshl" +include "writeToTex.dshl" +include "globtm.dshl" +include "clouds_hole_pos_tex.dshl" float4 clouds_field_res;//.xy - xz&y of res, .zw - xz&y of target res texture clouds_field_volume; @@ -111,10 +111,10 @@ shader downsample_cloud_field_ps } -include "distanceToClouds2.sh" -include "clouds_weather.sh" -include "viewVecVS.sh" -include "frustum.sh" +include "distanceToClouds2.dshl" +include "clouds_weather.dshl" +include "viewVecVS.dshl" +include "frustum.dshl" texture clouds_field_volume_low; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/gen_clouds_lut.sh b/prog/gameLibs/daSkies2/shaders/clouds2/gen_clouds_lut.dshl similarity index 98% rename from prog/gameLibs/daSkies2/shaders/clouds2/gen_clouds_lut.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/gen_clouds_lut.dshl index a115f5b47..692bc4721 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/gen_clouds_lut.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/gen_clouds_lut.dshl @@ -1,7 +1,7 @@ -include "sky_shader_global.sh" -include "clouds_density_height_lut.sh" -include "clouds_alt_fraction.sh" -include "writeToTex.sh" +include "sky_shader_global.dshl" +include "clouds_density_height_lut.dshl" +include "clouds_alt_fraction.dshl" +include "writeToTex.dshl" float4 clouds_height_fractions = (1.25, 0, 3, -2); float4 clouds_layers_types = (0,1, 0, 0.5); @@ -149,8 +149,8 @@ float clouds_ambient_desaturation = 0.5; texture skies_irradiance_texture; texture skies_transmittance_texture; -include "atmosphere.sh" -include "moon.sh" +include "atmosphere.dshl" +include "moon.dshl" float4 skies_sun_moon_effect; macro GEN_CLOUDS_LIGHTING(code) TOTAL_CLOUDS_MIN_MAX() @@ -244,7 +244,7 @@ shader gen_clouds_light_texture_ps } //we actually not use it at all -include "clouds_erosion_lut.sh" +include "clouds_erosion_lut.dshl" shader gen_clouds_erosion_lut//todo: use compute where compute is available { cull_mode = none; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/gen_weather.sh b/prog/gameLibs/daSkies2/shaders/clouds2/gen_weather.dshl similarity index 99% rename from prog/gameLibs/daSkies2/shaders/clouds2/gen_weather.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/gen_weather.dshl index 1e8937d64..3b059bca6 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/gen_weather.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/gen_weather.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" float clouds_layer1_freq = 2; float clouds_layer2_freq = 4; diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/generate_clouds2.sh b/prog/gameLibs/daSkies2/shaders/clouds2/generate_clouds2.dshl similarity index 99% rename from prog/gameLibs/daSkies2/shaders/clouds2/generate_clouds2.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/generate_clouds2.dshl index d6d8803ce..2e29490a4 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/generate_clouds2.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/generate_clouds2.dshl @@ -1,5 +1,5 @@ -include "hardware_defines.sh" -include "writeToTex.sh" +include "hardware_defines.dshl" +include "writeToTex.dshl" //changing this parameters would cause to recalculate noise //if we store noise as asset (texture), it won't be possible to change them diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/strata_clouds.sh b/prog/gameLibs/daSkies2/shaders/clouds2/strata_clouds.dshl similarity index 90% rename from prog/gameLibs/daSkies2/shaders/clouds2/strata_clouds.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/strata_clouds.dshl index 672feebd4..7ccaf10eb 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds2/strata_clouds.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds2/strata_clouds.dshl @@ -1,9 +1,9 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "panorama.sh" -include "clouds_sun_light.sh" -include "skies_special_vision.sh" -include "use_strata_clouds.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "panorama.dshl" +include "clouds_sun_light.dshl" +include "skies_special_vision.dshl" +include "use_strata_clouds.dshl" shader strata_clouds//, strata_clouds_panorama { diff --git a/prog/gameLibs/daSkies2/shaders/clouds2/use_strata_clouds.sh b/prog/gameLibs/daSkies2/shaders/clouds2/use_strata_clouds.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/clouds2/use_strata_clouds.sh rename to prog/gameLibs/daSkies2/shaders/clouds2/use_strata_clouds.dshl diff --git a/prog/gameLibs/daSkies2/shaders/clouds_shadow.sh b/prog/gameLibs/daSkies2/shaders/clouds_shadow.dshl similarity index 98% rename from prog/gameLibs/daSkies2/shaders/clouds_shadow.sh rename to prog/gameLibs/daSkies2/shaders/clouds_shadow.dshl index 576ef1c44..527cb98dd 100644 --- a/prog/gameLibs/daSkies2/shaders/clouds_shadow.sh +++ b/prog/gameLibs/daSkies2/shaders/clouds_shadow.dshl @@ -1,5 +1,5 @@ -include "clouds2/cloudsShadowVolume.sh" -include "clouds2/clouds_alt_fraction.sh" +include "clouds2/cloudsShadowVolume.dshl" +include "clouds2/clouds_alt_fraction.dshl" int skies_use_2d_shadows; diff --git a/prog/gameLibs/render/shaders/ssr_common_use.sh b/prog/gameLibs/daSkies2/shaders/clouds_vars.dshl similarity index 100% rename from prog/gameLibs/render/shaders/ssr_common_use.sh rename to prog/gameLibs/daSkies2/shaders/clouds_vars.dshl diff --git a/prog/gameLibs/daSkies2/shaders/compress_panorama.sh b/prog/gameLibs/daSkies2/shaders/compress_panorama.dshl similarity index 96% rename from prog/gameLibs/daSkies2/shaders/compress_panorama.sh rename to prog/gameLibs/daSkies2/shaders/compress_panorama.dshl index 36b61c81d..5f7adeca3 100644 --- a/prog/gameLibs/daSkies2/shaders/compress_panorama.sh +++ b/prog/gameLibs/daSkies2/shaders/compress_panorama.dshl @@ -1,7 +1,7 @@ -include "shader_global.sh" -include "etc2_compression_inc.sh" -include "bc_compression_inc.sh" -include "rgbm_inc.sh" +include "shader_global.dshl" +include "etc2_compression_inc.dshl" +include "bc_compression_inc.dshl" +include "rgbm_inc.dshl" texture src_tex; float src_mip = 0; diff --git a/prog/gameLibs/daSkies2/shaders/daSkiesList.blk b/prog/gameLibs/daSkies2/shaders/daSkiesList.blk index ccf04a800..e5358e751 100644 --- a/prog/gameLibs/daSkies2/shaders/daSkiesList.blk +++ b/prog/gameLibs/daSkies2/shaders/daSkiesList.blk @@ -1,26 +1,26 @@ - file:t = "skies2/query_rain_map.sh" - file:t = "skies2/render_skies2.sh" - file:t = "skies2/precompute_skies_ms.sh" - file:t = "skies2/prepareAltScattering.sh" + file:t = "skies2/query_rain_map.dshl" + file:t = "skies2/render_skies2.dshl" + file:t = "skies2/precompute_skies_ms.dshl" + file:t = "skies2/prepareAltScattering.dshl" - file:t = "clouds2/clouds_trace_ray.sh" - file:t = "clouds2/generate_clouds2.sh" - file:t = "clouds2/gen_weather.sh" - file:t = "clouds2/gen_clouds_lut.sh" - file:t = "clouds2/daClouds2.sh" - file:t = "clouds2/daCloudsTaa.sh" - file:t = "clouds2/daCloudsApply.sh" - file:t = "clouds2/downsampleCloudsField.sh" - file:t = "clouds2/clouds_field_gen.sh" - file:t = "clouds2/clouds_shadow_volume_gen.sh" - file:t = "clouds2/compress_voltex.sh" - file:t = "clouds2/clouds_volume_gen.sh" - file:t = "clouds2/clouds_hole_gen.sh" - file:t = "clouds2/clouds_shadow_2d_gen.sh" - file:t = "clouds2/strata_clouds.sh" - //file:t = "render_skies.sh"//to be removed - //file:t = "precompute_skies.sh"//to be removed + file:t = "clouds2/clouds_trace_ray.dshl" + file:t = "clouds2/generate_clouds2.dshl" + file:t = "clouds2/gen_weather.dshl" + file:t = "clouds2/gen_clouds_lut.dshl" + file:t = "clouds2/daClouds2.dshl" + file:t = "clouds2/daCloudsTaa.dshl" + file:t = "clouds2/daCloudsApply.dshl" + file:t = "clouds2/downsampleCloudsField.dshl" + file:t = "clouds2/clouds_field_gen.dshl" + file:t = "clouds2/clouds_shadow_volume_gen.dshl" + file:t = "clouds2/compress_voltex.dshl" + file:t = "clouds2/clouds_volume_gen.dshl" + file:t = "clouds2/clouds_hole_gen.dshl" + file:t = "clouds2/clouds_shadow_2d_gen.dshl" + file:t = "clouds2/strata_clouds.dshl" + //file:t = "render_skies.dshl"//to be removed + //file:t = "precompute_skies.dshl"//to be removed - file:t = "daStars.sh" - file:t = "applyPanorama.sh" - file:t = "applySkies.sh" + file:t = "daStars.dshl" + file:t = "applyPanorama.dshl" + file:t = "applySkies.dshl" diff --git a/prog/gameLibs/daSkies2/shaders/daStars.sh b/prog/gameLibs/daSkies2/shaders/daStars.dshl similarity index 97% rename from prog/gameLibs/daSkies2/shaders/daStars.sh rename to prog/gameLibs/daSkies2/shaders/daStars.dshl index 9b3fa09a9..8eb391779 100644 --- a/prog/gameLibs/daSkies2/shaders/daStars.sh +++ b/prog/gameLibs/daSkies2/shaders/daStars.dshl @@ -1,11 +1,11 @@ -include "sky_shader_global.sh" -include "clouds2/clouds_alt_fraction.sh" -include "moon.sh" -include "panorama.sh" -include "brunetonSkies.sh" -include "skies_special_vision.sh" -include "vr_reprojection.sh" -include "use_custom_fog_sky.sh" +include "sky_shader_global.dshl" +include "clouds2/clouds_alt_fraction.dshl" +include "moon.dshl" +include "panorama.dshl" +include "brunetonSkies.dshl" +include "skies_special_vision.dshl" +include "vr_reprojection.dshl" +include "use_custom_fog_sky.dshl" float star_intensity = 1; float stars_scale = 1; diff --git a/prog/gameLibs/daSkies2/shaders/moon.sh b/prog/gameLibs/daSkies2/shaders/moon.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/moon.sh rename to prog/gameLibs/daSkies2/shaders/moon.dshl diff --git a/prog/gameLibs/daSkies2/shaders/panorama.sh b/prog/gameLibs/daSkies2/shaders/panorama.dshl similarity index 99% rename from prog/gameLibs/daSkies2/shaders/panorama.sh rename to prog/gameLibs/daSkies2/shaders/panorama.dshl index 898cb5e42..f28b6b67b 100644 --- a/prog/gameLibs/daSkies2/shaders/panorama.sh +++ b/prog/gameLibs/daSkies2/shaders/panorama.dshl @@ -1,4 +1,4 @@ -//include "clouds_vars.sh" +//include "clouds_vars.dshl" float4 panoramaTC = (0,0,1,1); texture clouds_alpha_panorama_tex; diff --git a/prog/gameLibs/daSkies2/shaders/renderSkiesInc.sh b/prog/gameLibs/daSkies2/shaders/renderSkiesInc.dshl similarity index 92% rename from prog/gameLibs/daSkies2/shaders/renderSkiesInc.sh rename to prog/gameLibs/daSkies2/shaders/renderSkiesInc.dshl index 831fb0abd..3adb04cd8 100644 --- a/prog/gameLibs/daSkies2/shaders/renderSkiesInc.sh +++ b/prog/gameLibs/daSkies2/shaders/renderSkiesInc.dshl @@ -1,10 +1,10 @@ -include "hardware_defines.sh" -include "sky_shader_global.sh" -include "skyLight.sh" -include "moon.sh" -include "brunetonSkies.sh" -include "atmosphere.sh" -include_optional "sky_ground_color.sh" +include "hardware_defines.dshl" +include "sky_shader_global.dshl" +include "skyLight.dshl" +include "moon.dshl" +include "brunetonSkies.dshl" +include "atmosphere.dshl" +include_optional "sky_ground_color.dshl" //float4 skies_world_view_pos; //float render_sun = 1; diff --git a/prog/gameLibs/daSkies2/shaders/skies2/precompute_skies_ms.sh b/prog/gameLibs/daSkies2/shaders/skies2/precompute_skies_ms.dshl similarity index 99% rename from prog/gameLibs/daSkies2/shaders/skies2/precompute_skies_ms.sh rename to prog/gameLibs/daSkies2/shaders/skies2/precompute_skies_ms.dshl index f3db90582..b46c53bec 100644 --- a/prog/gameLibs/daSkies2/shaders/skies2/precompute_skies_ms.sh +++ b/prog/gameLibs/daSkies2/shaders/skies2/precompute_skies_ms.dshl @@ -1,7 +1,7 @@ -include "writeToTex.sh" -include "atmosphere.sh" +include "writeToTex.dshl" +include "atmosphere.dshl" float skies_planet_radius = 6360; -include "statistical_clouds_shadow.sh" +include "statistical_clouds_shadow.dshl" texture skies_transmittance_texture; texture skies_ms_texture; diff --git a/prog/gameLibs/daSkies2/shaders/skies2/prepareAltScattering.sh b/prog/gameLibs/daSkies2/shaders/skies2/prepareAltScattering.dshl similarity index 99% rename from prog/gameLibs/daSkies2/shaders/skies2/prepareAltScattering.sh rename to prog/gameLibs/daSkies2/shaders/skies2/prepareAltScattering.dshl index 07111cee2..5b0a8bc4a 100644 --- a/prog/gameLibs/daSkies2/shaders/skies2/prepareAltScattering.sh +++ b/prog/gameLibs/daSkies2/shaders/skies2/prepareAltScattering.dshl @@ -1,9 +1,9 @@ -include "writeToTex.sh" -include "atmosphere.sh" -include "sky_shader_global.sh" -include "brunetonSkies.sh" -include "statistical_clouds_shadow.sh" -include "skies_rainmap.sh" +include "writeToTex.dshl" +include "atmosphere.dshl" +include "sky_shader_global.dshl" +include "brunetonSkies.dshl" +include "statistical_clouds_shadow.dshl" +include "skies_rainmap.dshl" float4 prepare_origin; float4 prepare_sun_light_dir; @@ -111,9 +111,9 @@ shader skies_prepare_transmittance_for_altitude_cs compile("cs_5_0", "skies_gen_cs") } -include "viewVecVS.sh" -include "skies_shadows.sh" -include "panorama.sh" +include "viewVecVS.dshl" +include "skies_shadows.dshl" +include "panorama.dshl" texture prev_skies_frustum_scattering; int skies_frustum_scattering_frame; float4 prev_globtm_no_ofs_psf_0; diff --git a/prog/gameLibs/daSkies2/shaders/skies2/query_rain_map.sh b/prog/gameLibs/daSkies2/shaders/skies2/query_rain_map.dshl similarity index 86% rename from prog/gameLibs/daSkies2/shaders/skies2/query_rain_map.sh rename to prog/gameLibs/daSkies2/shaders/skies2/query_rain_map.dshl index 7ba127bcd..2a1f70e58 100644 --- a/prog/gameLibs/daSkies2/shaders/skies2/query_rain_map.sh +++ b/prog/gameLibs/daSkies2/shaders/skies2/query_rain_map.dshl @@ -1,6 +1,6 @@ -include "hardware_defines.sh" -include "skies_rainmap.sh" -include "writeToTex.sh" +include "hardware_defines.dshl" +include "skies_rainmap.dshl" +include "writeToTex.dshl" int trace_rays_count; diff --git a/prog/gameLibs/daSkies2/shaders/skies2/render_skies2.sh b/prog/gameLibs/daSkies2/shaders/skies2/render_skies2.dshl similarity index 98% rename from prog/gameLibs/daSkies2/shaders/skies2/render_skies2.sh rename to prog/gameLibs/daSkies2/shaders/skies2/render_skies2.dshl index 7799edebb..6dab22110 100644 --- a/prog/gameLibs/daSkies2/shaders/skies2/render_skies2.sh +++ b/prog/gameLibs/daSkies2/shaders/skies2/render_skies2.dshl @@ -1,13 +1,13 @@ -include "sky_shader_global.sh" -include "renderSkiesInc.sh" -include "postfx_inc.sh" -include "viewVecVS.sh" -include "roughToMip.sh" -include "panorama.sh" -include "skies_special_vision.sh" -include "skies_shadows.sh" -include "skies_rainmap.sh" -include "use_custom_fog_sky.sh" +include "sky_shader_global.dshl" +include "renderSkiesInc.dshl" +include "postfx_inc.dshl" +include "viewVecVS.dshl" +include "roughToMip.dshl" +include "panorama.dshl" +include "skies_special_vision.dshl" +include "skies_shadows.dshl" +include "skies_rainmap.dshl" +include "use_custom_fog_sky.dshl" float4 prepare_resolution = (1, 1, 1, 1); diff --git a/prog/gameLibs/daSkies2/shaders/skies2/skies_rainmap.sh b/prog/gameLibs/daSkies2/shaders/skies2/skies_rainmap.dshl similarity index 96% rename from prog/gameLibs/daSkies2/shaders/skies2/skies_rainmap.sh rename to prog/gameLibs/daSkies2/shaders/skies2/skies_rainmap.dshl index 0d5673ff3..031592f71 100644 --- a/prog/gameLibs/daSkies2/shaders/skies2/skies_rainmap.sh +++ b/prog/gameLibs/daSkies2/shaders/skies2/skies_rainmap.dshl @@ -1,5 +1,5 @@ -include "clouds2/clouds_weather.sh" -include "clouds2/clouds_alt_fraction.sh" +include "clouds2/clouds_weather.dshl" +include "clouds2/clouds_alt_fraction.dshl" texture clouds_weather_texture; float skies_rain_strength = 0; diff --git a/prog/gameLibs/daSkies2/shaders/skies_shadows.sh b/prog/gameLibs/daSkies2/shaders/skies_shadows.dshl similarity index 90% rename from prog/gameLibs/daSkies2/shaders/skies_shadows.sh rename to prog/gameLibs/daSkies2/shaders/skies_shadows.dshl index f73222571..a0b49f46e 100644 --- a/prog/gameLibs/daSkies2/shaders/skies_shadows.sh +++ b/prog/gameLibs/daSkies2/shaders/skies_shadows.dshl @@ -1,7 +1,7 @@ //godrays -include "clouds_shadow.sh" -include "statistical_clouds_shadow.sh" -include_optional "project_skies_shadows.sh" +include "clouds_shadow.dshl" +include "statistical_clouds_shadow.dshl" +include_optional "project_skies_shadows.dshl" define_macro_if_not_defined PROJECT_SKIES_SHADOWS(code) hlsl(code) { diff --git a/prog/gameLibs/daSkies2/shaders/skies_special_vision.sh b/prog/gameLibs/daSkies2/shaders/skies_special_vision.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/skies_special_vision.sh rename to prog/gameLibs/daSkies2/shaders/skies_special_vision.dshl diff --git a/prog/gameLibs/daSkies2/shaders/sky_shadows.sh b/prog/gameLibs/daSkies2/shaders/sky_shadows.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/sky_shadows.sh rename to prog/gameLibs/daSkies2/shaders/sky_shadows.dshl diff --git a/prog/gameLibs/daSkies2/shaders/statistical_clouds_shadow.sh b/prog/gameLibs/daSkies2/shaders/statistical_clouds_shadow.dshl similarity index 93% rename from prog/gameLibs/daSkies2/shaders/statistical_clouds_shadow.sh rename to prog/gameLibs/daSkies2/shaders/statistical_clouds_shadow.dshl index 327fe92d5..8db1972cf 100644 --- a/prog/gameLibs/daSkies2/shaders/statistical_clouds_shadow.sh +++ b/prog/gameLibs/daSkies2/shaders/statistical_clouds_shadow.dshl @@ -1,6 +1,6 @@ -include "clouds2/clouds_alt_fraction.sh" -include "clouds2/cloudsBaseMSLighting.sh" +include "clouds2/clouds_alt_fraction.dshl" +include "clouds2/cloudsBaseMSLighting.dshl" float clouds_shadow_coverage; diff --git a/prog/gameLibs/daSkies2/shaders/use_custom_fog_sky.sh b/prog/gameLibs/daSkies2/shaders/use_custom_fog_sky.dshl similarity index 100% rename from prog/gameLibs/daSkies2/shaders/use_custom_fog_sky.sh rename to prog/gameLibs/daSkies2/shaders/use_custom_fog_sky.dshl diff --git a/prog/gameLibs/dasModules/common/scriptsLoader.cpp b/prog/gameLibs/dasModules/common/scriptsLoader.cpp index b2d9432cd..20f65cef3 100644 --- a/prog/gameLibs/dasModules/common/scriptsLoader.cpp +++ b/prog/gameLibs/dasModules/common/scriptsLoader.cpp @@ -35,8 +35,7 @@ void DasScripts::fillSharedModules(TLoadedScript &scrip { for (das::ModuleInfo &moduleInfo : req) { - if (eastl::find_if(script.filesOpened.begin(), script.filesOpened.end(), - [&](auto it) { return it.first == moduleInfo.fileName; }) == script.filesOpened.end()) + if (script.filesOpened.find_as(moduleInfo.fileName) == script.filesOpened.end()) { if (globalFileAccess) { diff --git a/prog/gameLibs/ecs/phys/animCharFastPhysES.cpp.gen.es.cpp b/prog/gameLibs/ecs/phys/animCharFastPhysES.cpp.gen.es.cpp index 6e5889d70..6e71760db 100644 --- a/prog/gameLibs/ecs/phys/animCharFastPhysES.cpp.gen.es.cpp +++ b/prog/gameLibs/ecs/phys/animCharFastPhysES.cpp.gen.es.cpp @@ -89,16 +89,15 @@ static ecs::EntitySystemDesc animchar_fast_phys_destroy_es_event_handler_es_desc ); static constexpr ecs::ComponentDesc get_animchar_by_name_ecs_query_comps[] = { -//start of 1 rw components at [0] - {ECS_HASH("animchar__res"), ecs::ComponentTypeInfo()}, -//start of 1 ro components at [1] - {ECS_HASH("eid"), ecs::ComponentTypeInfo()} +//start of 2 ro components at [0] + {ECS_HASH("eid"), ecs::ComponentTypeInfo()}, + {ECS_HASH("animchar__res"), ecs::ComponentTypeInfo()} }; static ecs::CompileTimeQueryDesc get_animchar_by_name_ecs_query_desc ( "get_animchar_by_name_ecs_query", - make_span(get_animchar_by_name_ecs_query_comps+0, 1)/*rw*/, - make_span(get_animchar_by_name_ecs_query_comps+1, 1)/*ro*/, + empty_span(), + make_span(get_animchar_by_name_ecs_query_comps+0, 2)/*ro*/, empty_span(), empty_span()); template @@ -111,7 +110,7 @@ inline void get_animchar_by_name_ecs_query(Callable function) { function( ECS_RO_COMP(get_animchar_by_name_ecs_query_comps, "eid", ecs::EntityId) - , ECS_RW_COMP(get_animchar_by_name_ecs_query_comps, "animchar__res", ecs::string) + , ECS_RO_COMP(get_animchar_by_name_ecs_query_comps, "animchar__res", ecs::string) ); }while (++comp != compE); diff --git a/prog/gameLibs/ecs/phys/animCharFastPhysES.cpp.inl b/prog/gameLibs/ecs/phys/animCharFastPhysES.cpp.inl index 598ba81dc..2494703bf 100644 --- a/prog/gameLibs/ecs/phys/animCharFastPhysES.cpp.inl +++ b/prog/gameLibs/ecs/phys/animCharFastPhysES.cpp.inl @@ -10,7 +10,8 @@ #include #include #include -#include +#include +#include #include @@ -94,10 +95,10 @@ static void animchar_fast_phys_destroy_es_event_handler(const ecs::Event &, Anim } } -eastl::vector_set debugAnimCharsSet; +static dag::VectorSet debugAnimCharsSet; #define TEMPLATE_NAME "animchar_fast_phys_debug_render" const char *template_name = TEMPLATE_NAME; -void createTemplate() +static void createTemplate() { ecs::ComponentsMap map; map[ECS_HASH(TEMPLATE_NAME)] = ecs::Tag(); @@ -107,7 +108,7 @@ void createTemplate() g_entity_mgr->instantiateTemplate(g_entity_mgr->buildTemplateIdByName(template_name)); } -void removeSubTemplateAsync(ecs::EntityId eid) +static void removeSubTemplateAsync(ecs::EntityId eid) { if (const char *fromTemplate = g_entity_mgr->getEntityTemplateName(eid)) { @@ -118,7 +119,7 @@ void removeSubTemplateAsync(ecs::EntityId eid) } } -void addSubTemplateAsync(ecs::EntityId eid) +static void addSubTemplateAsync(ecs::EntityId eid) { if (const char *fromTemplate = g_entity_mgr->getEntityTemplateName(eid)) { @@ -133,12 +134,12 @@ template static void get_animchar_by_name_ecs_query(Callable c); -void toggleDebugAnimChar(eastl::string &str) +static void toggleDebugAnimChar(const eastl::string &str) { - auto it = debugAnimCharsSet.find(str); + auto it = debugAnimCharsSet.find(str_hash_fnv1(str.c_str())); if (it != debugAnimCharsSet.end()) { - get_animchar_by_name_ecs_query([&](ecs::EntityId eid, ecs::string &animchar__res) { + get_animchar_by_name_ecs_query([&](ecs::EntityId eid, const ecs::string &animchar__res) { if (animchar__res == str) removeSubTemplateAsync(eid); }); @@ -146,21 +147,20 @@ void toggleDebugAnimChar(eastl::string &str) } else { - get_animchar_by_name_ecs_query([&](ecs::EntityId eid, ecs::string &animchar__res) { + get_animchar_by_name_ecs_query([&](ecs::EntityId eid, const ecs::string &animchar__res) { if (animchar__res == str) addSubTemplateAsync(eid); }); - debugAnimCharsSet.insert(str); + debugAnimCharsSet.insert(str_hash_fnv1(str.c_str())); } } -void resetDebugAnimChars() +static void resetDebugAnimChars() { - for (auto it = debugAnimCharsSet.begin(); it != debugAnimCharsSet.end(); ++it) + for (auto &hash : debugAnimCharsSet) { - eastl::string str = *it; - get_animchar_by_name_ecs_query([&](ecs::EntityId eid, ecs::string &animchar__res) { - if (animchar__res == str) + get_animchar_by_name_ecs_query([&](ecs::EntityId eid, const ecs::string &animchar__res) { + if (str_hash_fnv1(animchar__res.c_str()) == hash) removeSubTemplateAsync(eid); }); } @@ -192,7 +192,7 @@ static bool fastphys_console_handler(const char *argv[], int argc) { if (argc > 1) { - eastl::string resName(argv[1]); + const eastl::string resName(argv[1]); toggleDebugAnimChar(resName); } else diff --git a/prog/gameLibs/fftWater/shaders/fft.sh b/prog/gameLibs/fftWater/shaders/fft.dshl similarity index 99% rename from prog/gameLibs/fftWater/shaders/fft.sh rename to prog/gameLibs/fftWater/shaders/fft.dshl index e32979aef..d9fe05e60 100644 --- a/prog/gameLibs/fftWater/shaders/fft.sh +++ b/prog/gameLibs/fftWater/shaders/fft.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" float current_water_time = 0; int fft_size = 128; diff --git a/prog/gameLibs/fftWater/shaders/fft_cs.sh b/prog/gameLibs/fftWater/shaders/fft_cs.dshl similarity index 71% rename from prog/gameLibs/fftWater/shaders/fft_cs.sh rename to prog/gameLibs/fftWater/shaders/fft_cs.dshl index 3467c74c1..2de08832b 100644 --- a/prog/gameLibs/fftWater/shaders/fft_cs.sh +++ b/prog/gameLibs/fftWater/shaders/fft_cs.dshl @@ -1,4 +1,4 @@ -include "fft_cs_same_size.sh" +include "fft_cs_same_size.dshl" hlsl(cs) { //no defaults, replace in your earlier folder with something like diff --git a/prog/gameLibs/fftWater/shaders/fft_cs_compression.sh b/prog/gameLibs/fftWater/shaders/fft_cs_compression.dshl similarity index 100% rename from prog/gameLibs/fftWater/shaders/fft_cs_compression.sh rename to prog/gameLibs/fftWater/shaders/fft_cs_compression.dshl diff --git a/prog/gameLibs/fftWater/shaders/fft_cs_defaults.sh b/prog/gameLibs/fftWater/shaders/fft_cs_defaults.dshl similarity index 100% rename from prog/gameLibs/fftWater/shaders/fft_cs_defaults.sh rename to prog/gameLibs/fftWater/shaders/fft_cs_defaults.dshl diff --git a/prog/gameLibs/fftWater/shaders/fft_cs_dif_size.sh b/prog/gameLibs/fftWater/shaders/fft_cs_dif_size.dshl similarity index 99% rename from prog/gameLibs/fftWater/shaders/fft_cs_dif_size.sh rename to prog/gameLibs/fftWater/shaders/fft_cs_dif_size.dshl index 921da5e20..4004801f5 100644 --- a/prog/gameLibs/fftWater/shaders/fft_cs_dif_size.sh +++ b/prog/gameLibs/fftWater/shaders/fft_cs_dif_size.dshl @@ -1,5 +1,5 @@ -include "fft_cs_defaults.sh" -include "fft_cs_compression.sh" +include "fft_cs_defaults.dshl" +include "fft_cs_compression.dshl" macro CBUFFER() hlsl(cs) { diff --git a/prog/gameLibs/fftWater/shaders/fft_cs_same_size.sh b/prog/gameLibs/fftWater/shaders/fft_cs_same_size.dshl similarity index 99% rename from prog/gameLibs/fftWater/shaders/fft_cs_same_size.sh rename to prog/gameLibs/fftWater/shaders/fft_cs_same_size.dshl index 86469548c..dd8e6c867 100644 --- a/prog/gameLibs/fftWater/shaders/fft_cs_same_size.sh +++ b/prog/gameLibs/fftWater/shaders/fft_cs_same_size.dshl @@ -1,9 +1,9 @@ //this is optimized for same size (in one dispatch) // techically it still workds with different sizes dispatches, but will be sub-optimal -include "../../render/shaders/hardware_defines.sh" -include "fft_cs_defaults.sh" -include "fft_cs_compression.sh" +include "../../render/shaders/hardware_defines.dshl" +include "fft_cs_defaults.dshl" +include "fft_cs_compression.dshl" int fft_spectrum = 0; interval fft_spectrum : phillips < 1, unified_directional; diff --git a/prog/gameLibs/fftWater/shaders/shore.sh b/prog/gameLibs/fftWater/shaders/shore.dshl similarity index 99% rename from prog/gameLibs/fftWater/shaders/shore.sh rename to prog/gameLibs/fftWater/shaders/shore.dshl index 61243ec18..bb05e9d77 100644 --- a/prog/gameLibs/fftWater/shaders/shore.sh +++ b/prog/gameLibs/fftWater/shaders/shore.dshl @@ -1,4 +1,4 @@ -include "water_heightmap.sh" +include "water_heightmap.dshl" texture shore_distance_field_tex; int distance_field_texture_size = 1024; diff --git a/prog/gameLibs/fftWater/shaders/underwater_fog.sh b/prog/gameLibs/fftWater/shaders/underwater_fog.dshl similarity index 100% rename from prog/gameLibs/fftWater/shaders/underwater_fog.sh rename to prog/gameLibs/fftWater/shaders/underwater_fog.dshl diff --git a/prog/gameLibs/fftWater/shaders/wake.sh b/prog/gameLibs/fftWater/shaders/wake.dshl similarity index 99% rename from prog/gameLibs/fftWater/shaders/wake.sh rename to prog/gameLibs/fftWater/shaders/wake.dshl index c4a188010..9cabb5644 100644 --- a/prog/gameLibs/fftWater/shaders/wake.sh +++ b/prog/gameLibs/fftWater/shaders/wake.dshl @@ -1,4 +1,4 @@ -include "wetness_inc.sh" +include "wetness_inc.dshl" texture wake_gradients_tex; texture wake_ht_tex; diff --git a/prog/gameLibs/fftWater/shaders/water_gradient.sh b/prog/gameLibs/fftWater/shaders/water_gradient.dshl similarity index 99% rename from prog/gameLibs/fftWater/shaders/water_gradient.sh rename to prog/gameLibs/fftWater/shaders/water_gradient.dshl index fa64793f5..d760cecdf 100644 --- a/prog/gameLibs/fftWater/shaders/water_gradient.sh +++ b/prog/gameLibs/fftWater/shaders/water_gradient.dshl @@ -1,4 +1,4 @@ -include "water_gradient_common.sh" +include "water_gradient_common.dshl" shader water_gradient, water_foam_blur { diff --git a/prog/gameLibs/fftWater/shaders/water_gradient_common.sh b/prog/gameLibs/fftWater/shaders/water_gradient_common.dshl similarity index 91% rename from prog/gameLibs/fftWater/shaders/water_gradient_common.sh rename to prog/gameLibs/fftWater/shaders/water_gradient_common.dshl index b95167764..311b4b59b 100644 --- a/prog/gameLibs/fftWater/shaders/water_gradient_common.sh +++ b/prog/gameLibs/fftWater/shaders/water_gradient_common.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "waveWorks.sh" +include "shader_global.dshl" +include "waveWorks.dshl" float4 water_texture_size = (512, 512, 1/512, 1/512); float4 water_gradient_scales0 = (1,1,0,0); diff --git a/prog/gameLibs/fftWater/shaders/water_gradient_cs.sh b/prog/gameLibs/fftWater/shaders/water_gradient_cs.dshl similarity index 99% rename from prog/gameLibs/fftWater/shaders/water_gradient_cs.sh rename to prog/gameLibs/fftWater/shaders/water_gradient_cs.dshl index 4464e626d..c055eedb1 100644 --- a/prog/gameLibs/fftWater/shaders/water_gradient_cs.sh +++ b/prog/gameLibs/fftWater/shaders/water_gradient_cs.dshl @@ -1,4 +1,4 @@ -include "water_gradient_common.sh" +include "water_gradient_common.dshl" float4 water_texture_size_mip = (512, 512, 1/512, 1/512); diff --git a/prog/gameLibs/fftWater/shaders/water_heightmap.sh b/prog/gameLibs/fftWater/shaders/water_heightmap.dshl similarity index 100% rename from prog/gameLibs/fftWater/shaders/water_heightmap.sh rename to prog/gameLibs/fftWater/shaders/water_heightmap.dshl diff --git a/prog/gameLibs/fftWater/shaders/water_normals.sh b/prog/gameLibs/fftWater/shaders/water_normals.dshl similarity index 98% rename from prog/gameLibs/fftWater/shaders/water_normals.sh rename to prog/gameLibs/fftWater/shaders/water_normals.dshl index d017cb85b..cd0ca1c71 100644 --- a/prog/gameLibs/fftWater/shaders/water_normals.sh +++ b/prog/gameLibs/fftWater/shaders/water_normals.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "waveWorks.sh" +include "shader_global.dshl" +include "waveWorks.dshl" float4 water_normals_size = (512, 512, 1 / 512, 1 / 512); diff --git a/prog/gameLibs/fftWater/shaders/waveWorks.sh b/prog/gameLibs/fftWater/shaders/waveWorks.dshl similarity index 99% rename from prog/gameLibs/fftWater/shaders/waveWorks.sh rename to prog/gameLibs/fftWater/shaders/waveWorks.dshl index 6875f2a43..032fdb5c6 100644 --- a/prog/gameLibs/fftWater/shaders/waveWorks.sh +++ b/prog/gameLibs/fftWater/shaders/waveWorks.dshl @@ -1,4 +1,4 @@ -include "shore.sh" +include "shore.dshl" int water_vs_cascades = 5; interval water_vs_cascades : zero<1, one <2, two<3, three<4, four<5, five; diff --git a/prog/gameLibs/gamePhys/phys/rendinstDestr.cpp b/prog/gameLibs/gamePhys/phys/rendinstDestr.cpp index c41e5e610..5f8a241ed 100644 --- a/prog/gameLibs/gamePhys/phys/rendinstDestr.cpp +++ b/prog/gameLibs/gamePhys/phys/rendinstDestr.cpp @@ -884,11 +884,10 @@ void rendinstdestr::deserialize_destr_data(const danet::BitStream &bs, int apply // always read cell count uint16_t cellCount = 0; - bs.ReadCompressed(cellCount); - if (!apply_reflection) { cachedDestr = bs; + bs.ReadCompressed(cellCount); for (int i = 0; i < cellCount; ++i) { uint16_t poolCount = 0; @@ -908,6 +907,7 @@ void rendinstdestr::deserialize_destr_data(const danet::BitStream &bs, int apply } return; } + bs.ReadCompressed(cellCount); rendinst::getDestrCellData(0 /*primary layer*/, [&](const Tab &destrCellData) { cellsNewDestrInfo.resize(cellCount); diff --git a/prog/gameLibs/gamePhys/phys/walker/humanPhys.cpp b/prog/gameLibs/gamePhys/phys/walker/humanPhys.cpp index c333cb98f..53fe44759 100644 --- a/prog/gameLibs/gamePhys/phys/walker/humanPhys.cpp +++ b/prog/gameLibs/gamePhys/phys/walker/humanPhys.cpp @@ -1539,7 +1539,7 @@ HumanPhys::TorsoCollisionResults HumanPhys::processTorsoCollision(TMatrix &tm, i } } const physmat::PhysDestructibleProps *destrProps = get_mat_props(contact); - constexpr float contactDepthThreshold = -0.05f; + constexpr float contactDepthThreshold = 0.05f; constexpr float contactDotThreshold = -0.5; const float spd = length(currentState.velocity); const float velDot = currentState.velocity * contact.wnormB; diff --git a/prog/gameLibs/heightmap/shaders/edge_tesselation.sh b/prog/gameLibs/heightmap/shaders/edge_tesselation.dshl similarity index 100% rename from prog/gameLibs/heightmap/shaders/edge_tesselation.sh rename to prog/gameLibs/heightmap/shaders/edge_tesselation.dshl diff --git a/prog/gameLibs/heightmap/shaders/heightmap_common.sh b/prog/gameLibs/heightmap/shaders/heightmap_common.dshl similarity index 99% rename from prog/gameLibs/heightmap/shaders/heightmap_common.sh rename to prog/gameLibs/heightmap/shaders/heightmap_common.dshl index 606d4cdb3..5595f62be 100644 --- a/prog/gameLibs/heightmap/shaders/heightmap_common.sh +++ b/prog/gameLibs/heightmap/shaders/heightmap_common.dshl @@ -1,4 +1,4 @@ -include "edge_tesselation.sh" +include "edge_tesselation.dshl" hlsl { ##if in_editor == yes diff --git a/prog/gameLibs/heightmap/shaders/heightmap_ofs.sh b/prog/gameLibs/heightmap/shaders/heightmap_ofs.dshl similarity index 99% rename from prog/gameLibs/heightmap/shaders/heightmap_ofs.sh rename to prog/gameLibs/heightmap/shaders/heightmap_ofs.dshl index 871b88437..912e4c4fc 100644 --- a/prog/gameLibs/heightmap/shaders/heightmap_ofs.sh +++ b/prog/gameLibs/heightmap/shaders/heightmap_ofs.dshl @@ -1,4 +1,4 @@ -include "land_block_inc.sh" +include "land_block_inc.dshl" texture hmap_ofs_tex; texture hmap_patches_tex; diff --git a/prog/gameLibs/heightmap/shaders/rendinst_heightmap_ofs.sh b/prog/gameLibs/heightmap/shaders/rendinst_heightmap_ofs.dshl similarity index 100% rename from prog/gameLibs/heightmap/shaders/rendinst_heightmap_ofs.sh rename to prog/gameLibs/heightmap/shaders/rendinst_heightmap_ofs.dshl diff --git a/prog/gameLibs/landMesh/shaders/biomes.sh b/prog/gameLibs/landMesh/shaders/biomes.dshl similarity index 100% rename from prog/gameLibs/landMesh/shaders/biomes.sh rename to prog/gameLibs/landMesh/shaders/biomes.dshl diff --git a/prog/gameLibs/landMesh/shaders/clipmap_common.sh b/prog/gameLibs/landMesh/shaders/clipmap_common.dshl similarity index 96% rename from prog/gameLibs/landMesh/shaders/clipmap_common.sh rename to prog/gameLibs/landMesh/shaders/clipmap_common.dshl index 4f60eacec..d3999862e 100644 --- a/prog/gameLibs/landMesh/shaders/clipmap_common.sh +++ b/prog/gameLibs/landMesh/shaders/clipmap_common.dshl @@ -27,8 +27,7 @@ endmacro float4 fallback_info0; float4 fallback_info1; -//float mip_scale = 0.42; -//float mip_bias = 0.92; + macro INIT_CLIPMAP_FALLBACK(code) (code) { fallback_info0@f3 = fallback_info0; diff --git a/prog/gameLibs/landMesh/shaders/tileConstantFiller.sh b/prog/gameLibs/landMesh/shaders/tileConstantFiller.dshl similarity index 100% rename from prog/gameLibs/landMesh/shaders/tileConstantFiller.sh rename to prog/gameLibs/landMesh/shaders/tileConstantFiller.dshl diff --git a/prog/gameLibs/landMesh/shaders/vtex.sh b/prog/gameLibs/landMesh/shaders/vtex.dshl similarity index 100% rename from prog/gameLibs/landMesh/shaders/vtex.sh rename to prog/gameLibs/landMesh/shaders/vtex.dshl diff --git a/prog/gameLibs/landMesh/virtualtexture.cpp b/prog/gameLibs/landMesh/virtualtexture.cpp index 3e6e0c006..e4dccddd6 100644 --- a/prog/gameLibs/landMesh/virtualtexture.cpp +++ b/prog/gameLibs/landMesh/virtualtexture.cpp @@ -243,7 +243,7 @@ class ClipmapImpl min(TILE_WIDTH * TILE_WIDTH * MAX_VTEX_CNT, FEEDBACK_WIDTH *FEEDBACK_HEIGHT); static constexpr uint32_t MAX_TILE_INFO_ELEMENT_CNT = MAX_TILE_CAPTURE_INFO_BUF_ELEMENTS * 2 + MAX_FAKE_TILE_CNT; - void initVirtualTexture(int cacheDimX, int cacheDimY); + void initVirtualTexture(int cacheDimX, int cacheDimY, float maxEffectiveTargetResolution); void closeVirtualTexture(); bool updateOrigin(const Point3 &cameraPosition, bool update_snap); @@ -358,7 +358,11 @@ class ClipmapImpl invalidate(true); } - void setTargetSize(int w, int h) { targetSize = IPoint2(w, h); }; + void setTargetSize(int w, int h, float mip_bias) + { + targetSize = IPoint2(w, h); + targetMipBias = mip_bias; + }; void prepareRender(ClipmapRenderer &render, bool force_update = false, bool turn_off_decals_on_fallback = false); void prepareFeedback(ClipmapRenderer &render, const Point3 &viewer_pos, const TMatrix &view_itm, const TMatrix4 &globtm, @@ -497,6 +501,8 @@ class ClipmapImpl int tileInfoSize = 0; IPoint2 targetSize = {-1, -1}; + float targetMipBias = 0.f; + float maxEffectiveTargetResolution = float(-1); // for debug comparison TileInfoArr debugTileInfo; @@ -533,7 +539,10 @@ class ClipmapImpl const IPoint2 Clipmap::FEEDBACK_SIZE = IPoint2(FEEDBACK_WIDTH, FEEDBACK_HEIGHT); const int Clipmap::MAX_TEX_MIP_CNT = TEX_MIPS; -void Clipmap::initVirtualTexture(int cacheDimX, int cacheDimY) { clipmapImpl->initVirtualTexture(cacheDimX, cacheDimY); } +void Clipmap::initVirtualTexture(int cacheDimX, int cacheDimY, float maxEffectiveTargetResolution) +{ + clipmapImpl->initVirtualTexture(cacheDimX, cacheDimY, maxEffectiveTargetResolution); +} void Clipmap::closeVirtualTexture() { clipmapImpl->closeVirtualTexture(); } bool Clipmap::updateOrigin(const Point3 &cameraPosition, bool update_snap) { @@ -604,7 +613,7 @@ void Clipmap::close() { clipmapImpl->close(); } void Clipmap::setMaxTexelSize(float max_texel_size) { clipmapImpl->setMaxTexelSize(max_texel_size); } float Clipmap::getStartTexelSize() const { return clipmapImpl->getStartTexelSize(); } void Clipmap::setStartTexelSize(float st_texel_size) { clipmapImpl->setStartTexelSize(st_texel_size); } -void Clipmap::setTargetSize(int w, int h) { clipmapImpl->setTargetSize(w, h); } +void Clipmap::setTargetSize(int w, int h, float mip_bias) { clipmapImpl->setTargetSize(w, h, mip_bias); } void Clipmap::prepareRender(ClipmapRenderer &render, bool force_update, bool turn_off_decals_on_fallback) { clipmapImpl->prepareRender(render, force_update, turn_off_decals_on_fallback); @@ -1874,7 +1883,7 @@ void ClipmapImpl::setTileSizeVars() ShaderGlobal::set_color4(g_cache2uvVarId, Color4(cpx, cpy, (brd + HALF_TEXEL_OFSF) * cpx, (brd + HALF_TEXEL_OFSF) * cpy)); } -void ClipmapImpl::initVirtualTexture(int argCacheDimX, int argCacheDimY) +void ClipmapImpl::initVirtualTexture(int argCacheDimX, int argCacheDimY, float argMaxEffectiveTargetResolution) { if (!is_uav_supported()) use_uav_feedback = false; @@ -1889,6 +1898,7 @@ void ClipmapImpl::initVirtualTexture(int argCacheDimX, int argCacheDimY) cacheDimX = argCacheDimX; cacheDimY = argCacheDimY; + maxEffectiveTargetResolution = argMaxEffectiveTargetResolution; tileInfoSize = 0; indirectionChanged = false; @@ -3335,7 +3345,9 @@ void ClipmapImpl::setDDScale() float ddw = float(FEEDBACK_WIDTH) / float(targetSize.x); float ddh = float(FEEDBACK_HEIGHT) / float(targetSize.y); - float sddh = (targetSize.y > 1200) ? sqrtf(float(targetSize.y) / 1080) : 1; + float targetResolution = float(targetSize.x * targetSize.y); + float effectiveTargetResolution = targetResolution * exp2f(-2 * targetMipBias); + float sddh = sqrtf(targetResolution / min(effectiveTargetResolution, maxEffectiveTargetResolution)); ShaderGlobal::set_color4(worldDDScaleVarId, Color4(ddw, ddh, sddh, sddh)); } diff --git a/prog/gameLibs/publicInclude/daECS/core/ecsHash.h b/prog/gameLibs/publicInclude/daECS/core/ecsHash.h index 25171dd59..57e605b16 100644 --- a/prog/gameLibs/publicInclude/daECS/core/ecsHash.h +++ b/prog/gameLibs/publicInclude/daECS/core/ecsHash.h @@ -39,8 +39,8 @@ struct HashedConstString hash_str_t hash; }; -#define ECS_HASH(a) (ecs::HashedConstString({a, eastl::integral_constant::value})) -#define ECS_HASH_SLOW(a) (ecs::HashedConstString({a, ecs_str_hash(a)})) +#define ECS_HASH(a) (ecs::HashedConstString{a, eastl::integral_constant::value}) +#define ECS_HASH_SLOW(a) (ecs::HashedConstString{a, ecs_str_hash(a)}) inline hash_str_t ecs_hash(eastl::string_view str) { return ecs_mem_hash(str.data(), str.length()); } diff --git a/prog/gameLibs/publicInclude/daFx/dafx_shaders.sh b/prog/gameLibs/publicInclude/daFx/dafx_shaders.dshl similarity index 100% rename from prog/gameLibs/publicInclude/daFx/dafx_shaders.sh rename to prog/gameLibs/publicInclude/daFx/dafx_shaders.dshl diff --git a/prog/gameLibs/publicInclude/dasModules/aotDm.h b/prog/gameLibs/publicInclude/dasModules/aotDm.h index b166ff4e8..600d34333 100644 --- a/prog/gameLibs/publicInclude/dasModules/aotDm.h +++ b/prog/gameLibs/publicInclude/dasModules/aotDm.h @@ -32,7 +32,6 @@ typedef dag::Vector DamageModelDataParts; using MetaPartPartIds = dag::VectorSet; MAKE_TYPE_FACTORY(DamageToPartEvent, dm::DamageToPartEvent) -MAKE_TYPE_FACTORY(PowderProps, dm::damage::PowderProps) MAKE_TYPE_FACTORY(ExplosiveProps, dm::ExplosiveProps) MAKE_TYPE_FACTORY(ExplosiveMassToSplash, dm::ExplosiveMassToSplash) MAKE_TYPE_FACTORY(MetaPart, dm::MetaPart); @@ -54,7 +53,6 @@ MAKE_TYPE_FACTORY(DmEffectPresetList, dm::effect::PresetList); MAKE_TYPE_FACTORY(MetaPartProp, dm::MetaPartProp); MAKE_TYPE_FACTORY(PenetrationTableProps, dm::kinetic::PenetrationTableProps); MAKE_TYPE_FACTORY(DamageTableProps, dm::kinetic::DamageTableProps); -MAKE_TYPE_FACTORY(EffectsProbabilityMultiplierProps, dm::kinetic::EffectsProbabilityMultiplierProps); MAKE_TYPE_FACTORY(DamageEffectActionCluster, dm::effect::ActionCluster); MAKE_TYPE_FACTORY(SplashProps, dm::splash::Properties); @@ -165,12 +163,17 @@ inline bool is_part_inner(const dm::DamageModelData &dm_data, int part_id) return props && props->testFlag(dm::DamagePartProps::Flag::INNER); } +inline int get_part_physmat_id(const dm::DamageModelData &dm_data, int part_id) +{ + const dm::DamagePartProps *props = dm::get_part_props(dm_data, dm::PartId(part_id, -1)); + return props ? props->physMaterialId : -1; +} + inline dm::splash::Params calc_splash_params(int damage_props_id, const dm::splash::Properties &splash_properties, bool underwater) { const dm::ExplosiveProps *explosiveProps = dm::ExplosiveProps::get_props(damage_props_id); dm::splash::Params params; - dm::splash::calc_params(&splash_properties, explosiveProps, dm::splash::FallBySquare::get_value(damage_props_id), - dm::splash::DamageTypeProp::get_value(damage_props_id), underwater ? dm::PhysEnvironment::WATER : dm::PhysEnvironment::AIR, + dm::splash::calc_params(splash_properties, explosiveProps, underwater ? dm::PhysEnvironment::WATER : dm::PhysEnvironment::AIR, params); return params; } diff --git a/prog/gameLibs/publicInclude/dasModules/dasFsFileAccess.h b/prog/gameLibs/publicInclude/dasModules/dasFsFileAccess.h index 449e98a7d..864b7a2a5 100644 --- a/prog/gameLibs/publicInclude/dasModules/dasFsFileAccess.h +++ b/prog/gameLibs/publicInclude/dasModules/dasFsFileAccess.h @@ -80,7 +80,7 @@ class FsFileInfo final : public das::FileInfo }; -class DagFileAccess final : public das::ModuleFileAccess +class DagFileAccess : public das::ModuleFileAccess { das::das_map extraRoots; das::FileAccess *localAccess; @@ -160,15 +160,12 @@ class DagFileAccess final : public das::ModuleFileAccess auto res = owner->getFileInfo(fname); if (storeOpenedFiles && res) { - bool found = false; - for (auto &f : owner->filesOpened) - if (f.first == fname) - { - filesOpened.emplace(fname, f.second); - found = true; - break; - } - if (EASTL_UNLIKELY(!found)) + auto it = owner->filesOpened.find_as(fname); + if (EASTL_LIKELY(it != owner->filesOpened.end())) + { + filesOpened.emplace(fname, it->second); + } + else { filesOpened.emplace(fname, getFileMtime(fname)); } diff --git a/prog/gameLibs/publicInclude/grid/spatialHashGridImpl.h b/prog/gameLibs/publicInclude/grid/spatialHashGridImpl.h index 48e014d28..dea8b0b10 100644 --- a/prog/gameLibs/publicInclude/grid/spatialHashGridImpl.h +++ b/prog/gameLibs/publicInclude/grid/spatialHashGridImpl.h @@ -22,17 +22,17 @@ class SpatialHash2D; typedef SpatialHash2D, 32> GridHolder; typedef eastl::fixed_function GridObjPred; -const GridObject *VECTORCALL grid_find_in_box_by_pos(const GridHolder &grid_holder, const BBox3 &bbox, const GridObjPred &pred); -const GridObject *VECTORCALL grid_find_in_box_by_bounding(const GridHolder &grid_holder, const BBox3 &bbox, const GridObjPred &pred); -const GridObject *VECTORCALL grid_find_in_sphere_by_pos(const GridHolder &grid_holder, const Point3 ¢er, float radius, +VECTORCALL const GridObject *grid_find_in_box_by_pos(const GridHolder &grid_holder, const BBox3 &bbox, const GridObjPred &pred); +VECTORCALL const GridObject *grid_find_in_box_by_bounding(const GridHolder &grid_holder, const BBox3 &bbox, const GridObjPred &pred); +VECTORCALL const GridObject *grid_find_in_sphere_by_pos(const GridHolder &grid_holder, const Point3 ¢er, float radius, const GridObjPred &pred); -const GridObject *VECTORCALL grid_find_in_sphere_by_bounding(const GridHolder &grid_holder, const Point3 ¢er, float radius, +VECTORCALL const GridObject *grid_find_in_sphere_by_bounding(const GridHolder &grid_holder, const Point3 ¢er, float radius, const GridObjPred &pred); -const GridObject *VECTORCALL grid_find_in_capsule_by_pos(const GridHolder &grid_holder, const Point3 &from, const Point3 &dir, +VECTORCALL const GridObject *grid_find_in_capsule_by_pos(const GridHolder &grid_holder, const Point3 &from, const Point3 &dir, float len, float radius, const GridObjPred &pred); -const GridObject *VECTORCALL grid_find_in_capsule_by_bounding(const GridHolder &grid_holder, const Point3 &from, const Point3 &dir, +VECTORCALL const GridObject *grid_find_in_capsule_by_bounding(const GridHolder &grid_holder, const Point3 &from, const Point3 &dir, float len, float radius, const GridObjPred &pred); -const GridObject *VECTORCALL grid_find_in_transformed_box_by_pos(const GridHolder &grid_holder, const TMatrix &tm, const BBox3 &bbox, +VECTORCALL const GridObject *grid_find_in_transformed_box_by_pos(const GridHolder &grid_holder, const TMatrix &tm, const BBox3 &bbox, const GridObjPred &pred); -const GridObject *VECTORCALL grid_find_in_transformed_box_by_bounding(const GridHolder &grid_holder, const TMatrix &tm, +VECTORCALL const GridObject *grid_find_in_transformed_box_by_bounding(const GridHolder &grid_holder, const TMatrix &tm, const BBox3 &bbox, const GridObjPred &pred); diff --git a/prog/gameLibs/publicInclude/landMesh/virtualtexture.h b/prog/gameLibs/publicInclude/landMesh/virtualtexture.h index af666b1ec..d7f128c0a 100644 --- a/prog/gameLibs/publicInclude/landMesh/virtualtexture.h +++ b/prog/gameLibs/publicInclude/landMesh/virtualtexture.h @@ -91,7 +91,7 @@ class Clipmap static const IPoint2 FEEDBACK_SIZE; static const int MAX_TEX_MIP_CNT; - void initVirtualTexture(int cacheDimX, int cacheDimY); + void initVirtualTexture(int cacheDimX, int cacheDimY, float maxEffectiveTargetResolution); void closeVirtualTexture(); bool updateOrigin(const Point3 &cameraPosition, bool update_snap); @@ -149,7 +149,7 @@ class Clipmap float getStartTexelSize() const; void setStartTexelSize(float st_texel_size); - void setTargetSize(int w, int h); + void setTargetSize(int w, int h, float mip_bias); void prepareRender(ClipmapRenderer &render, bool force_update = false, bool turn_off_decals_on_fallback = false); void prepareFeedback(ClipmapRenderer &render, const Point3 &viewer_pos, const TMatrix &view_itm, const TMatrix4 &globtm, float height, float maxDist0 = 0.f, float maxDist1 = 0.f, float approx_ht = 0.f, bool force_update = false, diff --git a/prog/gameLibs/publicInclude/pathFinder/tileRICommon.h b/prog/gameLibs/publicInclude/pathFinder/tileRICommon.h index 3046587b2..2f855ac7f 100644 --- a/prog/gameLibs/publicInclude/pathFinder/tileRICommon.h +++ b/prog/gameLibs/publicInclude/pathFinder/tileRICommon.h @@ -171,6 +171,14 @@ struct RendinstVertexDataCbBase : public rendinst::RendInstCollisionCB processCollision(coll); } + template + void procFilteredCollision(FilterCallback filter) + { + for (const rendinst::CollisionInfo &coll : collCache) + if (filter(coll)) + processCollision(coll); + } + virtual void processCollision(const rendinst::CollisionInfo &coll_info) = 0; virtual void addCollisionCheck(const rendinst::CollisionInfo &coll_info) { pushCollision(coll_info); } diff --git a/prog/gameLibs/publicInclude/projectiveDecals/projective_decals_common.sh b/prog/gameLibs/publicInclude/projectiveDecals/projective_decals_common.dshl similarity index 97% rename from prog/gameLibs/publicInclude/projectiveDecals/projective_decals_common.sh rename to prog/gameLibs/publicInclude/projectiveDecals/projective_decals_common.dshl index 10bfb8fd1..7bfb143cd 100644 --- a/prog/gameLibs/publicInclude/projectiveDecals/projective_decals_common.sh +++ b/prog/gameLibs/publicInclude/projectiveDecals/projective_decals_common.dshl @@ -1,8 +1,8 @@ -include "viewVecVS.sh" -include "land_block_inc.sh" -include "deform_hmap_common.sh" -include "heightmap_ofs.sh" -include "heightmap_common.sh" +include "viewVecVS.dshl" +include "land_block_inc.dshl" +include "deform_hmap_common.dshl" +include "heightmap_ofs.dshl" +include "heightmap_common.dshl" buffer decal_buffer; diff --git a/prog/gameLibs/publicInclude/recastTools/recastBuildJumpLinks.h b/prog/gameLibs/publicInclude/recastTools/recastBuildJumpLinks.h index a6eef8501..b813bc859 100644 --- a/prog/gameLibs/publicInclude/recastTools/recastBuildJumpLinks.h +++ b/prog/gameLibs/publicInclude/recastTools/recastBuildJumpLinks.h @@ -33,6 +33,7 @@ struct JumpLinksParams // 0 - disabled float complexJumpTheshold; bool crossObstaclesWithJumplinks; + bool enableCustomJumplinks; }; struct JumpLinkObstacle diff --git a/prog/gameLibs/publicInclude/rendInst/packedMultidrawParams.hlsli b/prog/gameLibs/publicInclude/rendInst/packedMultidrawParams.hlsli new file mode 100644 index 000000000..a25a80076 --- /dev/null +++ b/prog/gameLibs/publicInclude/rendInst/packedMultidrawParams.hlsli @@ -0,0 +1,15 @@ +#ifndef PACKED_MULTIDRAW_PARAMS_INCLUDED +#define PACKED_MULTIDRAW_PARAMS_INCLUDED + +#define MATERIAL_OFFSET_BITS 12 +#define MATRICES_OFFSET_BITS (32 - MATERIAL_OFFSET_BITS) + +#define MATERIAL_OFFSET_MASK ((1 << MATERIAL_OFFSET_BITS) - 1) +#define MATRICES_OFFSET_MASK ((1 << MATRICES_OFFSET_BITS) - 1) + +#define MATRICES_OFFSET_SHIFT MATERIAL_OFFSET_BITS + +#define MAX_MATERIAL_OFFSET (1 << MATERIAL_OFFSET_BITS) +#define MAX_MATRIX_OFFSET (1 << MATRICES_OFFSET_BITS) + +#endif // PACKED_MULTIDRAW_PARAMS_INCLUDED diff --git a/prog/gameLibs/publicInclude/rendInst/rendInstCollision.h b/prog/gameLibs/publicInclude/rendInst/rendInstCollision.h index eb4f78f14..5841013ff 100644 --- a/prog/gameLibs/publicInclude/rendInst/rendInstCollision.h +++ b/prog/gameLibs/publicInclude/rendInst/rendInstCollision.h @@ -112,7 +112,8 @@ struct TraceRayRendInstSolidData : TraceRayRendInstData using RendInstsIntersectionsList = dag::Vector; using RendInstsSolidIntersectionsList = dag::Vector; -void computeRiIntersectedSolids(RendInstsSolidIntersectionsList &intersected, const Point3 &dir, SolidSectionsMerge merge_mode); +void computeRiIntersectedSolids(RendInstsSolidIntersectionsList &intersected, const Point3 &from, const Point3 &dir, + SolidSectionsMerge merge_mode); // ======= trace ray stuff ======== diff --git a/prog/gameLibs/publicInclude/rendInst/riShaderConstBuffers.h b/prog/gameLibs/publicInclude/rendInst/riShaderConstBuffers.h index a38674eb8..9c0c885b5 100644 --- a/prog/gameLibs/publicInclude/rendInst/riShaderConstBuffers.h +++ b/prog/gameLibs/publicInclude/rendInst/riShaderConstBuffers.h @@ -31,7 +31,7 @@ struct RiShaderConstBuffers // float4 deltas1 (opt) - imp_size deltas for slices 2,3 // float4 deltas2 (opt) - imp_size deltas for slices 4,5 // float4 deltas3 (opt) - imp_size deltas for slices 6,7 - // float4 rendinst_bbox; - bounding box is used for vegetation interactions + // float4 rendinst_bbox__cross_dissolve_range - bounding box is used for vegetation interactions AND cross dissolve range // float4 color_from - first edge random color // float4 color_to - second edge random color // float4 rendinst_interaction_params - for shader interactions with other objects @@ -57,6 +57,7 @@ struct RiShaderConstBuffers void setOpacity(float p0, float p1, float p2 = 0.f, float p3 = 0.f); void setBoundingSphere(float p0, float p1, float sphereRadius, float cylinderRadius, float sphereCenterY); void setBoundingBox(const vec4f &bbox); + void setCrossDissolveRange(float crossDissolveRange); void setImpostorMultiWidths(float widths[], float heights[]); void setImpostorLocalView(const Point3 &view_x, const Point3 &view_y); void setRadiusFade(float radius, float drown_scale); diff --git a/prog/gameLibs/publicInclude/render/daBfg/detail/projectors.h b/prog/gameLibs/publicInclude/render/daBfg/detail/projectors.h index d6ffa64a4..0827986b7 100644 --- a/prog/gameLibs/publicInclude/render/daBfg/detail/projectors.h +++ b/prog/gameLibs/publicInclude/render/daBfg/detail/projectors.h @@ -14,7 +14,7 @@ using TypeErasedProjector = void *(*)(void *); template C owner_type_of_memptr(T C::*memberPtr); -template +template T member_type_of_memptr(T C::*memberPtr); template diff --git a/prog/gameLibs/publicInclude/render/daBfg/virtualResourceRequest.h b/prog/gameLibs/publicInclude/render/daBfg/virtualResourceRequest.h index 7b288984b..9643f9058 100644 --- a/prog/gameLibs/publicInclude/render/daBfg/virtualResourceRequest.h +++ b/prog/gameLibs/publicInclude/render/daBfg/virtualResourceRequest.h @@ -123,10 +123,10 @@ class VirtualResourceRequest * \param shader_var_name The name of the shader variable to bind. * If not specified, the name of the resource will be used. */ - template )> + template )> VirtualResourceRequest bindToShaderVar(const char *shader_var_name = nullptr) && { - using MemberType = decltype(detail::member_type_of_memptr(memberPtr)); + using MemberType = decltype(detail::member_type_of_memptr(memberPtr)); Base::bindToShaderVar(shader_var_name, tag_for(), detail::projector_for_member()); return {resUid, nodeId, registry}; } @@ -149,10 +149,10 @@ class VirtualResourceRequest * \tparam memberPtr A pointer to the member of the blob to bind, * e.g. `&Camera::viewTm`. */ - template )> + template )> VirtualResourceRequest bindAsView() && { - using MemberType = decltype(detail::member_type_of_memptr(memberPtr)); + using MemberType = decltype(detail::member_type_of_memptr(memberPtr)); Base::bindAsView(tag_for(), detail::projector_for_member()); return {resUid, nodeId, registry}; } @@ -175,10 +175,10 @@ class VirtualResourceRequest * \tparam memberPtr A pointer to the member of the blob to bind, * e.g. `&Camera::projTm`. */ - template )> + template )> VirtualResourceRequest bindAsProj() && { - using MemberType = decltype(detail::member_type_of_memptr(memberPtr)); + using MemberType = decltype(detail::member_type_of_memptr(memberPtr)); Base::bindAsProj(tag_for(), detail::projector_for_member()); return {resUid, nodeId, registry}; } diff --git a/prog/gameLibs/publicInclude/render/decals/dynamic_decals_params.hlsli b/prog/gameLibs/publicInclude/render/decals/dynamic_decals_params.hlsli index c137363e8..17eab0e86 100644 --- a/prog/gameLibs/publicInclude/render/decals/dynamic_decals_params.hlsli +++ b/prog/gameLibs/publicInclude/render/decals/dynamic_decals_params.hlsli @@ -1,5 +1,5 @@ // Uncomment this to tweak decal params and unlock shader vars and console (needs shader/exe compilation) -// also needs uncommenting in dynamic_decals_inc.sh +// also needs uncommenting in dynamic_decals_inc.dshl // #define DYNAMIC_DECALS_TWEAKING diff --git a/prog/gameLibs/publicInclude/render/depthAOAboveRenderer.h b/prog/gameLibs/publicInclude/render/depthAOAboveRenderer.h index d6459e852..a2cca688e 100644 --- a/prog/gameLibs/publicInclude/render/depthAOAboveRenderer.h +++ b/prog/gameLibs/publicInclude/render/depthAOAboveRenderer.h @@ -12,20 +12,38 @@ #include #include #include +#include class DynamicShaderHelper; #define MAX_UPDATE_REGIONS 5 + +enum RenderDepthAOType : uint32_t +{ + Transparent = 1 << 0, + Terrain = 1 << 1, + Opaque = 1 << 2, + ALL = 0xFFFFFFFF, +}; + class IRenderDepthAOCB { public: - virtual void renderDepthAO(const Point3 &, mat44f_cref, const float, int region, bool transparent = false) = 0; + virtual void renderDepthAO(const Point3 &, mat44f_cref, const float, int region, RenderDepthAOType type = RenderDepthAOType::ALL, + int cascade_no = 0) = 0; virtual void getMinMaxZ(float &, float &) = 0; }; + class DepthAOAboveRenderer { + enum class RenderDepthAOClearFirst + { + Yes, + No, + }; + struct RegionToRender { RegionToRender(ToroidalQuadRegion &r) : cullViewProj(), reg(r) {} @@ -49,7 +67,7 @@ class DepthAOAboveRenderer }; BlurDepthRenderer(); ~BlurDepthRenderer(); - void render(BaseTexture *target, TEXTUREID depth_tid, ToroidalHelper &worldAODepthData, Tab &tris); + void render(BaseTexture *target, TEXTUREID depth_tid, ToroidalHelper &worldAODepthData, Tab &tris, int cascade_no); }; BlurDepthRenderer blurDepthRenderer; @@ -58,36 +76,58 @@ class DepthAOAboveRenderer shaders::UniqueOverrideStateId zFuncAlwaysStateId; shaders::UniqueOverrideStateId zWriteOnStateId; + struct CascadeDependantData + { + ToroidalHelper worldAODepthData; + Tab invalidAORegions; + float depthAroundDistance = 0; + Tab regionsToRender; + }; + // Note: the code assumes that MAX_CASCADES == 2 and cannot handle more for now + // Need more? Move cascade dependant shadervars and etc to an array + static constexpr int MAX_CASCADES = 2; + float extraCascadeMult = 2.0f; + dag::RelocatableFixedVector cascadeDependantData; + + unsigned int texSize; UniqueTexHolder worldAODepth; UniqueTexHolder worldAODepthWithTransparency; - ToroidalHelper worldAODepthData; UniqueTexHolder blurredDepth; UniqueTexHolder blurredDepthWithTransparency; Point2 sceneMinMaxZ; - ; - Tab invalidAORegions; - float depthAroundDistance = 0; - Tab regionsToRender; bool renderTransparent = false; + + void renderAODepthQuads(dag::ConstSpan regions, IRenderDepthAOCB &renderDepthCb, int cascade_no); void renderAODepthQuads(dag::ConstSpan regions, IRenderDepthAOCB &renderDepthCb, BaseTexture *depthTex, - bool transparent); - void renderAODepthQuadsTransparent(dag::ConstSpan regions, IRenderDepthAOCB &renderDepthCb); - void copyDepthAboveRegions(dag::ConstSpan regions); + RenderDepthAOType type, RenderDepthAOClearFirst clear_mode, int cascade_no); + void renderAODepthQuadsTransparent(dag::ConstSpan regions, IRenderDepthAOCB &renderDepthCb, + RenderDepthAOClearFirst clear_mode, int cascade_no); + void copyDepthAboveRegions(dag::ConstSpan regions, BaseTexture *depthTex, int cascade_no); public: - DepthAOAboveRenderer(int texSize, float depth_around_distance, bool render_extra = false); + DepthAOAboveRenderer(int texSize, float depth_around_distance, bool render_extra = false, bool use_extra_cascade = false, + float extra_cascade_mult = 2.0f); ~DepthAOAboveRenderer() { setInvalidVars(); } - void prepareAO(const Point3 &origin, IRenderDepthAOCB &renderDepthCb); // prepare and render void prepareRenderRegions(const Point3 &origin, float scene_min_z, float scene_max_z, float splitThreshold = -1.0f); + void prepareRenderRegionsForCascade(const Point3 &origin, float scene_min_z, float scene_max_z, float splitThreshold = -1.0f, + int cascade_no = 0); void renderPreparedRegions(IRenderDepthAOCB &renderDepthCb); - void renderAODepthQuads(dag::ConstSpan regions, IRenderDepthAOCB &renderDepthCb); - dag::ConstSpan getRegionsToRender() const { return regionsToRender; } + void renderPreparedRegionsForCascade(IRenderDepthAOCB &renderDepthCb, int cascade_no = 0); + dag::ConstSpan getRegionsToRender(int cascade_no = 0) const + { + G_ASSERT(cascade_no < cascadeDependantData.size()); + return cascadeDependantData[cascade_no].regionsToRender; + } void invalidateAO(bool force); void invalidateAO(const BBox3 &box); void setDistanceAround(float distance_around); - float getDistanceAround() const { return depthAroundDistance; } + float getDistanceAround(int cascade_no = 0) const + { + G_ASSERT(cascade_no < cascadeDependantData.size()); + return cascadeDependantData[cascade_no].depthAroundDistance; + } void setVars(); void setInvalidVars(); }; diff --git a/prog/gameLibs/publicInclude/render/fluidDynamics/solver.h b/prog/gameLibs/publicInclude/render/fluidDynamics/solver.h index 869f658b7..d357dd33b 100644 --- a/prog/gameLibs/publicInclude/render/fluidDynamics/solver.h +++ b/prog/gameLibs/publicInclude/render/fluidDynamics/solver.h @@ -57,19 +57,20 @@ struct Cascade class CascadeSolver { public: - CascadeSolver(const char *solver_shader_name, uint32_t tex_width, uint32_t tex_height, - const eastl::array &num_dispatches_per_cascade = {4700, 1600, 650, 150}, float spatial_step = 1.f); + CascadeSolver(const char *solver_shader_name, IPoint3 tex_size, float spatial_step = 1.f, const char *solver_name = "", + const eastl::array &num_dispatches_per_cascade = {4700, 1600, 650, 150}); void fillInitialConditions(float standard_density, const Point2 &standard_velocity); - void solveEquations(float dt, int num_dispatches); + bool solveEquations(float dt, int num_dispatches); void showResult(PlotType plot_type); + void reset(); + + bool isResultReady() const; TEXTUREID getVelocityDensityTexId() const; float getSimulationTime() const; int getNumDispatches() const; - static constexpr int NUM_CASCADES = 4; - private: eastl::unique_ptr initialConditionsCs; eastl::unique_ptr initialConditionsFromTexCs; @@ -77,16 +78,21 @@ class CascadeSolver eastl::unique_ptr blurCs; PostFxRenderer showSolution; + static constexpr int NUM_CASCADES = 4; int currentCascade = 0; eastl::array numDispatchesPerCascade; int curNumDispatches = 0; int totalNumDispatches = 0; + bool resultReady = false; - Tab cascades; + eastl::array cascades; + int textureDepth = 0; float simulationTime = 0.0f; + float standardDensity = 0.0f; + Point2 standardVelocity = Point2::ZERO; void switchToCascade(int cascade); void fillNextCascadeInitialConditions(); diff --git a/prog/gameLibs/publicInclude/render/fluidDynamics/voxelizeDepthAbove.h b/prog/gameLibs/publicInclude/render/fluidDynamics/voxelizeDepthAbove.h index 196fe52a1..7ef1c3961 100644 --- a/prog/gameLibs/publicInclude/render/fluidDynamics/voxelizeDepthAbove.h +++ b/prog/gameLibs/publicInclude/render/fluidDynamics/voxelizeDepthAbove.h @@ -4,21 +4,35 @@ #include #include <3d/dag_resPtr.h> #include +#include namespace cfd { class Voxelizer { public: - Voxelizer(IPoint3 vol_tex_size); + Voxelizer(Point3 world_box_size, float meters_per_voxel_xz = 1.0f, float meters_per_voxel_y = 4.0f); - void voxelizeDepthAbove(const Point3 &world_pos, const Point2 &worldYMinMax); + void voxelizeDepthAbove(const Point3 &world_pos, float world_y_min); + TEXTUREID getVoxelTexId() const; + Point3 getVoxelTC(const Point3 &world_pos); + + Point3 getCenter() const; + BBox3 getWorldBox() const; + Point4 getWorldToVoxel() const; + Point4 getWorldToVoxelHeight() const; private: UniqueTexHolder voxelTex; - IPoint3 volTexSize; + IPoint3 voxelTexSize; Point3 worldBoxSize; - static constexpr float metersPerVoxel = 1.0f; + BBox3 worldBox; + + Point4 worldToVoxel; + Point4 worldToVoxelHeight; + + float metersPerVoxelXZ; + float metersPerVoxelY; eastl::unique_ptr voxelizeCs; }; diff --git a/prog/gameLibs/publicInclude/render/gpuVisibilityTest.h b/prog/gameLibs/publicInclude/render/gpuVisibilityTest.h index a98de3838..bf7108571 100644 --- a/prog/gameLibs/publicInclude/render/gpuVisibilityTest.h +++ b/prog/gameLibs/publicInclude/render/gpuVisibilityTest.h @@ -7,11 +7,8 @@ #include #include -#include #include <3d/dag_drv3d.h> #include <3d/dag_resPtr.h> -#include -#include #include #include #include <3d/dag_ringCPUQueryLock.h> diff --git a/prog/gameLibs/publicInclude/render/iesTextureManager.h b/prog/gameLibs/publicInclude/render/iesTextureManager.h index da210fafa..9b0312d0a 100644 --- a/prog/gameLibs/publicInclude/render/iesTextureManager.h +++ b/prog/gameLibs/publicInclude/render/iesTextureManager.h @@ -9,12 +9,53 @@ #include #include #include - +#include #include +#include +#include +#include <3d/dag_resPtr.h> + +#include + +#include + + +class IesEditor +{ +public: + IesEditor(); + + void renderIesTexture(); + void clearControlPoints(); + void removeControlPoint(int index); + void recalcCoefficients(); + int addPointWithUpdate(float theta, float intensity); + int addPointWithoutUpdate(float theta, float intensity); + float getLightIntensityAt(float theta) const; + + int getNumControlPoints() const { return sortedPhotometryControlPoints.size(); } + const PhotometryControlPoint *getPhotometryControlPoints() const { return sortedPhotometryControlPoints.data(); } + PhotometryControlPoint *getPhotometryControlPoints() { return sortedPhotometryControlPoints.data(); } + +private: + PostFxRenderer iesGenerator; + IPoint3 currentResolution = IPoint3(0, 0, 0); + UniqueTex dynamicIesTexArray; + UniqueBufHolder sortedPhotometryControlPointsBuf; + eastl::string originalTextureName; + eastl::vector sortedPhotometryControlPoints; + bool needsRender = true; + + static IPoint3 getTexResolution(BaseTexture *photometry_tex_array); + + void ensureTextureCreated(BaseTexture *photometry_tex_array); +}; class IesTextureCollection { public: + static const char *EDITOR_TEXTURE_NAME; + struct PhotometryData { float zoom = 1; @@ -32,16 +73,20 @@ class IesTextureCollection IesTextureCollection &operator=(const IesTextureCollection &) = delete; // move semantics implicitly deleted - // no need for its impelemtation + // no need for its implementation int getTextureIdx(const char *name); void reloadTextures(); void addTexture(const char *textureName); void close(); - PhotometryData getTextureData(int texIdx) const; + PhotometryData getTextureData(int tex_idx) const; + TEXTUREID getTextureArrayId(); + + IesEditor *requireEditor(); private: static IesTextureCollection *instance; + eastl::unique_ptr editor; uint32_t refCount = 0; eastl::vector usedTextures; diff --git a/prog/gameLibs/publicInclude/render/ies_generator_shared.hlsli b/prog/gameLibs/publicInclude/render/ies_generator_shared.hlsli new file mode 100644 index 000000000..44b37218a --- /dev/null +++ b/prog/gameLibs/publicInclude/render/ies_generator_shared.hlsli @@ -0,0 +1,8 @@ +#define MAX_NUM_CONTROL_POINTS 1024 + +struct PhotometryControlPoint +{ + float2 coefficients; // light_intensity = coefficients.x + theta * coefficients.y + float theta; // [0, pi] + float lightIntensity; // [0, inf) +}; \ No newline at end of file diff --git a/prog/gameLibs/publicInclude/render/ies_mappings.hlsl b/prog/gameLibs/publicInclude/render/ies_mappings.hlsl new file mode 100644 index 000000000..ec56e5794 --- /dev/null +++ b/prog/gameLibs/publicInclude/render/ies_mappings.hlsl @@ -0,0 +1,27 @@ +float3 inv_octahedral_mapping(float2 tc, float zoom, bool rotate) +{ + tc = (tc * 2 - 1)/zoom; + if (rotate) + tc = float2(tc.x - tc.y, tc.x + tc.y) / 2; + float3 dir = float3(tc.xy, 1.0 - (abs(tc.x) + abs(tc.y))); + if (dir.z < 0) + dir.xy = float2(-(abs(dir.y) - 1) * sign(dir.x), -(abs(dir.x) - 1) * sign(dir.y)); + return normalize(dir); +} + +half2 octahedral_mapping(half3 co, float zoom, bool rotate) +{ + co /= dot(half3(1, 1, 1), abs(co)); + co.xy = co.y < 0.0 + ? (1.0 - abs(co.zx)) * (co.xz < 0 ? float2(-1, -1) : float2(1, 1)) + : co.xz; + if (rotate) + { + float tempX = co.x; + co.x = (co.x + co.y); + co.y = (co.y - tempX); + } + co.x *= zoom; + co.y *= zoom; + return co.xy * 0.5 + 0.5; +} diff --git a/prog/gameLibs/publicInclude/render/spotLightsManager.h b/prog/gameLibs/publicInclude/render/spotLightsManager.h index 85f6f08af..18d3075bb 100644 --- a/prog/gameLibs/publicInclude/render/spotLightsManager.h +++ b/prog/gameLibs/publicInclude/render/spotLightsManager.h @@ -7,12 +7,12 @@ #include "spotLight.h" #include +#include #include #include #include #include #include "renderLights.hlsli" -#include #include @@ -172,9 +172,9 @@ class SpotLightsManager bool isLightNonOptimized(int id) { return nonOptLightIds.test(id); } bool tryGetNonOptimizedLightId(int &id) { - if (nonOptLightIds.any()) + if (int tId = nonOptLightIds.find_first(); tId != nonOptLightIds.kSize) { - id = nonOptLightIds.find_first(); + id = tId; return true; } return false; @@ -200,7 +200,7 @@ class SpotLightsManager carray masks; //-V730_NOINIT StaticTab freeLightIds; //-V730_NOINIT - eastl::bitset nonOptLightIds; + Bitset nonOptLightIds; IesTextureCollection *photometryTextures = nullptr; int maxLightIndex = -1; }; diff --git a/prog/gameLibs/publicInclude/webui/helpers.h b/prog/gameLibs/publicInclude/webui/helpers.h index 57d21ef9e..516eaf330 100644 --- a/prog/gameLibs/publicInclude/webui/helpers.h +++ b/prog/gameLibs/publicInclude/webui/helpers.h @@ -103,6 +103,7 @@ inline void YAMemSave::vprintf(const char *f, const DagorSafeArg *arg, int anum) extern HttpPlugin dagor_http_plugins[]; extern HttpPlugin squirrel_http_plugins[]; extern HttpPlugin webview_http_plugins[]; +extern HttpPlugin webview_files_http_plugins[]; extern HttpPlugin tvos_http_plugins[]; extern HttpPlugin shader_http_plugin; diff --git a/prog/gameLibs/quirrel/sqModules/sqModules.cpp b/prog/gameLibs/quirrel/sqModules/sqModules.cpp index 0c7eb4726..7bf92ea45 100644 --- a/prog/gameLibs/quirrel/sqModules/sqModules.cpp +++ b/prog/gameLibs/quirrel/sqModules/sqModules.cpp @@ -117,7 +117,7 @@ SqModules::SqModules(HSQUIRRELVM vm, SqModulesConfigBits cfg) : compilationOptions.doStaticAnalysis = false; compilationOptions.useAbsolutePath = false; - sq_disablesyntaxwarnings(); + sq_enablesyntaxwarnings(false); registerModulesModule(); } diff --git a/prog/gameLibs/rendInst/impostorTextureMgr.cpp b/prog/gameLibs/rendInst/impostorTextureMgr.cpp index d67b454c9..5259cbd80 100644 --- a/prog/gameLibs/rendInst/impostorTextureMgr.cpp +++ b/prog/gameLibs/rendInst/impostorTextureMgr.cpp @@ -363,6 +363,7 @@ void ImpostorTextureManager::render(const Point3 &point_to_eye, const TMatrix &v rendinst::render::RiShaderConstBuffers cb; cb.setOpacity(0, 1); + cb.setCrossDissolveRange(0); cb.setBoundingSphere(0, 0, 1, 1, 0); cb.setRandomColors(defaultColors); cb.setInstancing(0, 3, 0); diff --git a/prog/gameLibs/rendInst/rendInstAccess.cpp b/prog/gameLibs/rendInst/rendInstAccess.cpp index 4b7346c2d..8dac94328 100644 --- a/prog/gameLibs/rendInst/rendInstAccess.cpp +++ b/prog/gameLibs/rendInst/rendInstAccess.cpp @@ -317,6 +317,8 @@ rendinst::RendInstDesc rendinst::get_restorable_desc(const RendInstDesc &ri_desc int rendinst::find_restorable_data_index(const RendInstDesc &desc) { + if (unsigned(desc.pool) >= riExtra.size()) + return -1; const auto &ud = riExtra[desc.pool].riUniqueData; for (int r = 0; r < ud.size(); ++r) if (ud[r].cellId == -(desc.cellIdx + 1) && ud[r].offset == desc.offs) diff --git a/prog/gameLibs/rendInst/rendInstGen.cpp b/prog/gameLibs/rendInst/rendInstGen.cpp index 94e36234e..7e5623ec0 100644 --- a/prog/gameLibs/rendInst/rendInstGen.cpp +++ b/prog/gameLibs/rendInst/rendInstGen.cpp @@ -1649,6 +1649,9 @@ RendInstGenData::CellRtData *RendInstGenData::generateCell(int x, int z) for (int j = 0; j < cellDestr.destroyedPoolInfo.size(); ++j) { const rendinst::DestroyedPoolData &poolDestr = cellDestr.destroyedPoolInfo[j]; + if (!rtData->rtPoolData[poolDestr.poolIdx]) + continue; + bool posInst = rtData->riPosInst[poolDestr.poolIdx]; int stride = (posInst ? 4 : 12) + perInstDataDwords * 2; uint8_t *basePoolPtr = vbPtr + crt.pools[poolDestr.poolIdx].baseOfs; diff --git a/prog/gameLibs/rendInst/rendInstGenCollision.cpp b/prog/gameLibs/rendInst/rendInstGenCollision.cpp index 09baf6fda..87f3c09d3 100644 --- a/prog/gameLibs/rendInst/rendInstGenCollision.cpp +++ b/prog/gameLibs/rendInst/rendInstGenCollision.cpp @@ -245,7 +245,7 @@ struct TraceRayAllUnsortedListStrat : public TraceRayStrat data.tOut = data.tIn; data.normOut = data.normIn; } - in_out_t = eastl::max(in_out_t, node.intersectionT); + // in_out_t = eastl::max(in_out_t, node.intersectionT); } } return false; @@ -1411,7 +1411,7 @@ bool traceRayRendInstsListAllNormalized(const Point3 &from, const Point3 &dir, f template struct LocalIntersectionIdRemap { - eastl::fixed_vector data; + dag::RelocatableFixedVector data; IdxT add(const T &item) { auto it = eastl::find(data.begin(), data.end(), item); @@ -1426,7 +1426,8 @@ struct LocalIntersectionIdRemap const T &get(IdxT id) const { return data[id]; } }; -void computeRiIntersectedSolids(RendInstsSolidIntersectionsList &intersected, const Point3 &dir, SolidSectionsMerge merge_mode) +void computeRiIntersectedSolids(RendInstsSolidIntersectionsList &intersected, const Point3 &from, const Point3 &dir, + SolidSectionsMerge merge_mode) { if (EASTL_UNLIKELY(merge_mode == SolidSectionsMerge::NONE)) return; @@ -1445,9 +1446,10 @@ void computeRiIntersectedSolids(RendInstsSolidIntersectionsList &intersected, co if (dbgNames.length() > 200) break; } - logerr("computeRiIntersectedSolids has received too big intersection list, this is probably a bug, it will not be processed " - "printing first rendinsts: %s", - dbgNames.c_str()); + logerr("computeRiIntersectedSolids has received too big intersection list (%i), this is probably a bug, it will not be processed, " + "ray=(%.9f,%.9f,%.9f),(%.9f,%.9f,%.9f) printing first rendinsts: %s", + intersectionCount, from.x, from.y, from.z, dir.x, dir.y, dir.z, dbgNames.c_str()); + intersected.clear(); return; } @@ -1467,10 +1469,10 @@ void computeRiIntersectedSolids(RendInstsSolidIntersectionsList &intersected, co bool matches(LocalIntersectionId rhs) const { return collNodeId == rhs.collNodeId && matId == rhs.matId && riId == rhs.riId; } }; - eastl::fixed_vector intersectionData; + dag::RelocatableFixedVector intersectionData; LocalIntersectionIdRemap localCollNodeRemap; LocalIntersectionIdRemap localMatIdRemap; - LocalIntersectionIdRemap localRiRemap; + LocalIntersectionIdRemap localRiRemap; // [0, size) - coll node index and flags // [size, size * 2) - out intersection index diff --git a/prog/gameLibs/rendInst/rendInstGenDebris.cpp b/prog/gameLibs/rendInst/rendInstGenDebris.cpp index 9cf853818..9d84703c4 100644 --- a/prog/gameLibs/rendInst/rendInstGenDebris.cpp +++ b/prog/gameLibs/rendInst/rendInstGenDebris.cpp @@ -35,17 +35,9 @@ static void play_riextra_destroy_effect(rendinst::riex_handle_t id, mat44f_cref static inline void prepareDestrExcl(RendInstGenData *rgl) { - if (rendinst::gen::destrExcl.bm.getW()) - { - if (rendinst::gen::destrExcl.bm.getW() > 0 && rendinst::gen::destrExcl.bm.getW() <= 65536 && - rendinst::gen::destrExcl.bm.getH() > 0 && rendinst::gen::destrExcl.bm.getH() <= 65536) - return; - - fatal("rendinst::gen::destrExcl is broken: size=%d,%d", rendinst::gen::destrExcl.bm.getW(), rendinst::gen::destrExcl.bm.getH()); - rendinst::gen::destrExcl.clear(); - } - rendinst::gen::destrExcl.initExplicit(rgl->world0x(), rgl->world0z(), 0.5f, rgl->grid2world * rgl->cellSz * rgl->cellNumW, - rgl->grid2world * rgl->cellSz * rgl->cellNumH); + if (rendinst::gen::destrExcl.bm.getW() == 0) + rendinst::gen::destrExcl.initExplicit(rgl->world0x(), rgl->world0z(), 0.5f, rgl->grid2world * rgl->cellSz * rgl->cellNumW, + rgl->grid2world * rgl->cellSz * rgl->cellNumH); } static int sweepRIGenInBoxByMask(RendInstGenData *rgl, const BBox3 &_box, unsigned frameNo, rendinst::ri_damage_effect_cb effect_cb, diff --git a/prog/gameLibs/rendInst/render/clipShadows.cpp b/prog/gameLibs/rendInst/render/clipShadows.cpp index a5adf56d0..c942b44c3 100644 --- a/prog/gameLibs/rendInst/render/clipShadows.cpp +++ b/prog/gameLibs/rendInst/render/clipShadows.cpp @@ -326,6 +326,7 @@ bool render_clipmap_shadow_pool(rendinst::render::RtPoolData &pool, RenderableIn rendinst::render::RiShaderConstBuffers cb; cb.setBBoxZero(); cb.setOpacity(0, 1); + cb.setCrossDissolveRange(0); cb.setBoundingSphere(0, 0, 1, 1, 0); cb.setInstancing(pool.hasImpostor() ? 3 : 0, pool.hasImpostor() ? 1 : 3, impostor_buffer_offset); cb.flushPerDraw(); diff --git a/prog/gameLibs/rendInst/render/extra/riExtraRendererT.h b/prog/gameLibs/rendInst/render/extra/riExtraRendererT.h index 9b24db4ba..600d14ebb 100644 --- a/prog/gameLibs/rendInst/render/extra/riExtraRendererT.h +++ b/prog/gameLibs/rendInst/render/extra/riExtraRendererT.h @@ -14,6 +14,7 @@ #include #include #include +#include // Tools don't have depth prepass for trees. @@ -47,9 +48,7 @@ class RiExtraRendererT : public DynamicVariantsPolicy //-V730 uint32_t count; }; dag::Vector drawcallRanges; - dag::Vector indirectDrawcalls; ska::flat_hash_map, eastl::equal_to, Alloc> bindlessStatesToUpdateTexLevels; - dag::Vector drawcallIds; public: RiExtraRendererT() = default; @@ -73,9 +72,7 @@ class RiExtraRendererT : public DynamicVariantsPolicy //-V730 list.reserve(size_to_reserve); multidrawList.clear(); drawcallRanges.clear(); - indirectDrawcalls.clear(); bindlessStatesToUpdateTexLevels.clear(); - drawcallIds.clear(); if (layer == rendinst::LayerFlag::Transparent) startStage = endStage = ShaderMesh::STG_trans; else if (layer == rendinst::LayerFlag::Decals) @@ -114,9 +111,6 @@ class RiExtraRendererT : public DynamicVariantsPolicy //-V730 a.rstate == b.rstate && get_material_id(a.cstate) == get_material_id(b.cstate) && a.prog == b.prog; }; - indirectDrawcalls.push_back(DrawIndexedIndirectArgs{(uint32_t)multidrawList[0].numf * 3, - multidrawList[0].ofsAndCnt.y * instanceCountMultiply, (uint32_t)multidrawList[0].si, multidrawList[0].bv, 0}); - drawcallIds.push_back(PerInstanceParameters{get_material_offset(multidrawList[0].cstate), (uint32_t)multidrawList[0].ofsAndCnt.x}); drawcallRanges.push_back(PackedDrawCallsRange{0, 1}); bindlessStatesToUpdateTexLevels.emplace(multidrawList[0].cstate, multidrawList[0].texLevel); @@ -124,9 +118,6 @@ class RiExtraRendererT : public DynamicVariantsPolicy //-V730 { const auto ¤tRelem = multidrawList[i]; const bool mergeWithPrevious = mergeComparator(currentRelem, multidrawList[i - 1]); - indirectDrawcalls.push_back(DrawIndexedIndirectArgs{(uint32_t)currentRelem.numf * 3, - currentRelem.ofsAndCnt.y * instanceCountMultiply, (uint32_t)currentRelem.si, currentRelem.bv, 0}); - drawcallIds.push_back(PerInstanceParameters{get_material_offset(currentRelem.cstate), (uint32_t)currentRelem.ofsAndCnt.x}); if (mergeWithPrevious) { drawcallRanges.back().count++; @@ -146,16 +137,12 @@ class RiExtraRendererT : public DynamicVariantsPolicy //-V730 void updateDataForPackedRender() const { - G_ASSERT(indirectDrawcalls.empty() == drawcallIds.empty()); - if (indirectDrawcalls.empty()) + if (bindlessStatesToUpdateTexLevels.empty()) return; TIME_D3D_PROFILE(ri_extra_update_indirect_data); for (auto stateIdTexLevel : bindlessStatesToUpdateTexLevels) update_bindless_state(stateIdTexLevel.first, stateIdTexLevel.second); - - uint32_t startDrawId = rendinst::render::indirectDrawCallIds.update(drawcallIds.data(), drawcallIds.size()); - rendinst::render::indirectDrawCalls.fillBuffer(make_span_const(indirectDrawcalls), startDrawId); } inline void renderSortedMeshesPacked(dag::ConstSpan riResOrder) const @@ -169,6 +156,33 @@ class RiExtraRendererT : public DynamicVariantsPolicy //-V730 updateDataForPackedRender(); + multidrawContext.fillBuffers(multidrawList.size(), + [this](uint32_t draw_index, uint32_t &index_count_per_instance, uint32_t &instance_count, uint32_t &start_index_location, + int32_t &base_vertex_location, PerInstanceParameters &per_draw_data) { + index_count_per_instance = (uint32_t)multidrawList[draw_index].numf * 3; + instance_count = (uint32_t)multidrawList[draw_index].ofsAndCnt.y * instanceCountMultiply; + start_index_location = (uint32_t)multidrawList[draw_index].si; + base_vertex_location = (int32_t)multidrawList[draw_index].bv; + if (multidrawList[draw_index].ofsAndCnt.x % 4 != 0) + { + logerr("Assumption about alignment of offset in RI matrices buffer is incorrect."); + instance_count = 0; + } + const uint32_t instanceOffset = (uint32_t)multidrawList[draw_index].ofsAndCnt.x >> 2; + if (instanceOffset >= MAX_MATRIX_OFFSET) + { + logerr("Too big offset in instance matrix buffer %d.", instanceOffset); + instance_count = 0; + } + const uint32_t materialOffset = get_material_offset(multidrawList[draw_index].cstate); + if (materialOffset >= MAX_MATERIAL_OFFSET) + { + logerr("Too big material offset %d.", materialOffset); + instance_count = 0; + } + per_draw_data = (instanceOffset << MATRICES_OFFSET_SHIFT) | materialOffset; + }); + TIME_D3D_PROFILE(ri_extra_render_sorted_meshes_indirect); d3d_err(d3d::setind(unitedvdata::riUnitedVdata.getIB())); @@ -210,8 +224,8 @@ class RiExtraRendererT : public DynamicVariantsPolicy //-V730 rl.curShader->setReqTexLevel(rl.texLevel); set_states_for_variant(rl.curShader->native(), rl.cv, rl.prog, rl.state & ~rl.DISABLE_OPTIMIZATION_BIT_STATE); - d3d::multi_draw_indexed_indirect(PRIM_TRILIST, rendinst::render::indirectDrawCalls.getBuffer(), dcParams.count, - rendinst::render::indirectDrawCalls.getStride(), dcParams.start * rendinst::render::indirectDrawCalls.getStride()); + d3d::multi_draw_indexed_indirect(PRIM_TRILIST, rendinst::render::multidrawContext.getBuffer(), dcParams.count, + rendinst::render::multidrawContext.getStride(), dcParams.start * rendinst::render::multidrawContext.getStride()); } #if USE_DEPTH_PREPASS_FOR_TREES if (currentDepthPrepass) diff --git a/prog/gameLibs/rendInst/render/extraRender.cpp b/prog/gameLibs/rendInst/render/extraRender.cpp index aa80ff9e3..b4b4f97fd 100644 --- a/prog/gameLibs/rendInst/render/extraRender.cpp +++ b/prog/gameLibs/rendInst/render/extraRender.cpp @@ -494,8 +494,6 @@ void rendinst::add_ri_pool_to_tiled_scenes(rendinst::RiExtraPool &pool, int pool if (!(pool.hideMask & 2)) // mask&2 - completely invisible, never rendered { - if (pool.hasImpostor()) // todo: or we know it is dynamic object, like door/window - pool.tsIndex = DYNAMIC_SCENE; if (isDynamic) pool.tsIndex = DYNAMIC_SCENE; @@ -905,6 +903,7 @@ void rendinst::render::update_per_draw_gathered_data(uint32_t id) rendinst::render::RiShaderConstBuffers perDrawGatheredData; perDrawGatheredData.setBBoxNoChange(); perDrawGatheredData.setOpacity(0, 1); + perDrawGatheredData.setCrossDissolveRange(0); perDrawGatheredData.setRandomColors(rendinst::riExtra[id].poolColors); perDrawGatheredData.setInstancing(0, 4, 0); perDrawGatheredData.setBoundingSphere(0, 0, rendinst::riExtra[id].sphereRadius, rendinst::riExtra[id].sphereRadius, diff --git a/prog/gameLibs/rendInst/render/genRender.cpp b/prog/gameLibs/rendInst/render/genRender.cpp index 87b9a1a84..a3c245464 100644 --- a/prog/gameLibs/rendInst/render/genRender.cpp +++ b/prog/gameLibs/rendInst/render/genRender.cpp @@ -37,8 +37,7 @@ #include #include <3d/dag_resPtr.h> #include -#include <3d/dag_indirectDrawcallsBuffer.h> -#include <3d/dag_dynLinearAllocBuffer.h> +#include <3d/dag_multidrawContext.h> #include #include <3d/dag_drv3dReset.h> @@ -114,8 +113,7 @@ static VDECL rendinstDepthOnlyVDECL = BAD_VDECL; static int build_normal_type = -2; int normal_type = -1; -IndirectDrawcallsBuffer indirectDrawCalls("RI_drawcalls"); -DynLinearAllocBuffer indirectDrawCallIds("ri_drawcall_ids"); +MultidrawContext multidrawContext("ri_multidraw"); Vbuffer *oneInstanceTmVb = nullptr; Vbuffer *rotationPaletteTmVb = nullptr; @@ -408,8 +406,7 @@ void RendInstGenData::termRenderGlobals() del_d3dres(rendinst::render::perDrawCB); del_d3dres(rendinst::render::oneInstanceTmVb); del_d3dres(rendinst::render::rotationPaletteTmVb); - rendinst::render::indirectDrawCalls.close(); - rendinst::render::indirectDrawCallIds.close(); + rendinst::render::multidrawContext.close(); index_buffer::release_quads_16bit(); rendinst::render::closeClipmapShadows(); rendinst::render::close_depth_VDECL(); @@ -1208,6 +1205,9 @@ void RendInstGenData::renderPerInstance(rendinst::RenderPass render_pass, int lo float range = rtData->get_trees_last_range(rtData->rtPoolData[ri_idx]->lodRange[rtData->riResLodCount(ri_idx) - 1]); float deltaRcp = rtData->transparencyDeltaRcp / range; + float lodStartRange = safediv(visibility.crossDissolveRange[ri_idx], rendinst::render::lodsShiftDistMul); + cb.setCrossDissolveRange(lodStartRange); + if (visibility.forcedLod >= 0) { cb.setOpacity(0.f, 1.f, 0.f, 0.f); @@ -1279,10 +1279,11 @@ void RendInstGenData::renderCrossDissolve(rendinst::RenderPass render_pass, int if (render_pass == rendinst::RenderPass::Normal) cb.setRandomColors(&rtData->riColPair[ri_idx * 2 + 0]); - float lodStartRange = visibility.crossDissolveRange[ri_idx]; - lodStartRange = safediv(lodStartRange, rendinst::render::lodsShiftDistMul); + float lodStartRange = safediv(visibility.crossDissolveRange[ri_idx], rendinst::render::lodsShiftDistMul); float lodDissolveInvRange = 1.0f / TOTAL_CROSS_DISSOLVE_DIST; + cb.setCrossDissolveRange(lodStartRange); + if (render_pass == rendinst::RenderPass::ToShadow) { float range = rtData->get_trees_last_range(rtData->rtPoolData[ri_idx]->lodRange[rtData->riResLodCount(ri_idx) - 1]); @@ -1513,6 +1514,7 @@ void RendInstGenData::renderByCells(rendinst::RenderPass render_pass, const rend rendinst::render::RiShaderConstBuffers cb; cb.setOpacity(0.f, 2.f); + cb.setCrossDissolveRange(0); float subCellOfsSize = grid2worldcellSz * ((rendinst::render::per_instance_visibility_for_everyone ? 0.75f : 0.25f) * (rendinst::render::globalDistMul * 1.f / RendInstGenData::SUBCELL_DIV)); @@ -1567,6 +1569,9 @@ void RendInstGenData::renderByCells(rendinst::RenderPass render_pass, const rend rtData->rtPoolData[ri_idx]->hasImpostor() ? rtData->get_trees_range(initialLod0Range) : rtData->get_range(initialLod0Range); ShaderGlobal::set_real_fast(invLod0RangeVarId, 1.f / max(lod0Range + subCellOfsSize, 1.f)); + float lodStartRange = safediv(visibility.crossDissolveRange[ri_idx], rendinst::render::lodsShiftDistMul); + cb.setCrossDissolveRange(lodStartRange); + if (visibility.forcedLod >= 0) { cb.setOpacity(0.f, 1.f, 0.f, 0.f); diff --git a/prog/gameLibs/rendInst/render/genRender.h b/prog/gameLibs/rendInst/render/genRender.h index 5f0beacce..5c0c51922 100644 --- a/prog/gameLibs/rendInst/render/genRender.h +++ b/prog/gameLibs/rendInst/render/genRender.h @@ -14,8 +14,7 @@ #include #include #include <3d/dag_resPtr.h> -#include <3d/dag_indirectDrawcallsBuffer.h> -#include <3d/dag_dynLinearAllocBuffer.h> +#include <3d/dag_multidrawContext.h> //-V:SWITCH_STATES:501 @@ -102,8 +101,7 @@ namespace rendinst::render #define ENCODED_RENDINST_RESCALE (32767. / 256) extern shaders::UniqueOverrideStateId afterDepthPrepassOverride; -extern IndirectDrawcallsBuffer indirectDrawCalls; -extern DynLinearAllocBuffer indirectDrawCallIds; +extern MultidrawContext multidrawContext; extern bool use_ri_depth_prepass; extern int normal_type; diff --git a/prog/gameLibs/rendInst/render/impostor.cpp b/prog/gameLibs/rendInst/render/impostor.cpp index 37801a117..7f356275b 100644 --- a/prog/gameLibs/rendInst/render/impostor.cpp +++ b/prog/gameLibs/rendInst/render/impostor.cpp @@ -489,6 +489,7 @@ bool RendInstGenData::RtData::updateImpostorsPreshadow(int poolNo, const Point3 pool.setDynamicImpostorBoundingSphere(cb); cb.setOpacity(0.f, 1.f); + cb.setCrossDissolveRange(0); ShaderGlobal::setBlock(rendinst::render::globalFrameBlockId, ShaderGlobal::LAYER_FRAME); ShaderGlobal::setBlock(rendinst::render::rendinstDepthSceneBlockId, ShaderGlobal::LAYER_SCENE); @@ -882,6 +883,7 @@ void RendInstGenData::RtData::updateImpostors(float shadowDistance, const Point3 pool.setDynamicImpostorBoundingSphere(cb); cb.setOpacity(0.f, 1.f); + cb.setCrossDissolveRange(0); cb.setInstancing(0, 3, 0); rendinst::render::setCoordType(rendinst::render::COORD_TYPE_TM); diff --git a/prog/gameLibs/rendInst/render/riShaderConstBuffers.cpp b/prog/gameLibs/rendInst/render/riShaderConstBuffers.cpp index 9fdffd73d..26133fa38 100644 --- a/prog/gameLibs/rendInst/render/riShaderConstBuffers.cpp +++ b/prog/gameLibs/rendInst/render/riShaderConstBuffers.cpp @@ -77,7 +77,12 @@ void RiShaderConstBuffers::setBBox(vec4f p[2]) void RiShaderConstBuffers::setOpacity(float p0, float p1, float p2, float p3) { perDraw[0] = v_make_vec4f(p0, p1, p2, p3); } -void RiShaderConstBuffers::setBoundingBox(const vec4f &bounding_box) { perDraw[7] = bounding_box; } +void RiShaderConstBuffers::setBoundingBox(const vec4f &bounding_box) { perDraw[7] = v_perm_xyzd(bounding_box, perDraw[7]); } + +void RiShaderConstBuffers::setCrossDissolveRange(float crossDissolveRange) +{ + perDraw[7] = v_perm_xyzd(perDraw[7], v_splats(crossDissolveRange)); +} void RiShaderConstBuffers::setBoundingSphere(float p0, float p1, float sphereRadius, float cylinderRadius, float sphereCenterY) { diff --git a/prog/gameLibs/rendInst/riGen/riGenData.h b/prog/gameLibs/rendInst/riGen/riGenData.h index d66993f75..7dfdbf63e 100644 --- a/prog/gameLibs/rendInst/riGen/riGenData.h +++ b/prog/gameLibs/rendInst/riGen/riGenData.h @@ -51,6 +51,7 @@ struct RenderStateContext; struct RendInstGenData { + static constexpr int MAX_VISIBLE_CELLS = 256; static constexpr int SUBCELL_DIV = 8; enum { diff --git a/prog/gameLibs/rendInst/riGen/riGenExtra.h b/prog/gameLibs/rendInst/riGen/riGenExtra.h index afd409196..466a837d4 100644 --- a/prog/gameLibs/rendInst/riGen/riGenExtra.h +++ b/prog/gameLibs/rendInst/riGen/riGenExtra.h @@ -92,11 +92,7 @@ typedef TiledScenesGroup<4> RITiledScenes; extern RITiledScenes riExTiledScenes; extern float riExTiledSceneMaxDist[RITiledScenes::MAX_COUNT]; -struct PerInstanceParameters -{ - uint32_t materialOffset; - uint32_t matricesOffset; -}; +using PerInstanceParameters = uint32_t; void init_tiled_scenes(const DataBlock *level_blk); void term_tiled_scenes(); diff --git a/prog/gameLibs/rendInst/visibility/cellVisibility.h b/prog/gameLibs/rendInst/visibility/cellVisibility.h new file mode 100644 index 000000000..aa5a1b630 --- /dev/null +++ b/prog/gameLibs/rendInst/visibility/cellVisibility.h @@ -0,0 +1,117 @@ +#pragma once + +#include +#include +#include +#include "visibility/cullingMath.h" + +namespace rendinst +{ + +struct Cell +{ + float distance = 0.f; + uint16_t x = 0, z = 0; + uint16_t rangesStart = 0; + uint16_t rangesCount = 0; // it is actually only 5 bit, but for the sake of alignment, keep it 16bit +}; + +struct SubCellRange +{ + uint8_t start = 0; + uint8_t end = 0; +}; + +template +struct VisibleCells +{ + G_STATIC_ASSERT(subcell_div *subcell_div < eastl::numeric_limits::max()); + + static constexpr int CELL_BBOX_OFFSET = 0; + static constexpr int SUBCELL_BBOX_OFFSET = 1; + static constexpr int MAX_VISIBLE_CELLS = max_visible_cells; + static constexpr int MAX_VISIBLE_SUBCELLS = MAX_VISIBLE_CELLS * 2 * (subcell_div * subcell_div / 2 + 1); + + dag::RelocatableFixedVector cells = {}; + dag::RelocatableFixedVector subCellRanges = {}; + VisibleCells() {} + + inline void calcInsideVisibility(Cell &cell, const bbox3f *__restrict bbox, Occlusion *occlusion) + { + uint8_t startRange = 0; + uint8_t endRange = subcell_div * subcell_div - 1; + if (occlusion) + { + for (; startRange < subcell_div * subcell_div; ++startRange) + if (!occlusion->isOccludedBox(bbox[startRange + SUBCELL_BBOX_OFFSET].bmin, bbox[startRange + SUBCELL_BBOX_OFFSET].bmax)) + break; + + for (; endRange > startRange; --endRange) + if (!occlusion->isOccludedBox(bbox[endRange + SUBCELL_BBOX_OFFSET].bmin, bbox[endRange + SUBCELL_BBOX_OFFSET].bmax)) + break; + + if (endRange < startRange) + return; + } + + subCellRanges.emplace_back(SubCellRange{startRange, endRange}); + cell.rangesCount += 1; + } + + inline void calcIntersectVisibility(Cell &cell, const bbox3f *__restrict bbox, Occlusion *occlusion, const vec4f *__restrict planes, + int n_planes) + { + for (uint8_t range = 0; range < subcell_div * subcell_div; ++range) + { + const auto bboxIdx = range + SUBCELL_BBOX_OFFSET; + if (test_box_planesb(bbox[bboxIdx].bmin, bbox[bboxIdx].bmax, planes, n_planes)) + { + if (occlusion && occlusion->isOccludedBox(bbox[bboxIdx].bmin, bbox[bboxIdx].bmax)) + continue; + if (!cell.rangesCount || subCellRanges.back().end != range - 1) + { + subCellRanges.emplace_back(SubCellRange{range, range}); + cell.rangesCount++; + } + else + subCellRanges.back().end = range; + } + } + } + + inline void calcCellVisibility(int cell_x, int cell_z, vec3f view_pos, const Frustum &frustum, const bbox3f *__restrict bbox, + Occlusion *occlusion) + { + if (cells.size() >= max_visible_cells) + return; + + Cell cell{}; + int nPlanes; + vec4f planes[6]; + + int cellIntersection = test_box_planes(bbox[0].bmin, bbox[0].bmax, frustum, planes, nPlanes); + + if (cellIntersection == Frustum::OUTSIDE) + return; + + if (occlusion && occlusion->isOccludedBox(bbox[CELL_BBOX_OFFSET].bmin, bbox[CELL_BBOX_OFFSET].bmax)) + return; + + cell.distance = v_extract_x(v_sqrt_x(v_distance_sq_to_bbox_x(bbox[0].bmin, bbox[0].bmax, view_pos))); + cell.rangesStart = subCellRanges.size(); + + if (cellIntersection == Frustum::INSIDE) //-V1051 + calcInsideVisibility(cell, bbox, occlusion); + else + calcIntersectVisibility(cell, bbox, occlusion, planes, nPlanes); + + if (cell.rangesCount != 0) + { + cell.x = cell_x; + cell.z = cell_z; + cells.emplace_back(eastl::move(cell)); + } + } +}; + +} // namespace rendinst diff --git a/prog/gameLibs/rendInst/visibility/genVisibility.cpp b/prog/gameLibs/rendInst/visibility/genVisibility.cpp index 5295426f2..be26e3d46 100644 --- a/prog/gameLibs/rendInst/visibility/genVisibility.cpp +++ b/prog/gameLibs/rendInst/visibility/genVisibility.cpp @@ -4,6 +4,7 @@ #include "render/genRender.h" #include "riGen/genObjUtil.h" +#include "visibility/cellVisibility.h" #include "visibility/cullingMath.h" #include @@ -89,100 +90,6 @@ void rendinst::sortRIGenVisibility(RiGenVisibility *visibility, const Point3 &vi rgl->sortRIGenVisibility(visibility[_layer], viewPos, viewDir, vertivalFov, horizontalFov, areaThreshold); } -static inline bool getSubCellsVisibility(vec3f curViewPos, const Frustum &frustum, const bbox3f *__restrict bbox, - uint16_t &ranges_count, uint8_t *ranges, float &cellDist, Occlusion *use_occlusion) -{ - G_STATIC_ASSERT(RendInstGenData::SUBCELL_DIV == 8); - G_STATIC_ASSERT(RendInstGenData::SUBCELL_DIV * RendInstGenData::SUBCELL_DIV <= 256); - - int nPlanes; - vec4f planes[6]; - int cellIntersection = test_box_planes(bbox[0].bmin, bbox[0].bmax, frustum, planes, nPlanes); - if (cellIntersection == Frustum::OUTSIDE) - { - ranges_count = 0; - return false; - } - if (use_occlusion) - { - if (use_occlusion->isOccludedBox(bbox[0].bmin, bbox[0].bmax)) - { - ranges_count = 0; - return false; - } - } - cellDist = v_extract_x(v_sqrt_x(v_distance_sq_to_bbox_x(bbox[0].bmin, bbox[0].bmax, curViewPos))); - if (cellIntersection == Frustum::INSIDE) //-V1051 - { - if (use_occlusion) - { - int idx = 1; - for (; idx < RendInstGenData::SUBCELL_DIV * RendInstGenData::SUBCELL_DIV + 1; ++idx) - if (!use_occlusion->isOccludedBox(bbox[idx].bmin, bbox[idx].bmax)) - break; - - int idx2 = RendInstGenData::SUBCELL_DIV * RendInstGenData::SUBCELL_DIV; - for (; idx2 > idx; --idx2) - if (!use_occlusion->isOccludedBox(bbox[idx2].bmin, bbox[idx2].bmax)) - break; - if (idx2 < idx) - { - ranges_count = 0; - return false; - } - ranges[0] = idx - 1; - ranges[1] = idx2 - 1; - } - else - { - ranges[0] = 0; - ranges[1] = RendInstGenData::SUBCELL_DIV * RendInstGenData::SUBCELL_DIV - 1; - } - ranges_count = 1; - return true; - } - - - ranges_count = 0; - for (int idx = 1; idx < RendInstGenData::SUBCELL_DIV * RendInstGenData::SUBCELL_DIV + 1; ++idx) - { - if (test_box_planesb(bbox[idx].bmin, bbox[idx].bmax, planes, nPlanes)) - { - if (use_occlusion) - { - if (use_occlusion->isOccludedBox(bbox[idx].bmin, bbox[idx].bmax)) - continue; - } - if (!ranges_count || ranges[-1] != idx - 2) - { - ranges[0] = ranges[1] = idx - 1; - ranges += 2; - ranges_count++; - } - else - ranges[-1] = idx - 1; - } - } - return ranges_count != 0; -} - -struct RendInstGenRenderPrepareData -{ - static constexpr int MAX_VISIBLE_CELLS = 256; - int totalVisibleCells; - struct Cell - { - float distance; - uint16_t x, z; - uint16_t rangesStart; - uint16_t rangesCount; // it is actually only 5 bit, but for the sake of alignment, keep it 16bit - }; - carray cells = {}; - carray cellRanges = {}; - int visibleCellsCount() const { return totalVisibleCells; } - RendInstGenRenderPrepareData() : totalVisibleCells(0) {} -}; - struct SortByY { bool operator()(const IPoint2 &a, const IPoint2 &b) const { return a.y < b.y; } @@ -244,29 +151,7 @@ bool RendInstGenData::prepareVisibility(const Frustum &frustum, const Point3 &ca visibility.resizeRanges(rtData->riRes.size(), forShadow ? 4 : 8); ScopedLockRead lock(rtData->riRwCs); - RendInstGenRenderPrepareData visData; - uint8_t *ranges = visData.cellRanges.data(); - -#define PREPARE_CELL(XX, ZZ) \ - { \ - const RendInstGenData::Cell &cell = cells[cellI]; \ - const RendInstGenData::CellRtData *crt_ptr = cell.isReady(); \ - if (crt_ptr && visData.totalVisibleCells < visData.MAX_VISIBLE_CELLS) \ - { \ - int cellNo = visData.visibleCellsCount(); \ - RendInstGenRenderPrepareData::Cell &visCell = visData.cells[cellNo]; \ - if (getSubCellsVisibility(curViewPos, curFrustum, crt_ptr->bbox.data(), visCell.rangesCount, ranges, visCell.distance, \ - use_occlusion)) \ - { \ - visCell.x = XX, visCell.z = ZZ; \ - visCell.rangesStart = ranges - visData.cellRanges.data(); \ - visCell.rangesCount *= 2; \ - ranges += visCell.rangesCount; \ - G_ASSERT((int)(ranges - visData.cellRanges.data()) < visData.cellRanges.size()); \ - visData.totalVisibleCells++; \ - } \ - } \ - } + rendinst::VisibleCells visData; rtData->loadedCellsBBox.clip(regions[0], regions[1], regions[2], regions[3]); @@ -284,13 +169,17 @@ bool RendInstGenData::prepareVisibility(const Frustum &frustum, const Point3 &ca unsigned int startCellI = startCellX + startCellZ * cellNumW; { + const auto calcRiCellVisibility = [&](int cell_idx, int cell_x, int cell_z) { + const auto cellRtData = cells[cell_idx].isReady(); + if (cellRtData) + visData.calcCellVisibility(cell_x, cell_z, curViewPos, curFrustum, cellRtData->bbox.data(), use_occlusion); + }; + int maxRadius = max(max((regions[3] - startCellZ), (startCellZ - regions[1])), max((regions[2] - startCellX), (startCellX - regions[0]))); if (startCellX >= 0 && startCellX < cellNumW && startCellZ < cellNumH && startCellZ >= 0) - { - int cellI = startCellI; - PREPARE_CELL(startCellX, startCellZ); - } + calcRiCellVisibility(startCellI, startCellX, startCellZ); + int minX, maxX; int minZ, maxZ; for (int radius = 1; radius <= maxRadius; ++radius) @@ -300,23 +189,23 @@ bool RendInstGenData::prepareVisibility(const Frustum &frustum, const Point3 &ca if (minZ >= regions[1] && minZ <= regions[3]) for (int x = max(minX, regions[0]), cellI = minZ * cellNumW + x; x <= min(maxX, regions[2]); x++, cellI++) - PREPARE_CELL(x, minZ); + calcRiCellVisibility(cellI, x, minZ); if (maxZ <= regions[3] && maxZ >= regions[1]) for (int x = max(minX, regions[0]), cellI = maxZ * cellNumW + x; x <= min(maxX, regions[2]); x++, cellI++) - PREPARE_CELL(x, maxZ); + calcRiCellVisibility(cellI, x, maxZ); if (minX >= regions[0] && minX <= regions[2]) for (int z = max(minZ + 1, regions[1]), cellI = z * cellNumW + minX; z <= min(maxZ - 1, regions[3]); z++, cellI += cellNumW) - PREPARE_CELL(minX, z); + calcRiCellVisibility(cellI, minX, z); if (maxX <= regions[2] && maxX >= regions[0]) for (int z = max(minZ + 1, regions[1]), cellI = z * cellNumW + maxX; z <= min(maxZ - 1, regions[3]); z++, cellI += cellNumW) - PREPARE_CELL(maxX, z); + calcRiCellVisibility(cellI, maxX, z); } } #undef PREPARE_CELL - if (!visData.visibleCellsCount()) + if (!visData.cells.size()) return false; mem_set_0(visibility.instNumberCounter); float subCellOfsSize = grid2worldcellSz * ((rendinst::render::per_instance_visibility_for_everyone ? 0.75f : 0.25f) * @@ -330,7 +219,7 @@ bool RendInstGenData::prepareVisibility(const Frustum &frustum, const Point3 &ca if (rendinst::render::per_instance_visibility) { visibility.startTreeInstances(); - for (int vi = 0; vi < min(MAX_PER_INSTANCE_CELLS, visData.visibleCellsCount()); ++vi) + for (int vi = 0; vi < min(MAX_PER_INSTANCE_CELLS, visData.cells.size()); ++vi) { int x = visData.cells[vi].x; int z = visData.cells[vi].z; @@ -480,7 +369,7 @@ bool RendInstGenData::prepareVisibility(const Frustum &frustum, const Point3 &ca rendinst::gen::RotationPaletteManager::Palette palette = rendinst::gen::get_rotation_palette_manager()->getPalette({rtData->layerIdx, (int)ri_idx}); - for (int vi = 0; vi < visData.visibleCellsCount(); vi++) + for (int vi = 0; vi < visData.cells.size(); vi++) { int x = visData.cells[vi].x; int z = visData.cells[vi].z; @@ -534,17 +423,16 @@ bool RendInstGenData::prepareVisibility(const Frustum &frustum, const Point3 &ca lodI = rtData->riRes[ri_idx]->getQlBestLod(); int cellAdded = -1; - for (uint8_t *rangeI = visData.cellRanges.data() + visData.cells[vi].rangesStart, - *end = rangeI + visData.cells[vi].rangesCount; - rangeI != end; rangeI += 2) + for (auto range = visData.subCellRanges.begin() + visData.cells[vi].rangesStart, end = range + visData.cells[vi].rangesCount; + range != end; range++) { - const RendInstGenData::CellRtData::SubCellSlice &scss = crt.getCellSlice(ri_idx, rangeI[0]); - const RendInstGenData::CellRtData::SubCellSlice &scse = crt.getCellSlice(ri_idx, rangeI[1]); + const RendInstGenData::CellRtData::SubCellSlice &scss = crt.getCellSlice(ri_idx, range->start); + const RendInstGenData::CellRtData::SubCellSlice &scse = crt.getCellSlice(ri_idx, range->end); if (scse.ofs + scse.sz == scss.ofs) continue; // add to farLodNo if (cellAdded < 0) - cellAdded = visibility.addCell(lodI, x, z, startVbOfs, visData.cells[vi].rangesCount >> 1); + cellAdded = visibility.addCell(lodI, x, z, startVbOfs, visData.cells[vi].rangesCount); visibility.addRange(lodI, scss.ofs, (scse.ofs + scse.sz - scss.ofs)); visibility.instNumberCounter[lodI] += (scse.ofs + scse.sz - scss.ofs) / visibility.stride; } @@ -557,21 +445,21 @@ bool RendInstGenData::prepareVisibility(const Frustum &frustum, const Point3 &ca carray cellAdded; int lastLod = -1; mem_set_ff(cellAdded); - for (uint8_t *rangeI = visData.cellRanges.data() + visData.cells[vi].rangesStart, - *end = rangeI + visData.cells[vi].rangesCount; - rangeI != end; rangeI += 2) + for (auto range = visData.subCellRanges.begin() + visData.cells[vi].rangesStart, end = range + visData.cells[vi].rangesCount; + range != end; range++) { - const RendInstGenData::CellRtData::SubCellSlice &scss = crt.getCellSlice(ri_idx, rangeI[0]); - const RendInstGenData::CellRtData::SubCellSlice &scse = crt.getCellSlice(ri_idx, rangeI[1]); + const RendInstGenData::CellRtData::SubCellSlice &scss = crt.getCellSlice(ri_idx, range->start); + const RendInstGenData::CellRtData::SubCellSlice &scse = crt.getCellSlice(ri_idx, range->end); if (scse.ofs + scse.sz == scss.ofs) continue; - for (int cri = rangeI[0]; cri <= rangeI[1]; ++cri) + for (int cri = range->start; cri <= range->end; ++cri) { const RendInstGenData::CellRtData::SubCellSlice &sc = crt.getCellSlice(ri_idx, cri); if (!sc.sz) // empty subcell continue; - float subCellDistSq = v_extract_x(v_distance_sq_to_bbox_x(crt.bbox[cri + 1].bmin, crt.bbox[cri + 1].bmax, curViewPos)); + const auto bboxIdx = cri + visData.SUBCELL_BBOX_OFFSET; + float subCellDistSq = v_extract_x(v_distance_sq_to_bbox_x(crt.bbox[bboxIdx].bmin, crt.bbox[bboxIdx].bmax, curViewPos)); float maxDistSq = visibility.forcedLod < 0 ? farLodEndRangeSq : forcedLodDistSq; if (subCellDistSq >= maxDistSq) @@ -579,7 +467,7 @@ bool RendInstGenData::prepareVisibility(const Frustum &frustum, const Point3 &ca if (use_external_filter) { - if (!external_filter(crt.bbox[cri + 1].bmin, crt.bbox[cri + 1].bmax)) + if (!external_filter(crt.bbox[bboxIdx].bmin, crt.bbox[bboxIdx].bmax)) continue; } if (vi < MAX_PER_INSTANCE_CELLS && pool.hasImpostor() && rendinst::render::per_instance_visibility) // todo: support not diff --git a/prog/gameLibs/render/cables/cables.cpp b/prog/gameLibs/render/cables/cables.cpp index 6272a4163..ae0ef33db 100644 --- a/prog/gameLibs/render/cables/cables.cpp +++ b/prog/gameLibs/render/cables/cables.cpp @@ -173,15 +173,14 @@ void Cables::destroyCables() tiledArea.grid.size(), cables.size(), destroyedRIExtra.size()); for (RIExtraInfo &riex : destroyedRIExtra) { - TMatrix tm = riex.tm; mat44f riTm; bbox3f riBBox; - v_mat44_make_from_43cu_unsafe(riTm, tm.array); + v_mat44_make_from_43cu_unsafe(riTm, riex.tm.array); v_bbox3_init(riBBox, riTm, v_ldu_bbox3(riex.box)); G_ASSERT_CONTINUE(!isnan(v_extract_x(riBBox.bmin)) && !isnan(v_extract_x(riBBox.bmax)) && !isnan(v_extract_z(riBBox.bmin)) && !isnan(v_extract_z(riBBox.bmax))); // inverse matrix usage is more accurate, but seems it works well as is - // TMatrix invTm = inverse(tm); + // TMatrix invTm = inverse(riex.tm); int i_start = max((v_extract_x(riBBox.bmin) - tiledArea.gridBoundMin.x) / tiledArea.tileSize.x, 0); int i_end = min((v_extract_x(riBBox.bmax) - tiledArea.gridBoundMin.x) / tiledArea.tileSize.x + 1, tiledArea.gridSize.x); int j_start = max((v_extract_z(riBBox.bmin) - tiledArea.gridBoundMin.y) / tiledArea.tileSize.y, 0); @@ -194,7 +193,7 @@ void Cables::destroyCables() { CablePointInfo &info = tiledArea.cables_points[tile.start + k]; float4 &point = info.cableEnd ? cables[info.cableIndex].point2_sag : cables[info.cableIndex].point1_rad; - // Point3 localPoint = invTm % (Point3::xyz(point) - tm.getcol(3)); + // Point3 localPoint = invTm % (Point3::xyz(point) - riex.tm.getcol(3)); // if (riex.box & localPoint) if (v_bbox3_test_pt_inside(riBBox, v_ldu(&point.x))) setCable(info.cableIndex, Point3(0, 0, 0), Point3(0, 0, 0), 0, 0); diff --git a/prog/gameLibs/render/daBfg/backend/resourceScheduling/nativeResourceScheduler.cpp b/prog/gameLibs/render/daBfg/backend/resourceScheduling/nativeResourceScheduler.cpp index 5a46b32cb..dea4302e7 100644 --- a/prog/gameLibs/render/daBfg/backend/resourceScheduling/nativeResourceScheduler.cpp +++ b/prog/gameLibs/render/daBfg/backend/resourceScheduling/nativeResourceScheduler.cpp @@ -4,6 +4,7 @@ #include #include <3d/dag_resizableTex.h> #include <3d/dag_resPtr.h> +#include <3d/dag_drv3d.h> #include #include @@ -14,23 +15,11 @@ namespace dabfg { -static uint32_t auto_mip_levels_count(uint32_t w, uint32_t h) -{ - uint32_t lev = 1; - uint32_t t = min(w, h); - while (t > 1) - { - lev++; - t >>= 1; - } - return lev; -} - static ResourceDescription fix_tex_params(const ResourceDescription &desc) { ResourceDescription fixed_desc = desc; if (desc.asTexRes.mipLevels == AUTO_MIP_COUNT) - fixed_desc.asTexRes.mipLevels = auto_mip_levels_count(desc.asTexRes.width, desc.asTexRes.height); + fixed_desc.asTexRes.mipLevels = auto_mip_levels_count(desc.asTexRes.width, desc.asTexRes.height, 1); return fixed_desc; } diff --git a/prog/gameLibs/render/daBfg/backend/resourceScheduling/packers/boxingPacker.cpp b/prog/gameLibs/render/daBfg/backend/resourceScheduling/packers/boxingPacker.cpp index 7d6a1e054..38fa4a352 100644 --- a/prog/gameLibs/render/daBfg/backend/resourceScheduling/packers/boxingPacker.cpp +++ b/prog/gameLibs/render/daBfg/backend/resourceScheduling/packers/boxingPacker.cpp @@ -839,7 +839,7 @@ class UnitJobBoxer TimePoint left, right; // Important: this does not include end points! - bool openIntervalContains(TimePoint x) const { return left < x && x < right || (left >= right && (x < right || left < x)); } + bool openIntervalContains(TimePoint x) const { return (left < x && x < right) || (left >= right && (x < right || left < x)); } friend __forceinline bool operator==(const Segment &fst, const Segment &snd) { @@ -967,7 +967,7 @@ class UnitJobBoxer static __forceinline bool jobAliveAt(Job job, TimePoint x) { - return job.left <= x && x < job.right || (job.left >= job.right && (x < job.right || job.left <= x)); + return (job.left <= x && x < job.right) || (job.left >= job.right && (x < job.right || job.left <= x)); } void boxAliveAtT(const eastl::span alive_job_idxs, const TimePoint crit_point, FmemVector &out_unresolved) diff --git a/prog/gameLibs/render/depthAOAboveRenderer.cpp b/prog/gameLibs/render/depthAOAboveRenderer.cpp index 9c9be640e..ef0a1a0c7 100644 --- a/prog/gameLibs/render/depthAOAboveRenderer.cpp +++ b/prog/gameLibs/render/depthAOAboveRenderer.cpp @@ -14,49 +14,78 @@ #include #include -static int world_to_depth_aoVarId = -1; -static int depth_ao_heightsVarId = -1; -static int depth_ao_tex_to_blurVarId = -1; -static int depth_ao_texture_rcp_sizeVarId = -1; -static int depth_ao_texture_sizeVarId = -1; -static int depth_above_transparentVarId = -1; -static int blurred_depth_transparentVarId = -1; +#define GLOBAL_VARS_LIST \ + VAR(world_to_depth_ao) \ + VAR(depth_ao_heights) \ + VAR(depth_ao_tex_to_blur) \ + VAR(depth_ao_texture_size) \ + VAR(depth_ao_texture_rcp_size) \ + VAR(world_to_depth_ao_extra) \ + VAR(depth_ao_heights_extra) \ + VAR(blurred_depth) + +#define GLOBAL_VARS_LIST_OPT \ + VAR(depth_around_transparent) \ + VAR(blurred_depth_transparent) \ + VAR(heightmap_min_max) \ + VAR(depth_above_copy_layer) \ + VAR(depth_ao_extra_enabled) \ + VAR(depth_above_blur_layer) + +#define VAR(a) static int a##VarId = -1; +GLOBAL_VARS_LIST +#undef VAR + +#define VAR(a) static int a##VarId = -1; +GLOBAL_VARS_LIST_OPT +#undef VAR + +static void init_shader_vars() +{ +#define VAR(a) a##VarId = get_shader_variable_id(#a); + GLOBAL_VARS_LIST +#undef VAR +#define VAR(a) a##VarId = get_shader_variable_id(#a, true); + GLOBAL_VARS_LIST_OPT +#undef VAR +} -DepthAOAboveRenderer::DepthAOAboveRenderer(const int texSize, const float depth_around_distance, bool render_transparent) : - depthAroundDistance(depth_around_distance), sceneMinMaxZ(0, 0), renderTransparent(render_transparent) +DepthAOAboveRenderer::DepthAOAboveRenderer(const int tex_size, const float depth_around_distance, bool render_transparent, + bool use_extra_cascade, float extra_cascade_mult) : + texSize(tex_size), sceneMinMaxZ(0, 0), renderTransparent(render_transparent), extraCascadeMult(extra_cascade_mult) { - worldAODepth = dag::create_tex(NULL, texSize, texSize, TEXCF_RTARGET | TEXFMT_DEPTH16, 1, "depth_around"); - worldAODepth->texfilter(TEXFILTER_POINT); - blurredDepth = dag::create_tex(NULL, texSize, texSize, TEXCF_RTARGET | TEXFMT_L16, 1, "blurred_depth"); + init_shader_vars(); + const int numCascades = use_extra_cascade ? 2 : 1; + ShaderGlobal::set_int(depth_ao_extra_enabledVarId, use_extra_cascade ? 1 : 0); + worldAODepth = dag::create_array_tex(texSize, texSize, numCascades, TEXCF_RTARGET | TEXFMT_DEPTH16, 1, "depth_around"); + worldAODepth->texfilter(TEXFILTER_POINT); + blurredDepth = dag::create_array_tex(texSize, texSize, numCascades, TEXCF_RTARGET | TEXFMT_L16, 1, "blurred_depth"); - depth_above_transparentVarId = ::get_shader_glob_var_id("depth_around_transparent", true); - blurred_depth_transparentVarId = ::get_shader_glob_var_id("blurred_depth_transparent", true); if (renderTransparent) { copyRegionsRenderer.init("depth_above_copy_regions"); worldAODepthWithTransparency = - dag::create_tex(NULL, texSize, texSize, TEXCF_RTARGET | TEXFMT_DEPTH16, 1, "depth_around_transparent"); + dag::create_array_tex(texSize, texSize, numCascades, TEXCF_RTARGET | TEXFMT_DEPTH16, 1, "depth_around_transparent"); worldAODepthWithTransparency->texfilter(TEXFILTER_POINT); - blurredDepthWithTransparency = dag::create_tex(NULL, texSize, texSize, TEXCF_RTARGET | TEXFMT_L16, 1, "blurred_depth_transparent"); + blurredDepthWithTransparency = + dag::create_array_tex(texSize, texSize, numCascades, TEXCF_RTARGET | TEXFMT_L16, 1, "blurred_depth_transparent"); } else { - ShaderGlobal::set_texture(depth_above_transparentVarId, worldAODepth); + ShaderGlobal::set_texture(depth_around_transparentVarId, worldAODepth); ShaderGlobal::set_texture(blurred_depth_transparentVarId, blurredDepth); } - // worldAODepth.getTex2D()->texaddr(TEXADDR_WRAP); - // displacementData.curOrigin = IPoint2(-1000000, 1000000); - // displacementData.texSize = texSize; - worldAODepthData.curOrigin = IPoint2(-1000000, 1000000); - worldAODepthData.texSize = texSize; - world_to_depth_aoVarId = ::get_shader_variable_id("world_to_depth_ao"); - depth_ao_heightsVarId = ::get_shader_glob_var_id("depth_ao_heights"); - depth_ao_tex_to_blurVarId = ::get_shader_glob_var_id("depth_ao_tex_to_blur"); - depth_ao_texture_sizeVarId = ::get_shader_glob_var_id("depth_ao_texture_size"); - depth_ao_texture_rcp_sizeVarId = ::get_shader_glob_var_id("depth_ao_texture_rcp_size"); + cascadeDependantData.resize(numCascades); + for (int i = 0; i < cascadeDependantData.size(); ++i) + { + cascadeDependantData[i].worldAODepthData.curOrigin = IPoint2(-1000000, 1000000); + cascadeDependantData[i].worldAODepthData.texSize = texSize; + cascadeDependantData[i].depthAroundDistance = i == 0 ? depth_around_distance : depth_around_distance * extraCascadeMult; + } + shaders::OverrideState state; state.set(shaders::OverrideState::Z_FUNC); @@ -67,56 +96,6 @@ DepthAOAboveRenderer::DepthAOAboveRenderer(const int texSize, const float depth_ zWriteOnStateId = shaders::overrides::create(state); } -/*struct WorldDepthCallback -{ - float texelSize; - DisplacementCallback(float texel, LandMeshRenderer &lmRenderer, LandMeshManager &lmMgr):texelSize(texel), cm(lmRenderer, lmMgr){} - float minZ, maxZ; - ViewProjMatrixContainer oviewproj; - void start(const IPoint2 &texelOrigin) - { - Point2 center = point2(texelOrigin)*texelSize; - Point3 pos(center.x, ::grs_cur_view.pos.y, center.y); - BBox3 landBox = provider.getBBox(); - minZ = landBox[0].y-10; - maxZ = landBox[1].y+10; - - TMatrix vtm = TMatrix::IDENT; - d3d_get_view_proj(oviewproj); - vtm.setcol(0, 1, 0, 0); - vtm.setcol(1, 0, 0, 1); - vtm.setcol(2, 0, 1, 0); - d3d::settm(TM_VIEW, vtm); - - } - virtual void end() - { - renderer.setRenderInBBox(BBox3()); - ShaderGlobal::setBlock(-1, ShaderGlobal::LAYER_SCENE); - WorldRenderer::set_lmesh_rendering_mode(omode); - d3d_set_view_proj(oviewproj); - } - - virtual void renderTile(const BBox2 ®ion) - { - TMatrix4 proj; - proj = matrix_ortho_off_center_lh(region[0].x, region[1].x, - region[1].y, region[0].y, - maxZ, minZ); - d3d::settm(TM_PROJ, &proj); - BBox3 region3(Point3(region[0].x, minZ, region[0].y), Point3(region[1].x, maxZ+500, region[1].y)); - renderer.setRenderInBBox(region3); - //d3d::clearview(CLEAR_TARGET,0xFF00FF00, 0,0); - } - void renderQuad(const IPoint2 <, const IPoint2 &wd, const IPoint2 &texelsFrom) - { - d3d::setview(lt.x, lt.y, wd.x, wd.y, 0, 1); - d3d::clearview(CLEAR_ZBUFFER,0,0,0); - BBox2 box(point2(texelsFrom)*texelSize, point2(texelsFrom+wd)*texelSize); - cm.renderTile(box); - } -};*/ - struct GatherRegionsCallback { StaticTab regions; @@ -167,7 +146,6 @@ inline void wrap_quads(IBBox2 box, int tex_sz, T &quads) DepthAOAboveRenderer::BlurDepthRenderer::BlurDepthRenderer() { - blurred_depthVarId = ::get_shader_variable_id("blurred_depth"); CompiledShaderChannelId channels[] = {{SCTYPE_FLOAT2, SCUSAGE_POS, 0, 0}, {SCTYPE_FLOAT4, SCUSAGE_TC, 0, 0}}; blurDepth.reset(nullptr); blurDepth = eastl::make_unique(); @@ -178,13 +156,14 @@ DepthAOAboveRenderer::BlurDepthRenderer::~BlurDepthRenderer() = default; void DepthAOAboveRenderer::BlurDepthRenderer::render(BaseTexture *target, TEXTUREID depth_tid, ToroidalHelper &worldAODepthData, - Tab &tris) + Tab &tris, int cascade_no) { - d3d::set_render_target((Texture *)target, 0); + d3d::set_render_target((Texture *)target, cascade_no, 0); ShaderGlobal::set_texture(depth_ao_tex_to_blurVarId, depth_tid); ShaderGlobal::set_real(depth_ao_texture_sizeVarId, worldAODepthData.texSize); ShaderGlobal::set_real(depth_ao_texture_rcp_sizeVarId, 1.0f / worldAODepthData.texSize); + ShaderGlobal::set_int(depth_above_blur_layerVarId, cascade_no); blurDepth->shader->setStates(0, true); d3d::draw_up(PRIM_TRILIST, tris.size() / 3, tris.data(), elem_size(tris)); d3d::resource_barrier({target, RB_RO_SRV | RB_STAGE_COMPUTE | RB_STAGE_PIXEL, 0, 0}); @@ -192,16 +171,18 @@ void DepthAOAboveRenderer::BlurDepthRenderer::render(BaseTexture *target, TEXTUR void DepthAOAboveRenderer::renderAODepthQuads(dag::ConstSpan regions, IRenderDepthAOCB &renderDepthCb, - BaseTexture *depthTex, bool transparent) + BaseTexture *depthTex, RenderDepthAOType type, RenderDepthAOClearFirst clear_mode, int cascade_no) { TIME_D3D_PROFILE(render_depth_above_quads); - const float fullDistance = 2.0f * depthAroundDistance; - float texelSize = (fullDistance / worldAODepthData.texSize); + const CascadeDependantData &cascadeData = cascadeDependantData[cascade_no]; + + const float fullDistance = 2.0f * cascadeData.depthAroundDistance; + float texelSize = (fullDistance / texSize); d3d::set_render_target(); d3d::set_render_target(0, (Texture *)NULL, 0); - d3d::set_depth(depthTex, DepthAccess::RW); + d3d::set_depth(depthTex, cascade_no, DepthAccess::RW); for (int i = 0; i < regions.size(); ++i) { @@ -210,61 +191,65 @@ void DepthAOAboveRenderer::renderAODepthQuads(dag::ConstSpan reg continue; const IPoint2 < = region.reg.lt; const IPoint2 &wd = region.reg.wd; - const IPoint2 viewLt(lt.x, worldAODepthData.texSize - lt.y - wd.y); + const IPoint2 viewLt(lt.x, texSize - lt.y - wd.y); const IPoint2 &texelsFrom = region.reg.texelsFrom; BBox2 reg(point2(texelsFrom) * texelSize, point2(texelsFrom + wd) * texelSize); d3d::setglobtm((mat44f_cref)region.cullViewProj); d3d::setview(viewLt.x, viewLt.y, wd.x, wd.y, 0, 1); - if (!transparent) + if (clear_mode == RenderDepthAOClearFirst::Yes) d3d::clearview(CLEAR_ZBUFFER, 0, 0.0f, 0); - else + + if (type & RenderDepthAOType::Transparent) shaders::overrides::set(zWriteOnStateId); Point3 origin = Point3::xVy(reg.center(), 0.5 * (sceneMinMaxZ.x + sceneMinMaxZ.y)); - renderDepthCb.renderDepthAO(origin, (mat44f_cref)regions[i].cullViewProj, depthAroundDistance, i, transparent); - shaders::overrides::reset(); + renderDepthCb.renderDepthAO(origin, (mat44f_cref)regions[i].cullViewProj, cascadeData.depthAroundDistance, i, type, cascade_no); + if (type & RenderDepthAOType::Transparent) + shaders::overrides::reset(); } d3d::resource_barrier({depthTex, RB_RO_SRV | RB_STAGE_COMPUTE | RB_STAGE_PIXEL, 0, 0}); } -void DepthAOAboveRenderer::copyDepthAboveRegions(dag::ConstSpan regions) +void DepthAOAboveRenderer::copyDepthAboveRegions(dag::ConstSpan regions, BaseTexture *depthTex, int cascade_no) { TIME_D3D_PROFILE(copy_depth_above_regions) d3d::set_render_target(); d3d::set_render_target(0, (Texture *)NULL, 0); shaders::overrides::set(zFuncAlwaysStateId); - d3d::set_depth(worldAODepthWithTransparency.getTex2D(), DepthAccess::RW); + d3d::set_depth(depthTex, cascade_no, DepthAccess::RW); + ShaderGlobal::set_int(depth_above_copy_layerVarId, cascade_no); for (auto region : regions) { if (region.reg.wd.x <= 0 || region.reg.wd.y <= 0) continue; - { - TIME_D3D_PROFILE(copy_one_region) - IPoint2 wd = region.reg.wd; - IPoint2 lt = region.reg.lt; - IPoint2 from = IPoint2(lt.x, worldAODepthData.texSize - lt.y - wd.y); + TIME_D3D_PROFILE(copy_one_region) - d3d::setview(from.x, from.y, wd.x, wd.y, 0, 1); - copyRegionsRenderer.render(); - } + IPoint2 wd = region.reg.wd; + IPoint2 lt = region.reg.lt; + IPoint2 from = IPoint2(lt.x, texSize - lt.y - wd.y); + + d3d::setview(from.x, from.y, wd.x, wd.y, 0, 1); + copyRegionsRenderer.render(); } shaders::overrides::reset(); } -void DepthAOAboveRenderer::renderAODepthQuadsTransparent(dag::ConstSpan regions, IRenderDepthAOCB &renderDepthCb) +void DepthAOAboveRenderer::renderAODepthQuadsTransparent(dag::ConstSpan regions, IRenderDepthAOCB &renderDepthCb, + RenderDepthAOClearFirst clear_mode, int cascade_no) { if (worldAODepthWithTransparency.getTexId() != BAD_TEXTUREID) { - copyDepthAboveRegions(regions); - renderAODepthQuads(regions, renderDepthCb, worldAODepthWithTransparency.getTex2D(), true); // render transparent + copyDepthAboveRegions(regions, worldAODepthWithTransparency.getArrayTex(), cascade_no); + renderAODepthQuads(regions, renderDepthCb, worldAODepthWithTransparency.getArrayTex(), RenderDepthAOType::Transparent, clear_mode, + cascade_no); } } -void DepthAOAboveRenderer::renderAODepthQuads(dag::ConstSpan regions, IRenderDepthAOCB &renderDepthCb) +void DepthAOAboveRenderer::renderAODepthQuads(dag::ConstSpan regions, IRenderDepthAOCB &renderDepthCb, int cascade_no) { if (!worldAODepth || !regions.size()) return; @@ -273,36 +258,38 @@ void DepthAOAboveRenderer::renderAODepthQuads(dag::ConstSpan reg SCOPE_RENDER_TARGET; SCOPE_VIEW_PROJ_MATRIX; const float dimensions = (sceneMinMaxZ.y - sceneMinMaxZ.x); - ShaderGlobal::set_color4(get_shader_variable_id("heightmap_min_max", true), 1.f / dimensions, -sceneMinMaxZ.x / dimensions, - dimensions, 0); + ShaderGlobal::set_color4(heightmap_min_maxVarId, 1.f / dimensions, -sceneMinMaxZ.x / dimensions, dimensions, 0); - renderAODepthQuads(regions, renderDepthCb, worldAODepth.getTex2D(), false); - renderAODepthQuadsTransparent(regions, renderDepthCb); + CascadeDependantData &cascadeData = cascadeDependantData[cascade_no]; + + renderAODepthQuads(regions, renderDepthCb, worldAODepth.getArrayTex(), + (RenderDepthAOType)(RenderDepthAOType::Terrain | RenderDepthAOType::Opaque), RenderDepthAOClearFirst::Yes, cascade_no); + renderAODepthQuadsTransparent(regions, renderDepthCb, RenderDepthAOClearFirst::No, cascade_no); TIME_D3D_PROFILE(depth_blur); Tab blurBoxes(framemem_ptr()); - IPoint2 splitLine = (worldAODepthData.curOrigin - worldAODepthData.mainOrigin) % worldAODepthData.texSize; + IPoint2 splitLine = (cascadeData.worldAODepthData.curOrigin - cascadeData.worldAODepthData.mainOrigin) % texSize; splitLine.y = -splitLine.y; // since we have flipped texture - splitLine = (splitLine + IPoint2(worldAODepthData.texSize, worldAODepthData.texSize)) % worldAODepthData.texSize; + splitLine = (splitLine + IPoint2(texSize, texSize)) % texSize; for (int i = 0; i < regions.size(); ++i) { if (regions[i].reg.wd.x <= 0 || regions[i].reg.wd.y <= 0) continue; const IPoint2 < = regions[i].reg.lt; const IPoint2 &wd = regions[i].reg.wd; - const IPoint2 viewLt(lt.x, worldAODepthData.texSize - lt.y - wd.y); + const IPoint2 viewLt(lt.x, texSize - lt.y - wd.y); const IPoint2 viewRb = viewLt + wd; const int blurKernel = 11; // we have 11x11 gaussian blur const int halfKernel = blurKernel / 2; const IPoint2 fblurLt = IPoint2(viewLt.x - (splitLine.x == viewLt.x ? 0 : halfKernel), viewLt.y - (splitLine.y == viewLt.y ? 0 : halfKernel)); - const IPoint2 fblurRb = IPoint2(viewRb.x + (splitLine.x == ((viewLt.x + wd.x) % worldAODepthData.texSize) ? 0 : halfKernel), - viewRb.y + (splitLine.y == ((viewLt.y + wd.y) % worldAODepthData.texSize) ? 0 : halfKernel)); + const IPoint2 fblurRb = IPoint2(viewRb.x + (splitLine.x == ((viewLt.x + wd.x) % texSize) ? 0 : halfKernel), + viewRb.y + (splitLine.y == ((viewLt.y + wd.y) % texSize) ? 0 : halfKernel)); // if unclamped (blurLt, blurWd) is out of texture, we actually have to render these (wrapped) regions either! // split quads StaticTab blurQuads; - wrap_quads(IBBox2(fblurLt, fblurRb), worldAODepthData.texSize, blurQuads); + wrap_quads(IBBox2(fblurLt, fblurRb), texSize, blurQuads); for (int j = 0; j < blurQuads.size(); ++j) add_non_intersected_box(blurBoxes, IBBox2(blurQuads[j][0], blurQuads[j][1] - IPoint2(1, 1))); // we add inclusive ibbox2, so we // need to substract 1 from right @@ -311,89 +298,100 @@ void DepthAOAboveRenderer::renderAODepthQuads(dag::ConstSpan reg Tab tris(framemem_ptr()); for (int j = 0; j < blurBoxes.size(); ++j) { - Point2 scrLt = mul(Point2::xy(blurBoxes[j][0]) / worldAODepthData.texSize, Point2(2, -2)) - Point2(1, -1); - Point2 scrRb = mul(Point2::xy(blurBoxes[j][1] + IPoint2(1, 1)) / worldAODepthData.texSize, Point2(2, -2)) - Point2(1, -1); + Point2 scrLt = mul(Point2::xy(blurBoxes[j][0]) / texSize, Point2(2, -2)) - Point2(1, -1); + Point2 scrRb = mul(Point2::xy(blurBoxes[j][1] + IPoint2(1, 1)) / texSize, Point2(2, -2)) - Point2(1, -1); Point4 clampTc; - clampTc = Point4((blurBoxes[j][0].x < splitLine.x) ? -1 : (splitLine.x + 0.5) / worldAODepthData.texSize, - (blurBoxes[j][0].x < splitLine.x) ? (splitLine.x - 0.5) / worldAODepthData.texSize : 2, - (blurBoxes[j][0].y < splitLine.y) ? -1 : (splitLine.y + 0.5) / worldAODepthData.texSize, - (blurBoxes[j][0].y < splitLine.y) ? (splitLine.y - 0.5) / worldAODepthData.texSize : 2); + clampTc = Point4((blurBoxes[j][0].x < splitLine.x) ? -1 : (splitLine.x + 0.5) / texSize, + (blurBoxes[j][0].x < splitLine.x) ? (splitLine.x - 0.5) / texSize : 2, + (blurBoxes[j][0].y < splitLine.y) ? -1 : (splitLine.y + 0.5) / texSize, + (blurBoxes[j][0].y < splitLine.y) ? (splitLine.y - 0.5) / texSize : 2); BlurDepthRenderer::Vertex pt[6] = {{scrLt, clampTc}, {Point2(scrRb.x, scrLt.y), clampTc}, {Point2(scrLt.x, scrRb.y), clampTc}, {Point2(scrLt.x, scrRb.y), clampTc}, {Point2(scrRb.x, scrLt.y), clampTc}, {scrRb, clampTc}}; append_items(tris, 6, pt); } - blurDepthRenderer.render(blurredDepth.getTex2D(), worldAODepth.getTexId(), worldAODepthData, tris); + blurDepthRenderer.render(blurredDepth.getArrayTex(), worldAODepth.getTexId(), cascadeData.worldAODepthData, tris, cascade_no); if (renderTransparent) - blurDepthRenderer.render(blurredDepthWithTransparency.getTex2D(), worldAODepthWithTransparency.getTexId(), worldAODepthData, tris); + blurDepthRenderer.render(blurredDepthWithTransparency.getArrayTex(), worldAODepthWithTransparency.getTexId(), + cascadeData.worldAODepthData, tris, cascade_no); } void DepthAOAboveRenderer::prepareRenderRegions(const Point3 &origin, float scene_min_z, float scene_max_z, float splitThreshold) +{ + for (int i = 0; i < cascadeDependantData.size(); ++i) + prepareRenderRegionsForCascade(origin, scene_min_z, scene_max_z, splitThreshold, i); +} + +void DepthAOAboveRenderer::prepareRenderRegionsForCascade(const Point3 &origin, float scene_min_z, float scene_max_z, + float splitThreshold, int cascade_no) { if (!worldAODepth) return; + G_ASSERT(cascade_no < cascadeDependantData.size()); G_ASSERT_RETURN(scene_min_z != scene_max_z, ); sceneMinMaxZ = Point2(scene_min_z, scene_max_z); - regionsToRender.clear(); + CascadeDependantData &cascadeData = cascadeDependantData[cascade_no]; + cascadeData.regionsToRender.clear(); Point2 alignedOrigin = Point2::xz(origin); - const float fullDistance = 2.0f * depthAroundDistance; - float texelSize = (fullDistance / worldAODepthData.texSize); + const float fullDistance = 2.0f * cascadeData.depthAroundDistance; + float texelSize = (fullDistance / texSize); static constexpr int TEXEL_ALIGN = 4; IPoint2 newTexelsOrigin = (ipoint2(floor(alignedOrigin / (texelSize))) + IPoint2(TEXEL_ALIGN / 2, TEXEL_ALIGN / 2)); newTexelsOrigin = newTexelsOrigin - (newTexelsOrigin % TEXEL_ALIGN); static constexpr int THRESHOLD = TEXEL_ALIGN * 4; - IPoint2 move = abs(worldAODepthData.curOrigin - newTexelsOrigin); + IPoint2 move = abs(cascadeData.worldAODepthData.curOrigin - newTexelsOrigin); if (move.x >= THRESHOLD || move.y >= THRESHOLD) { TIME_D3D_PROFILE(depth_above); const float fullUpdateThreshold = 0.45; - const int fullUpdateThresholdTexels = fullUpdateThreshold * worldAODepthData.texSize; + const int fullUpdateThresholdTexels = fullUpdateThreshold * texSize; if (max(move.x, move.y) < fullUpdateThresholdTexels) // if distance travelled is too big, there is no need to update movement in // two steps { if (move.x < move.y) - newTexelsOrigin.x = worldAODepthData.curOrigin.x; + newTexelsOrigin.x = cascadeData.worldAODepthData.curOrigin.x; else - newTexelsOrigin.y = worldAODepthData.curOrigin.y; + newTexelsOrigin.y = cascadeData.worldAODepthData.curOrigin.y; } - bool forcedUpdate = worldAODepthData.curOrigin.x == -1000000 && worldAODepthData.curOrigin.y == 1000000; + bool forcedUpdate = cascadeData.worldAODepthData.curOrigin.x == -1000000 && cascadeData.worldAODepthData.curOrigin.y == 1000000; GatherRegionsCallback cb; - int texelsUpdated = toroidal_update(newTexelsOrigin, worldAODepthData, fullUpdateThresholdTexels, cb); - toroidal_clip_regions(worldAODepthData, invalidAORegions); + int texelsUpdated = toroidal_update(newTexelsOrigin, cascadeData.worldAODepthData, fullUpdateThresholdTexels, cb); + toroidal_clip_regions(cascadeData.worldAODepthData, cascadeData.invalidAORegions); - Point2 ofs = - point2((worldAODepthData.mainOrigin - worldAODepthData.curOrigin) % worldAODepthData.texSize) / worldAODepthData.texSize; - alignedOrigin = point2(worldAODepthData.curOrigin) * texelSize; + Point2 ofs = point2((cascadeData.worldAODepthData.mainOrigin - cascadeData.worldAODepthData.curOrigin) % texSize) / texSize; + alignedOrigin = point2(cascadeData.worldAODepthData.curOrigin) * texelSize; - ShaderGlobal::set_color4(world_to_depth_aoVarId, 1.0f / fullDistance, -1.0f / fullDistance, -alignedOrigin.x / fullDistance + 0.5, + int worldToAoVarId = cascade_no == 0 ? world_to_depth_aoVarId : world_to_depth_ao_extraVarId; + int depthAoHeightsVarId = cascade_no == 0 ? depth_ao_heightsVarId : depth_ao_heights_extraVarId; + ShaderGlobal::set_color4(worldToAoVarId, 1.0f / fullDistance, -1.0f / fullDistance, -alignedOrigin.x / fullDistance + 0.5, alignedOrigin.y / fullDistance + 0.5); - ShaderGlobal::set_color4(depth_ao_heightsVarId, sceneMinMaxZ.y - sceneMinMaxZ.x, sceneMinMaxZ.x, ofs.x, -ofs.y); + ShaderGlobal::set_color4(depthAoHeightsVarId, sceneMinMaxZ.y - sceneMinMaxZ.x, sceneMinMaxZ.x, ofs.x, -ofs.y); - bool bigUpdate = texelsUpdated > worldAODepthData.texSize * worldAODepthData.texSize * splitThreshold; + bool bigUpdate = texelsUpdated > texSize * texSize * splitThreshold; if (splitThreshold != -1.0f && bigUpdate && !forcedUpdate) { for (ToroidalQuadRegion &r : cb.regions) { IBBox2 b{r.texelsFrom, r.texelsFrom + r.wd}; - toroidal_clip_region(worldAODepthData, b); - add_non_intersected_box(invalidAORegions, b); + toroidal_clip_region(cascadeData.worldAODepthData, b); + add_non_intersected_box(cascadeData.invalidAORegions, b); } } else { for (ToroidalQuadRegion &r : cb.regions) - regionsToRender.emplace_back(r); + cascadeData.regionsToRender.emplace_back(r); } } - if (regionsToRender.empty()) + if (cascadeData.regionsToRender.empty()) { - int id = get_closest_region_and_split(worldAODepthData, invalidAORegions); + int id = get_closest_region_and_split(cascadeData.worldAODepthData, cascadeData.invalidAORegions); if (id >= 0) { // split region if it is too big, along it's longest axis @@ -402,31 +400,31 @@ void DepthAOAboveRenderer::prepareRenderRegions(const Point3 &origin, float scen if (splitThreshold != -1.0f) { - int desiredSide = sqrtf(worldAODepthData.texSize * worldAODepthData.texSize * splitThreshold); - rest += - split_region_to_size_linear(desiredSide, invalidAORegions[id], invalidAORegions[id], restRegion, worldAODepthData.curOrigin); - rest += split_region_to_size_linear(desiredSide, invalidAORegions[id], invalidAORegions[id], &restRegion[rest], - worldAODepthData.curOrigin); + int desiredSide = sqrtf(texSize * texSize * splitThreshold); + rest += split_region_to_size_linear(desiredSide, cascadeData.invalidAORegions[id], cascadeData.invalidAORegions[id], + restRegion, cascadeData.worldAODepthData.curOrigin); + rest += split_region_to_size_linear(desiredSide, cascadeData.invalidAORegions[id], cascadeData.invalidAORegions[id], + &restRegion[rest], cascadeData.worldAODepthData.curOrigin); } else { - rest += split_region_to_size(THRESHOLD * worldAODepthData.texSize, invalidAORegions[id], invalidAORegions[id], restRegion, - worldAODepthData.curOrigin); + rest += split_region_to_size(THRESHOLD * texSize, cascadeData.invalidAORegions[id], cascadeData.invalidAORegions[id], + restRegion, cascadeData.worldAODepthData.curOrigin); } if (rest) - append_items(invalidAORegions, rest, restRegion); + append_items(cascadeData.invalidAORegions, rest, restRegion); // finally, update chosen invalid region. - ToroidalQuadRegion quad(transform_point_to_viewport(invalidAORegions[id][0], worldAODepthData), - invalidAORegions[id].width() + IPoint2(1, 1), invalidAORegions[id][0]); - regionsToRender.emplace_back(quad); + ToroidalQuadRegion quad(transform_point_to_viewport(cascadeData.invalidAORegions[id][0], cascadeData.worldAODepthData), + cascadeData.invalidAORegions[id].width() + IPoint2(1, 1), cascadeData.invalidAORegions[id][0]); + cascadeData.regionsToRender.emplace_back(quad); // and remove it from update list - erase_items(invalidAORegions, id, 1); + erase_items(cascadeData.invalidAORegions, id, 1); } } - if (regionsToRender.empty()) + if (cascadeData.regionsToRender.empty()) return; // prepare matrices @@ -438,13 +436,13 @@ void DepthAOAboveRenderer::prepareRenderRegions(const Point3 &origin, float scen vtm.setcol(2, 0, 1, 0); d3d::settm(TM_VIEW, vtm); - for (RegionToRender &i : regionsToRender) + for (RegionToRender &i : cascadeData.regionsToRender) { if (i.reg.wd.x <= 0 || i.reg.wd.y <= 0) continue; const IPoint2 < = i.reg.lt; const IPoint2 &wd = i.reg.wd; - const IPoint2 viewLt(lt.x, worldAODepthData.texSize - lt.y - wd.y); + const IPoint2 viewLt(lt.x, texSize - lt.y - wd.y); const IPoint2 &texelsFrom = i.reg.texelsFrom; BBox2 region(point2(texelsFrom) * texelSize, point2(texelsFrom + wd) * texelSize); @@ -455,47 +453,55 @@ void DepthAOAboveRenderer::prepareRenderRegions(const Point3 &origin, float scen } } -void DepthAOAboveRenderer::prepareAO(const Point3 &origin, IRenderDepthAOCB &renderDepthCb) +void DepthAOAboveRenderer::renderPreparedRegions(IRenderDepthAOCB &renderDepthCb) { - renderDepthCb.getMinMaxZ(sceneMinMaxZ.x, sceneMinMaxZ.y); - prepareRenderRegions(origin, sceneMinMaxZ.x, sceneMinMaxZ.y); - renderAODepthQuads(regionsToRender, renderDepthCb); + for (int i = 0; i < cascadeDependantData.size(); ++i) + renderAODepthQuads(cascadeDependantData[i].regionsToRender, renderDepthCb, i); } -void DepthAOAboveRenderer::renderPreparedRegions(IRenderDepthAOCB &renderDepthCb) +void DepthAOAboveRenderer::renderPreparedRegionsForCascade(IRenderDepthAOCB &renderDepthCb, int cascade_no) { - renderAODepthQuads(regionsToRender, renderDepthCb); + G_ASSERT(cascade_no < cascadeDependantData.size()); + renderAODepthQuads(cascadeDependantData[cascade_no].regionsToRender, renderDepthCb, cascade_no); } void DepthAOAboveRenderer::invalidateAO(bool force) { - invalidAORegions.clear(); - if (!force) + for (auto &cascade : cascadeDependantData) { - invalidAORegions.push_back(get_texture_box(worldAODepthData)); - return; + cascade.invalidAORegions.clear(); + if (!force) + { + cascade.invalidAORegions.push_back(get_texture_box(cascade.worldAODepthData)); + return; + } + // forced update! + cascade.worldAODepthData.curOrigin = IPoint2(-1000000, 1000000); } - // forced update! - worldAODepthData.curOrigin = IPoint2(-1000000, 1000000); } void DepthAOAboveRenderer::invalidateAO(const BBox3 &box) { - const float fullDistance = 2.f * depthAroundDistance; - const float texelSize = (fullDistance / worldAODepthData.texSize); - IBBox2 ibox(ipoint2(floor(Point2::xz(box[0]) / texelSize)), ipoint2(ceil(Point2::xz(box[1]) / texelSize))); - - toroidal_clip_region(worldAODepthData, ibox); - if (ibox.isEmpty()) - return; - add_non_intersected_box(invalidAORegions, ibox); + for (auto &cascade : cascadeDependantData) + { + const float fullDistance = 2.f * cascade.depthAroundDistance; + const float texelSize = (fullDistance / texSize); + IBBox2 ibox(ipoint2(floor(Point2::xz(box[0]) / texelSize)), ipoint2(ceil(Point2::xz(box[1]) / texelSize))); + + toroidal_clip_region(cascade.worldAODepthData, ibox); + if (ibox.isEmpty()) + return; + add_non_intersected_box(cascade.invalidAORegions, ibox); + } } void DepthAOAboveRenderer::setDistanceAround(const float distance_around) { - if (depthAroundDistance == distance_around) + if (cascadeDependantData[0].depthAroundDistance == distance_around) return; - depthAroundDistance = distance_around; + + for (int i = 0; i < cascadeDependantData.size(); ++i) + cascadeDependantData[i].depthAroundDistance = i == 0 ? distance_around : distance_around * extraCascadeMult; invalidateAO(true); } @@ -518,9 +524,9 @@ void DepthAOAboveRenderer::setVars() } else { - ShaderGlobal::set_texture(depth_above_transparentVarId, worldAODepth); + ShaderGlobal::set_texture(depth_around_transparentVarId, worldAODepth); ShaderGlobal::set_texture(blurred_depth_transparentVarId, blurredDepth); } - ShaderGlobal::set_real(depth_ao_texture_sizeVarId, worldAODepthData.texSize); - ShaderGlobal::set_real(depth_ao_texture_rcp_sizeVarId, 1.0f / worldAODepthData.texSize); + ShaderGlobal::set_real(depth_ao_texture_sizeVarId, texSize); + ShaderGlobal::set_real(depth_ao_texture_rcp_sizeVarId, 1.0f / texSize); } \ No newline at end of file diff --git a/prog/gameLibs/render/fluidDynamics/shaders/cfd_inc.dshl b/prog/gameLibs/render/fluidDynamics/shaders/cfd_inc.dshl new file mode 100644 index 000000000..ffcae9af7 --- /dev/null +++ b/prog/gameLibs/render/fluidDynamics/shaders/cfd_inc.dshl @@ -0,0 +1,27 @@ +float4 cfd_world_to_voxel; +float4 cfd_world_to_voxel_height; +texture cfd_voxel_tex; + +macro INIT_CFD_CONSTS(code) + (code) { + cfd_world_to_voxel@f4 = cfd_world_to_voxel; + cfd_world_to_voxel_height@f2 = (cfd_world_to_voxel_height.x, cfd_world_to_voxel_height.y, 0, 0); + } +endmacro + +macro INIT_CFD(code) + (code) {cfd_voxel_tex@smp2d = cfd_voxel_tex;} + INIT_CFD_CONSTS(code) +endmacro + +macro USE_CFD_TC(code) + hlsl(code) { + float3 get_cfd_voxel_tc(float3 worldPos) + { + float3 tc; + tc.xy = saturate((worldPos.xz - cfd_world_to_voxel.zw) * cfd_world_to_voxel.xy); + tc.z = saturate((worldPos.y - cfd_world_to_voxel_height.y) * cfd_world_to_voxel_height.x); + return tc; + } + } +endmacro \ No newline at end of file diff --git a/prog/gameLibs/render/fluidDynamics/shaders/euler_solver.sh b/prog/gameLibs/render/fluidDynamics/shaders/euler_solver.dshl similarity index 87% rename from prog/gameLibs/render/fluidDynamics/shaders/euler_solver.sh rename to prog/gameLibs/render/fluidDynamics/shaders/euler_solver.dshl index 377c63181..222e61c5d 100644 --- a/prog/gameLibs/render/fluidDynamics/shaders/euler_solver.sh +++ b/prog/gameLibs/render/fluidDynamics/shaders/euler_solver.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" +include "shader_global.dshl" texture velocity_density_tex; texture next_velocity_density_tex; @@ -26,9 +26,6 @@ hlsl { return rho * R * T / M; } - #define x_ofs uint2(1, 0) - #define y_ofs uint2(0, 1) - struct ValueCross { float left; @@ -62,26 +59,24 @@ shader fill_initial_conditions (cs) { velocity_density@uav = velocity_density_tex hlsl { - RWTexture2D velocity_density@uav; + RWTexture3D velocity_density@uav; }; standard_density@f1 = (standard_density, 0, 0, 0); standard_velocity@f2 = (standard_velocity.x, standard_velocity.y, 0, 0); - texSize@i2 = (tex_size.x, tex_size.y, 0, 0); + texSize@i3 = (tex_size.x, tex_size.y, tex_size.z, 0); } hlsl(cs) { [numthreads(8, 8, 1)] void cs_main(uint3 tid : SV_DispatchThreadID) { - uint2 size = texSize; - if (tid.x >= size.x || tid.y >= size.y) + uint3 size = texSize; + if (tid.x >= size.x || tid.y >= size.y || tid.z >= size.z) return; - uint2 coord = uint2(tid.x, tid.y); - - velocity_density[coord] = float4(standard_velocity, 0, standard_density); + velocity_density[tid] = float4(standard_velocity, 0, standard_density); } } @@ -94,25 +89,23 @@ shader fill_initial_conditions_from_tex (cs) { velocity_density@uav = velocity_density_tex hlsl { - RWTexture2D velocity_density@uav; + RWTexture3D velocity_density@uav; }; - initial_velocity_density@smp2d = initial_velocity_density_tex; + initial_velocity_density@smp3d = initial_velocity_density_tex; - texSize@i2 = (tex_size.x, tex_size.y, 0, 0); + texSize@i3 = (tex_size.x, tex_size.y, tex_size.z, 0); } hlsl(cs) { [numthreads(8, 8, 1)] void cs_main(uint3 tid : SV_DispatchThreadID) { - uint2 size = texSize; - if (tid.x >= size.x || tid.y >= size.y) + uint3 size = texSize; + if (tid.x >= size.x || tid.y >= size.y || tid.z >= size.z) return; - uint2 coord = uint2(tid.x, tid.y); - - velocity_density[coord] = tex2Dlod(initial_velocity_density, float4(float2(coord) / float2(size), 0, 0)); + velocity_density[tid] = tex3Dlod(initial_velocity_density, float4(float3(tid) / float3(size), 0)); } } @@ -124,27 +117,27 @@ shader euler_simulation_cs ENABLE_ASSERT(cs) (cs) { - tex_size@i2 = (tex_size.x, tex_size.y, 0, 0); + tex_size@i3 = (tex_size.x, tex_size.y, tex_size.z, 0); - simulation_time@f1 = (simulation_time, 0, 0, 0); dt@f1 = (simulation_dt, 0, 0, 0); h@f1 = (simulation_dx, 0, 0, 0); standard_density@f1 = (standard_density, 0, 0, 0); standard_velocity@f2 = (standard_velocity.x, standard_velocity.y, 0, 0); - velocity_density@smp2d = velocity_density_tex; - next_velocity_density@uav = next_velocity_density_tex hlsl { - RWTexture2D next_velocity_density@uav; - }; - - solidBoundaries@smp2d = solid_boundaries_tex; + solid_boundaries@smp3d = solid_boundaries_tex; } hlsl(cs) { - float2 frictionForce(uint2 coord, float2 v) + #define x_ofs uint3(1, 0, 0) + #define y_ofs uint3(0, 1, 0) + + Texture3D velocity_density : register(t1); + RWTexture3D next_velocity_density : register(u0); + + float2 frictionForce(uint3 coord, float2 v) { - float boundaryData = tex2Dlod(solidBoundaries, float4(float2(coord) / float2(tex_size), 0, 0)).w; + float boundaryData = tex3Dlod(solid_boundaries, float4(float3(coord) / float3(tex_size), 0)).x; if (boundaryData > 0) return -v * 10000.0; @@ -152,7 +145,7 @@ shader euler_simulation_cs return 0; } - void solver(uint2 coord, float t) + void solver(uint3 coord) { float4 nextVelDensity = 0; @@ -216,10 +209,10 @@ shader euler_simulation_cs [numthreads(8, 8, 1)] void cs_main(uint3 tid : SV_DispatchThreadID) { - if (tid.x >= tex_size.x || tid.y >= tex_size.y) + if (tid.x >= tex_size.x || tid.y >= tex_size.y || tid.z >= tex_size.z) return; - solver(tid.xy, simulation_time); + solver(tid); } } compile("cs_5_0", "cs_main") @@ -250,10 +243,12 @@ shader euler_simulation_explicit_implicit_cs RWTexture2D next_velocity_density@uav; }; - solidBoundaries@smp2d = solid_boundaries_tex; + solid_boundaries@smp2d = solid_boundaries_tex; } hlsl(cs) { + #define x_ofs uint2(1, 0) + #define y_ofs uint2(0, 1) //#define ROW_SIZE 512 #define ROW_SIZE 64 @@ -264,7 +259,7 @@ shader euler_simulation_explicit_implicit_cs float2 frictionForce(uint2 coord, float2 v) { - float boundaryData = tex2Dlod(solidBoundaries, float4(float2(coord) / float2(tex_size), 0, 0)).w; + float boundaryData = tex2Dlod(solid_boundaries, float4(float2(coord) / float2(tex_size), 0, 0)).w; if (boundaryData > 0) return -v * 10000.0; @@ -423,20 +418,22 @@ shader blur_result_cs ENABLE_ASSERT(cs) (cs) { - tex_size@i2 = (tex_size.x, tex_size.y, 0, 0); + tex_size@i3 = (tex_size.x, tex_size.y, tex_size.z, 0); simulation_time@f1 = (simulation_time, 0, 0, 0) blurWeights@f2 = (euler_centralBlurWeight, 1.0/(euler_centralBlurWeight + 4.0), 0, 0); - velocity_density@smp2d = velocity_density_tex; - next_velocity_density@uav = next_velocity_density_tex hlsl { - RWTexture2D next_velocity_density@uav; - }; standard_density@f1 = (standard_density, 0, 0, 0); standard_velocity@f2 = (standard_velocity.x, standard_velocity.y, 0, 0); } hlsl(cs) { - void blurer(int2 coord, float t) + #define x_ofs uint3(1, 0, 0) + #define y_ofs uint3(0, 1, 0) + + Texture3D velocity_density : register(t1); + RWTexture3D next_velocity_density : register(u0); + + void blurer(int3 coord, float t) { float4 blurredVelDensity = 0; @@ -467,10 +464,10 @@ shader blur_result_cs [numthreads(8, 8, 1)] void cs_main(uint3 tid : SV_DispatchThreadID) { - if (tid.x >= tex_size.x || tid.y >= tex_size.y) + if (tid.x >= tex_size.x || tid.y >= tex_size.y || tid.z >= tex_size.z) return; - blurer(tid.xy, simulation_time); + blurer(tid, simulation_time); } } compile("cs_5_0", "cs_main") diff --git a/prog/gameLibs/render/fluidDynamics/shaders/show_solution.sh b/prog/gameLibs/render/fluidDynamics/shaders/show_cfd_solution.dshl similarity index 81% rename from prog/gameLibs/render/fluidDynamics/shaders/show_solution.sh rename to prog/gameLibs/render/fluidDynamics/shaders/show_cfd_solution.dshl index 444b60044..f59beabf4 100644 --- a/prog/gameLibs/render/fluidDynamics/shaders/show_solution.sh +++ b/prog/gameLibs/render/fluidDynamics/shaders/show_cfd_solution.dshl @@ -1,8 +1,9 @@ -include "shader_global.sh" -include "postfx_inc.sh" +include "shader_global.dshl" +include "postfx_inc.dshl" -texture plot_tex; -int plot_type = 0; +texture cfd_plot_tex; +int cfd_plot_type = 0; +float cfd_depth_tc = 0; shader show_cfd_solution { @@ -15,8 +16,9 @@ shader show_cfd_solution POSTFX_VS_TEXCOORD(0, texcoord) (ps) { - plot_tex@smp2d = plot_tex; - plot_type@i1 = plot_type; + plot_tex@smp3d = cfd_plot_tex; + plot_type@i1 = cfd_plot_type; + depth_tc@f1 = cfd_depth_tc; } hlsl(ps) { @@ -30,7 +32,7 @@ shader show_cfd_solution float4 show_solution_ps(VsOutput input) : SV_Target { - float4 val = tex2Dlod(plot_tex, float4(input.texcoord.xy,0,0)); + float4 val = tex3Dlod(plot_tex, float4(input.texcoord.xy, depth_tc, 0)); if (plot_type == 0) // DENSITY { float density = val.w; diff --git a/prog/gameLibs/render/fluidDynamics/shaders/voxelize_depth_above.dshl b/prog/gameLibs/render/fluidDynamics/shaders/voxelize_depth_above.dshl new file mode 100644 index 000000000..6d80fb84b --- /dev/null +++ b/prog/gameLibs/render/fluidDynamics/shaders/voxelize_depth_above.dshl @@ -0,0 +1,53 @@ +include "shader_global.dshl" +include "depth_above.dshl" +include "cfd_inc.dshl" + +int4 cfd_voxel_tex_size; +float4 cfd_voxel_size; +float4 cfd_world_box_min; + +shader voxelize_depth_above +{ + ENABLE_ASSERT(cs) + INIT_DEPTH_ABOVE(cs, blurred_depth) + USE_DEPTH_ABOVE_TC(cs) + + (cs) { + depth_above@smpArray = depth_around; + voxel_tex@uav = cfd_voxel_tex hlsl { + RWTexture3D voxel_tex@uav; + }; + tex_size@i3 = (cfd_voxel_tex_size.x, cfd_voxel_tex_size.y, cfd_voxel_tex_size.z); + voxel_size@f3 = cfd_voxel_size; + world_box_min@f3 = cfd_world_box_min; + } + + hlsl(cs) { + float3 get_voxel_corner_in_world(uint3 id) + { + return world_box_min + id.xzy * voxel_size; + } + } + + hlsl(cs) { + [numthreads(8, 8, 1)] + void cs_main(uint3 tid : SV_DispatchThreadID) + { + if (tid.x >= tex_size.x || tid.y >= tex_size.y || tid.z >= tex_size.z) + return; + + float3 voxelCorner = get_voxel_corner_in_world(tid); + float3 voxelCenter = voxelCorner + voxel_size * 0.5f; + float2 depthAboveTc = saturate(world_to_depth_ao_extra.xy * voxelCenter.xz + world_to_depth_ao_extra.zw) - depth_ao_heights_extra.zw; + + // tc.z is 1 because we use the bigger cascade always + float height = decode_depth_above(tex3Dlod(depth_above, float4(depthAboveTc, 1, 0)).x); + + if (height > voxelCenter.y) + voxel_tex[tid] = 1; + else + voxel_tex[tid] = 0; + } + } + compile("cs_5_0", "cs_main") +} \ No newline at end of file diff --git a/prog/gameLibs/render/fluidDynamics/shaders/voxelize_depth_above.sh b/prog/gameLibs/render/fluidDynamics/shaders/voxelize_depth_above.sh deleted file mode 100644 index 70bf763a1..000000000 --- a/prog/gameLibs/render/fluidDynamics/shaders/voxelize_depth_above.sh +++ /dev/null @@ -1,53 +0,0 @@ -include "shader_global.sh" -include "depth_above.sh" - -texture cfd_voxel_tex; -int4 cfd_voxel_tex_size; -float4 cfd_voxel_size; -float4 world_box_corner; - -shader voxelize_depth_above -{ - ENABLE_ASSERT(cs) - INIT_DEPTH_ABOVE(cs, blurred_depth) - USE_DEPTH_ABOVE_TC(cs) - - (cs) { - depth_above@smp2d = depth_around; - voxel_tex@uav = cfd_voxel_tex hlsl { - RWTexture3D voxel_tex@uav; - }; - tex_size@i3 = (cfd_voxel_tex_size.x, cfd_voxel_tex_size.y, cfd_voxel_tex_size.z); - voxel_size@f3 = cfd_voxel_size; - world_box_corner@f3 = world_box_corner; - } - - hlsl(cs) { - float3 getVoxelCornerInWorld(uint3 id) - { - return world_box_corner + id.xzy * voxel_size; - } - } - - hlsl(cs) { - [numthreads(8, 8, 1)] - void cs_main(uint3 tid : SV_DispatchThreadID) - { - if (tid.x >= tex_size.x || tid.y >= tex_size.y || tid.z >= tex_size.z) - return; - - float3 voxelCorner = getVoxelCornerInWorld(tid); - float3 voxelCenter = voxelCorner + voxel_size * 0.5f; - float2 depthAboveTc = saturate(world_to_depth_ao.xy * voxelCenter.xz + world_to_depth_ao.zw) - depth_ao_heights.zw; - - float height = decode_depth_above(tex2Dlod(depth_above, float4(depthAboveTc,0,0) ).x); - - - if (height > voxelCenter.y) - voxel_tex[tid] = 1u; - else - voxel_tex[tid] = 0u; - } - } - compile("cs_5_0", "cs_main") -} \ No newline at end of file diff --git a/prog/gameLibs/render/fluidDynamics/solver.cpp b/prog/gameLibs/render/fluidDynamics/solver.cpp index 0a7781ace..6ca931c4f 100644 --- a/prog/gameLibs/render/fluidDynamics/solver.cpp +++ b/prog/gameLibs/render/fluidDynamics/solver.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace cfd { @@ -60,7 +61,7 @@ void Solver::fillInitialConditions(float standard_density, const Point2 &standar void Solver::solveEquations(float dt, int num_dispatches) { - TIME_D3D_PROFILE("cfd::solveEquations"); + TIME_D3D_PROFILE("cfd_solveEquations"); int currentIdx = 0; int currentImplicit = 0; @@ -106,12 +107,12 @@ float Solver::getSimulationTime() const { return simulationTime; } // CascadeSolver -// TODO: account for different number of cascades static constexpr float cascadeDtMultipliers[4] = {2.0f, 2.0f, 1.5f, 1.0f}; +static constexpr float cascadeDispatchNumMultipliers[4] = {1.0f, 0.5f, 0.125f, 0.03125f}; -CascadeSolver::CascadeSolver(const char *solver_shader_name, uint32_t tex_width, uint32_t tex_height, - const eastl::array &num_dispatches_per_cascade, float spatial_step) : - numDispatchesPerCascade(eastl::move(num_dispatches_per_cascade)) +CascadeSolver::CascadeSolver(const char *solver_shader_name, IPoint3 tex_size, float spatial_step, const char *solver_name, + const eastl::array &num_dispatches_per_cascade) : + numDispatchesPerCascade(eastl::move(num_dispatches_per_cascade)), textureDepth(tex_size.z) { #define VAR(a) a##VarId = get_shader_variable_id(#a, true); VARS_LIST @@ -125,18 +126,24 @@ CascadeSolver::CascadeSolver(const char *solver_shader_name, uint32_t tex_width, for (int i = 0; i < NUM_CASCADES; ++i) { - auto &newCascade = cascades.push_back(); - newCascade.texSize = IPoint2(tex_width / (1 << (NUM_CASCADES - 1 - i)), tex_height / (1 << (NUM_CASCADES - 1 - i))); + Cascade &newCascade = cascades[i]; + newCascade.texSize = IPoint2(tex_size.x / (1 << (NUM_CASCADES - 1 - i)), tex_size.y / (1 << (NUM_CASCADES - 1 - i))); newCascade.spatialStep = spatial_step * (1 << (NUM_CASCADES - 1 - i)); newCascade.dtMultiplier = cascadeDtMultipliers[i]; - newCascade.velDensityTex[0] = dag::create_tex(NULL, newCascade.texSize.x, newCascade.texSize.y, - TEXFMT_A32B32G32R32F | TEXCF_UNORDERED, 1, String(0, "velocity_pressure_cascade_%d", i)); - newCascade.velDensityTex[1] = dag::create_tex(NULL, newCascade.texSize.x, newCascade.texSize.y, - TEXFMT_A32B32G32R32F | TEXCF_UNORDERED, 1, String(0, "next_velocity_pressure_cascade_%d", i)); + newCascade.velDensityTex[0] = dag::create_voltex(newCascade.texSize.x, newCascade.texSize.y, tex_size.z, + TEXFMT_A32B32G32R32F | TEXCF_UNORDERED, 1, String(0, "velocity_density_cascade_%d_%s", i, solver_name)); + newCascade.velDensityTex[1] = dag::create_voltex(newCascade.texSize.x, newCascade.texSize.y, tex_size.z, + TEXFMT_A32B32G32R32F | TEXCF_UNORDERED, 1, String(0, "next_velocity_density_cascade_%d_%s", i, solver_name)); + + d3d::resource_barrier({cascades[i].velDensityTex[0].getBaseTex(), RB_STAGE_COMPUTE | RB_RW_UAV, 0, 0}); + d3d::resource_barrier({cascades[i].velDensityTex[1].getBaseTex(), RB_STAGE_COMPUTE | RB_RW_UAV, 0, 0}); + + newCascade.velDensityTex[0].getVolTex()->texfilter(TEXFILTER_POINT); + newCascade.velDensityTex[1].getVolTex()->texfilter(TEXFILTER_POINT); // Mirror for ghost cells on the edges - newCascade.velDensityTex[0].getTex2D()->texaddr(TEXADDR_MIRROR); - newCascade.velDensityTex[1].getTex2D()->texaddr(TEXADDR_MIRROR); + newCascade.velDensityTex[0].getVolTex()->texaddr(TEXADDR_MIRROR); + newCascade.velDensityTex[1].getVolTex()->texaddr(TEXADDR_MIRROR); } } @@ -144,51 +151,88 @@ void CascadeSolver::fillInitialConditions(float standard_density, const Point2 & { switchToCascade(0); - ShaderGlobal::set_real(standard_densityVarId, standard_density); - ShaderGlobal::set_color4(standard_velocityVarId, Color4(standard_velocity.x, standard_velocity.y, 0.0f, 0.0f)); + standardDensity = standard_density; + standardVelocity = standard_velocity; - initialConditionsCs->dispatchThreads(cascades[currentCascade].texSize.x, cascades[currentCascade].texSize.y, 1); + ShaderGlobal::set_real(standard_densityVarId, standardDensity); + ShaderGlobal::set_color4(standard_velocityVarId, Color4(standardVelocity.x, standardVelocity.y, 0.0f, 0.0f)); + + initialConditionsCs->dispatchThreads(cascades[currentCascade].texSize.x, cascades[currentCascade].texSize.y, textureDepth); + d3d::resource_barrier({cascades[currentCascade].velDensityTex[0].getBaseTex(), RB_STAGE_COMPUTE | RB_RO_SRV, 0, 0}); } -void CascadeSolver::solveEquations(float dt, int num_dispatches) +bool CascadeSolver::solveEquations(float dt, int base_num_dispatches) { - TIME_D3D_PROFILE("cfd::solveEquationsCascade"); - - if (curNumDispatches > numDispatchesPerCascade[currentCascade]) - return; + TIME_D3D_PROFILE("cfd_solveEquationsCascade"); - const float actualDt = dt * cascades[currentCascade].dtMultiplier; - int currentIdx = 0; - int currentImplicit = 0; - ShaderGlobal::set_real(simulation_dtVarId, actualDt); - for (int i = 0; i < num_dispatches; ++i) - { - ShaderGlobal::set_texture(velocity_density_texVarId, cascades[currentCascade].velDensityTex[currentIdx]); - ShaderGlobal::set_texture(next_velocity_density_texVarId, cascades[currentCascade].velDensityTex[1 - currentIdx]); - - solverCs->dispatchThreads(cascades[currentCascade].texSize.x, cascades[currentCascade].texSize.y, 1); - - simulationTime += actualDt; - currentIdx = (currentIdx + 1) % 2; - currentImplicit = (currentImplicit + 1) % 2; - - ShaderGlobal::set_texture(velocity_density_texVarId, cascades[currentCascade].velDensityTex[currentIdx]); - ShaderGlobal::set_texture(next_velocity_density_texVarId, cascades[currentCascade].velDensityTex[1 - currentIdx]); + if (curNumDispatches >= numDispatchesPerCascade[currentCascade]) + return false; - blurCs->dispatchThreads(cascades[currentCascade].texSize.x, cascades[currentCascade].texSize.y, 1); + int i = 0; + const int actualNumDispatches = static_cast(base_num_dispatches * cascadeDispatchNumMultipliers[currentCascade]); - currentIdx = (currentIdx + 1) % 2; - } + ShaderGlobal::set_real(standard_densityVarId, standardDensity); + ShaderGlobal::set_color4(standard_velocityVarId, Color4(standardVelocity.x, standardVelocity.y, 0.0f, 0.0f)); - curNumDispatches += num_dispatches; - totalNumDispatches += num_dispatches; - if (curNumDispatches >= numDispatchesPerCascade[currentCascade]) + while (i < actualNumDispatches) { - if (currentCascade != NUM_CASCADES - 1) - switchToCascade(currentCascade + 1); - else - return; + const float actualDt = dt * cascades[currentCascade].dtMultiplier; + + ShaderGlobal::set_real(simulation_dtVarId, actualDt); + ShaderGlobal::set_int4(tex_sizeVarId, + IPoint4(cascades[currentCascade].texSize.x, cascades[currentCascade].texSize.y, textureDepth, 0)); + ShaderGlobal::set_real(simulation_dxVarId, cascades[currentCascade].spatialStep); + + int currentIdx = 0; + int currentImplicit = 0; + + solverCs->setStates(); + blurCs->setStates(); + for (; i < actualNumDispatches && curNumDispatches < numDispatchesPerCascade[currentCascade]; ++i) + { + d3d::set_tex(STAGE_CS, 1, cascades[currentCascade].velDensityTex[currentIdx].getBaseTex()); + d3d::set_rwtex(STAGE_CS, 0, cascades[currentCascade].velDensityTex[1 - currentIdx].getBaseTex(), 0, 0); + + solverCs->dispatchThreads(cascades[currentCascade].texSize.x, cascades[currentCascade].texSize.y, textureDepth, + GpuPipeline::GRAPHICS, false); + d3d::resource_barrier({cascades[currentCascade].velDensityTex[currentIdx].getBaseTex(), RB_STAGE_COMPUTE | RB_RW_UAV, 0, 0}); + d3d::resource_barrier({cascades[currentCascade].velDensityTex[1 - currentIdx].getBaseTex(), RB_STAGE_COMPUTE | RB_RO_SRV, 0, 0}); + + simulationTime += actualDt; + currentIdx = (currentIdx + 1) % 2; + currentImplicit = (currentImplicit + 1) % 2; + + d3d::set_tex(STAGE_CS, 1, cascades[currentCascade].velDensityTex[currentIdx].getBaseTex()); + d3d::set_rwtex(STAGE_CS, 0, cascades[currentCascade].velDensityTex[1 - currentIdx].getBaseTex(), 0, 0); + + blurCs->dispatchThreads(cascades[currentCascade].texSize.x, cascades[currentCascade].texSize.y, textureDepth, + GpuPipeline::GRAPHICS, false); + d3d::resource_barrier({cascades[currentCascade].velDensityTex[currentIdx].getBaseTex(), RB_STAGE_COMPUTE | RB_RW_UAV, 0, 0}); + d3d::resource_barrier({cascades[currentCascade].velDensityTex[1 - currentIdx].getBaseTex(), RB_STAGE_COMPUTE | RB_RO_SRV, 0, 0}); + + currentIdx = (currentIdx + 1) % 2; + + ++curNumDispatches; + ++totalNumDispatches; + } + + d3d::set_tex(STAGE_CS, 1, nullptr); + d3d::set_rwtex(STAGE_CS, 0, nullptr, 0, 0); + + if (curNumDispatches >= numDispatchesPerCascade[currentCascade]) + { + d3d::resource_barrier( + {cascades[currentCascade].velDensityTex[0].getBaseTex(), RB_STAGE_COMPUTE | RB_STAGE_PIXEL | RB_RO_SRV, 0, 0}); + if (currentCascade != NUM_CASCADES - 1) + switchToCascade(currentCascade + 1); + else + { + resultReady = true; + return true; + } + } } + return true; } void CascadeSolver::showResult(PlotType plot_type) @@ -198,6 +242,17 @@ void CascadeSolver::showResult(PlotType plot_type) showSolution.render(); } +void CascadeSolver::reset() +{ + curNumDispatches = 0; + totalNumDispatches = 0; + simulationTime = 0.0f; + currentCascade = 0; + resultReady = false; +} + +bool CascadeSolver::isResultReady() const { return resultReady; } + TEXTUREID CascadeSolver::getVelocityDensityTexId() const { return cascades[currentCascade].velDensityTex[0].getTexId(); } float CascadeSolver::getSimulationTime() const { return simulationTime; } @@ -208,10 +263,11 @@ void CascadeSolver::switchToCascade(int cascade) { ShaderGlobal::set_texture(velocity_density_texVarId, cascades[cascade].velDensityTex[0]); ShaderGlobal::set_texture(next_velocity_density_texVarId, cascades[cascade].velDensityTex[1]); - ShaderGlobal::set_int4(tex_sizeVarId, IPoint4(cascades[cascade].texSize.x, cascades[cascade].texSize.y, 0, 0)); + ShaderGlobal::set_int4(tex_sizeVarId, IPoint4(cascades[cascade].texSize.x, cascades[cascade].texSize.y, textureDepth, 0)); ShaderGlobal::set_real(simulation_dxVarId, cascades[cascade].spatialStep); - fillNextCascadeInitialConditions(); + if (cascade != 0) + fillNextCascadeInitialConditions(); curNumDispatches = 0; currentCascade = cascade; @@ -221,7 +277,9 @@ void CascadeSolver::fillNextCascadeInitialConditions() { ShaderGlobal::set_texture(initial_velocity_density_texVarId, cascades[currentCascade].velDensityTex[0]); - initialConditionsFromTexCs->dispatchThreads(cascades[currentCascade + 1].texSize.x, cascades[currentCascade + 1].texSize.y, 1); + initialConditionsFromTexCs->dispatchThreads(cascades[currentCascade + 1].texSize.x, cascades[currentCascade + 1].texSize.y, + textureDepth); + d3d::resource_barrier({cascades[currentCascade + 1].velDensityTex[0].getBaseTex(), RB_STAGE_COMPUTE | RB_RO_SRV, 0, 0}); } } // namespace cfd diff --git a/prog/gameLibs/render/fluidDynamics/voxelizeDepthAbove.cpp b/prog/gameLibs/render/fluidDynamics/voxelizeDepthAbove.cpp index 5709c2750..2d8e1d345 100644 --- a/prog/gameLibs/render/fluidDynamics/voxelizeDepthAbove.cpp +++ b/prog/gameLibs/render/fluidDynamics/voxelizeDepthAbove.cpp @@ -1,25 +1,70 @@ #include +#include namespace cfd { -Voxelizer::Voxelizer(IPoint3 vol_tex_size) : volTexSize(vol_tex_size), worldBoxSize(vol_tex_size.x, vol_tex_size.z, vol_tex_size.y) +#define VARS_LIST \ + VAR(cfd_voxel_tex_size) \ + VAR(cfd_voxel_size) \ + VAR(cfd_world_box_min) \ + VAR(cfd_world_to_voxel) \ + VAR(cfd_world_to_voxel_height) + +#define VAR(a) static int a##VarId = -1; +VARS_LIST +#undef VAR + +Voxelizer::Voxelizer(Point3 world_box_size, float meters_per_voxel_xz, float meters_per_voxel_y) : + voxelTexSize( + IPoint3(world_box_size.x / meters_per_voxel_xz, world_box_size.z / meters_per_voxel_xz, world_box_size.y / meters_per_voxel_y)), + worldBoxSize(world_box_size), + metersPerVoxelXZ(meters_per_voxel_xz), + metersPerVoxelY(meters_per_voxel_y) { +#define VAR(a) a##VarId = get_shader_variable_id(#a, true); + VARS_LIST +#undef VAR + voxelizeCs.reset(new_compute_shader("voxelize_depth_above")); - voxelTex = dag::create_voltex(volTexSize.x, volTexSize.y, volTexSize.z, TEXFMT_R8UI | TEXCF_UNORDERED, 1, "cfd_voxel_tex"); + voxelTex = dag::create_voltex(voxelTexSize.x, voxelTexSize.y, voxelTexSize.z, TEXFMT_L8 | TEXCF_UNORDERED, 1, "cfd_voxel_tex"); + voxelTex->texfilter(TEXFILTER_POINT); + voxelTex->texaddr(TEXADDR_CLAMP); - ShaderGlobal::set_int4(get_shader_variable_id("cfd_voxel_tex_size"), IPoint4(volTexSize.x, volTexSize.y, volTexSize.z, 0)); - ShaderGlobal::set_color4(get_shader_variable_id("cfd_voxel_size"), metersPerVoxel, metersPerVoxel * 4, metersPerVoxel, 0); + ShaderGlobal::set_int4(cfd_voxel_tex_sizeVarId, IPoint4(voxelTexSize.x, voxelTexSize.y, voxelTexSize.z, 0)); + ShaderGlobal::set_color4(cfd_voxel_sizeVarId, metersPerVoxelXZ, metersPerVoxelY, metersPerVoxelXZ, 0); } -void Voxelizer::voxelizeDepthAbove(const Point3 &world_pos, const Point2 &world_y_min_max) +void Voxelizer::voxelizeDepthAbove(const Point3 &world_pos, float world_y_min) { const Point2 worldCenterXZ = Point2::xz(world_pos); Point2 worldMinXZ = worldCenterXZ - Point2::xz(worldBoxSize) / 2.f; + Point3 worldMin = Point3::xVy(worldMinXZ, world_y_min); + worldBox = BBox3(worldMin, worldMin + worldBoxSize); + + worldToVoxel = Point4(1.0f / worldBoxSize.x, 1.0f / worldBoxSize.z, worldMinXZ.x, worldMinXZ.y); + worldToVoxelHeight = Point4(1.0f / worldBoxSize.y, world_y_min, 0, 0); - Point3 worldMin = Point3::xVy(worldMinXZ, world_y_min_max.x); + ShaderGlobal::set_color4(cfd_world_box_minVarId, Point4::xyz0(worldMin)); + ShaderGlobal::set_color4(cfd_world_to_voxelVarId, worldToVoxel); + ShaderGlobal::set_color4(cfd_world_to_voxel_heightVarId, worldToVoxelHeight); - ShaderGlobal::set_color4(get_shader_variable_id("world_box_corner"), Point4::xyz0(worldMin)); + voxelizeCs->dispatchThreads(voxelTexSize.x, voxelTexSize.y, voxelTexSize.z); + d3d::resource_barrier({voxelTex.getBaseTex(), RB_STAGE_COMPUTE | RB_RO_SRV, 0, 0}); +} + +TEXTUREID Voxelizer::getVoxelTexId() const { return voxelTex.getTexId(); } +Point4 Voxelizer::getWorldToVoxel() const { return worldToVoxel; } +Point4 Voxelizer::getWorldToVoxelHeight() const { return worldToVoxelHeight; }; - voxelizeCs->dispatchThreads(volTexSize.x, volTexSize.y, volTexSize.z); +Point3 Voxelizer::getCenter() const { return worldBox.center(); } +BBox3 Voxelizer::getWorldBox() const { return worldBox; } + +Point3 Voxelizer::getVoxelTC(const Point3 &world_pos) +{ + Point3 tc; + tc.x = clamp((world_pos.x - worldToVoxel.z) * worldToVoxel.x, 0.f, 1.f); + tc.y = clamp((world_pos.z - worldToVoxel.w) * worldToVoxel.y, 0.f, 1.f); + tc.z = clamp((world_pos.y - worldToVoxelHeight.y) * worldToVoxelHeight.x, 0.f, 1.f); + return tc; } } // namespace cfd diff --git a/prog/gameLibs/render/foam/foamFx.cpp b/prog/gameLibs/render/foam/foamFx.cpp index e94232dca..8b1573b9d 100644 --- a/prog/gameLibs/render/foam/foamFx.cpp +++ b/prog/gameLibs/render/foam/foamFx.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include enum class FoamTexture { @@ -37,7 +37,7 @@ static const char *foamTextureNames[]{ static const char *getFoamTextureName(FoamTexture tex) { return foamTextureNames[(int)tex]; } -static eastl::map debugTextures; +static dag::VectorMap debugTextures; static const char *prepare_debug_step[]{ "pattern", diff --git a/prog/gameLibs/render/hdrRender/hdrRender.cpp b/prog/gameLibs/render/hdrRender/hdrRender.cpp index 1456e1db8..1f2d16d3a 100644 --- a/prog/gameLibs/render/hdrRender/hdrRender.cpp +++ b/prog/gameLibs/render/hdrRender/hdrRender.cpp @@ -12,7 +12,7 @@ namespace { namespace defaults { -#include "../shaders/hdr/hdr_render_defaults.sh" +#include "../shaders/hdr/hdr_render_defaults.dshl" } } // namespace diff --git a/prog/gameLibs/render/iesTextureManager.cpp b/prog/gameLibs/render/iesTextureManager.cpp index 7ce4f9d57..86c0df1ca 100644 --- a/prog/gameLibs/render/iesTextureManager.cpp +++ b/prog/gameLibs/render/iesTextureManager.cpp @@ -6,6 +6,8 @@ #include #include #include <3d/dag_resPtr.h> +#include +#include #include @@ -13,6 +15,7 @@ static const char *const PHOTOMETRY_TEX_NAME = "photometry_textures"; static const char *const PHOTOMETRY_VAR_NAME = "photometry_textures_tex"; IesTextureCollection *IesTextureCollection::instance = nullptr; +const char *IesTextureCollection::EDITOR_TEXTURE_NAME = "__ies_editor_tex__"; IesTextureCollection *IesTextureCollection::getSingleton() { return instance; } @@ -65,6 +68,8 @@ void IesTextureCollection::close() int IesTextureCollection::getTextureIdx(const char *name) { + if (strcmp(name, EDITOR_TEXTURE_NAME) == 0) + return usedTextures.size(); int ret = textureNames.getNameId(name); if (ret == -1) { @@ -77,11 +82,15 @@ int IesTextureCollection::getTextureIdx(const char *name) return ret; } -IesTextureCollection::PhotometryData IesTextureCollection::getTextureData(int texIdx) const +IesTextureCollection::PhotometryData IesTextureCollection::getTextureData(int tex_idx) const { - if (texIdx < 0) + if (tex_idx < 0) return {}; - return photometryData[texIdx]; + // tex_idx == photometryData.size() is a special value, it indicates that this is the edited texture + // The edited texture currently only supports default photometry parameters + if (tex_idx >= photometryData.size()) + return {}; + return photometryData[tex_idx]; } void IesTextureCollection::reloadTextures() @@ -123,6 +132,8 @@ void IesTextureCollection::reloadTextures() } } +TEXTUREID IesTextureCollection::getTextureArrayId() { return photometryTexId; } + void IesTextureCollection::addTexture(const char *textureName) { // This implementation is not efficient, but it is rarely used @@ -131,3 +142,159 @@ void IesTextureCollection::addTexture(const char *textureName) usedTextures.push_back(String(textureName)); reloadTextures(); } + +IesEditor *IesTextureCollection::requireEditor() +{ + if (!editor) + editor = eastl::make_unique(); + return editor.get(); +} + +IPoint3 IesEditor::getTexResolution(BaseTexture *photometry_tex_array) +{ + if (photometry_tex_array == nullptr) + return IPoint3(0, 0, 0); + TextureInfo textureInfo; + photometry_tex_array->getinfo(textureInfo); + return IPoint3(textureInfo.w, textureInfo.h, textureInfo.a); +} + +void IesEditor::ensureTextureCreated(BaseTexture *photometry_tex_array) +{ + IPoint3 photometryResolution = getTexResolution(photometry_tex_array); + IPoint3 newResolution = IPoint3(photometryResolution.x, photometryResolution.y, photometryResolution.z + 1); + if (newResolution == currentResolution) + return; + dynamicIesTexArray.close(); + currentResolution = newResolution; + if (photometry_tex_array == nullptr) + return; + dynamicIesTexArray = dag::create_array_tex(currentResolution.x, currentResolution.y, currentResolution.z, + TEXCF_RTARGET | TEXCF_CLEAR_ON_CREATE | TEXCF_SRGBREAD | TEXFMT_L8, 1, "ies_editor_tex"); + for (int i = 0; i < photometryResolution.z; ++i) + { + dynamicIesTexArray.getArrayTex()->updateSubRegion(photometry_tex_array, i, 0, 0, 0, photometryResolution.x, photometryResolution.y, + 1, i, 0, 0, 0); + } + d3d::resource_barrier({dynamicIesTexArray.getArrayTex(), RB_RO_SRV | RB_STAGE_PIXEL, 0, 0}); + static int photometry_textures_texVarId = get_shader_variable_id("photometry_textures_tex", true); + ShaderGlobal::set_texture(photometry_textures_texVarId, dynamicIesTexArray.getTexId()); +} + +IesEditor::IesEditor() : iesGenerator("ies_generator") +{ + IesTextureCollection *photometryTextures = IesTextureCollection::getSingleton(); + if (TEXTUREID photometryTexArrayId = photometryTextures->getTextureArrayId()) + { + BaseTexture *photometryTexArray = ::acquire_managed_tex(photometryTexArrayId); + ensureTextureCreated(photometryTexArray); + ::release_managed_tex(photometryTexArrayId); + } + sortedPhotometryControlPointsBuf = + dag::buffers::create_persistent_sr_structured(sizeof(PhotometryControlPoint), MAX_NUM_CONTROL_POINTS, "ies_control_points_buf"); +} + +void IesEditor::renderIesTexture() +{ + TIME_D3D_PROFILE(iesTextureGen); + if (currentResolution.lengthSq() == 0 || dynamicIesTexArray.getBaseTex() == nullptr) + return; + if (!needsRender) + return; + needsRender = false; + + if (!sortedPhotometryControlPoints.empty()) + sortedPhotometryControlPointsBuf->updateDataWithLock(0, + sizeof(sortedPhotometryControlPoints[0]) * sortedPhotometryControlPoints.size(), sortedPhotometryControlPoints.data(), + VBLOCK_WRITEONLY); + + float maxLight = 0; + for (const auto &controlPoint : sortedPhotometryControlPoints) + maxLight = eastl::max(maxLight, controlPoint.lightIntensity); + static int num_control_pointsVarId = get_shader_variable_id("num_control_points", false); + static int ies_max_light_levelVarId = get_shader_variable_id("ies_max_light_level", false); + ShaderGlobal::set_int(num_control_pointsVarId, sortedPhotometryControlPoints.size()); + ShaderGlobal::set_real(ies_max_light_levelVarId, maxLight); + + { + SCOPE_RENDER_TARGET; + d3d::set_render_target(dynamicIesTexArray.getBaseTex(), currentResolution.z - 1, 0); + iesGenerator.render(); + } +} + +void IesEditor::clearControlPoints() +{ + sortedPhotometryControlPoints.clear(); + recalcCoefficients(); +} + +void IesEditor::removeControlPoint(int index) +{ + sortedPhotometryControlPoints.erase(sortedPhotometryControlPoints.begin() + index); + recalcCoefficients(); +} + +void IesEditor::recalcCoefficients() +{ + needsRender = true; + if (sortedPhotometryControlPoints.empty()) + return; + for (int i = 0; i < sortedPhotometryControlPoints.size(); ++i) + { + if (i + 1 < sortedPhotometryControlPoints.size()) + { + float t0 = sortedPhotometryControlPoints[i].theta; + float l0 = sortedPhotometryControlPoints[i].lightIntensity; + float l1 = sortedPhotometryControlPoints[i + 1].lightIntensity; + float t1 = sortedPhotometryControlPoints[i + 1].theta; + + float y = safediv(l1 - l0, t1 - t0); + float x = l0 - y * t0; + sortedPhotometryControlPoints[i].coefficients = float2(x, y); + } + else + sortedPhotometryControlPoints[i].coefficients = float2(sortedPhotometryControlPoints[i].lightIntensity, 0); + } +} + +int IesEditor::addPointWithoutUpdate(float theta, float intensity) +{ + sortedPhotometryControlPoints.resize(sortedPhotometryControlPoints.size() + 1); + int index = sortedPhotometryControlPoints.size() - 1; + while (index > 0 && sortedPhotometryControlPoints[index - 1].theta > theta) + { + sortedPhotometryControlPoints[index] = sortedPhotometryControlPoints[index - 1]; + index--; + } + sortedPhotometryControlPoints[index] = {float2(0, 0), theta, intensity}; + return index; +} + +int IesEditor::addPointWithUpdate(float theta, float intensity) +{ + int index = addPointWithoutUpdate(theta, intensity); + recalcCoefficients(); + return index; +} + +float IesEditor::getLightIntensityAt(float theta) const +{ + if (sortedPhotometryControlPoints.empty()) + return 1; + int a = 0, b = sortedPhotometryControlPoints.size(); + while (a + 1 < b) + { + int m = (a + b) / 2; + if (theta < sortedPhotometryControlPoints[m].theta) + b = m; + else + a = m; + } + const auto &coeffs = sortedPhotometryControlPoints[a].coefficients; + theta = eastl::max(theta, sortedPhotometryControlPoints[a].theta); // clamp on low end + if (a + 1 < sortedPhotometryControlPoints.size()) + theta = eastl::min(theta, sortedPhotometryControlPoints[a + 1].theta); // clamp on high end + + return coeffs.x + theta * coeffs.y; +} \ No newline at end of file diff --git a/prog/gameLibs/render/randomGrass.cpp b/prog/gameLibs/render/randomGrass.cpp index 1dbbe4b45..e627473e6 100644 --- a/prog/gameLibs/render/randomGrass.cpp +++ b/prog/gameLibs/render/randomGrass.cpp @@ -931,9 +931,11 @@ void RandomGrass::fillLayerLod(GrassLayer &layer, unsigned int lod_idx, int rand if ((lod.maxRadius - lod.minRadius) < 1.f) numInstancesInCell = 0; + bool emptyLayer = false; if (numInstancesInCell == 0) { numInstancesInCell = 1; + emptyLayer = true; } if (vboForMaxElements) @@ -951,7 +953,7 @@ void RandomGrass::fillLayerLod(GrassLayer &layer, unsigned int lod_idx, int rand lod.warpSize = (quadSize * 2 + 1); int maxInstancesInBuffer = lod.warpSize * lod.warpSize * (GRASS_WARP_SIZE_X * GRASS_WARP_SIZE_Y); // we can't see all instances lod.maxInstancesCount = maxInstancesInBuffer; - if (numInstancesInCell == 1) // empty layer + if (emptyLayer) { lod.warpSize = 0; lod.maxInstancesCount = 0; diff --git a/prog/gameLibs/render/shaders/alternate_reflections.sh b/prog/gameLibs/render/shaders/alternate_reflections.dshl similarity index 100% rename from prog/gameLibs/render/shaders/alternate_reflections.sh rename to prog/gameLibs/render/shaders/alternate_reflections.dshl diff --git a/prog/gameLibs/render/shaders/android_screen_rotate.sh b/prog/gameLibs/render/shaders/android_screen_rotate.dshl similarity index 97% rename from prog/gameLibs/render/shaders/android_screen_rotate.sh rename to prog/gameLibs/render/shaders/android_screen_rotate.dshl index 0a378820a..f274ed257 100644 --- a/prog/gameLibs/render/shaders/android_screen_rotate.sh +++ b/prog/gameLibs/render/shaders/android_screen_rotate.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" int android_internal_backbuffer_binding_reg = 15; int android_screen_rotation = 0; diff --git a/prog/gameLibs/render/shaders/antialiasing_fxaa.sh b/prog/gameLibs/render/shaders/antialiasing_fxaa.dshl similarity index 99% rename from prog/gameLibs/render/shaders/antialiasing_fxaa.sh rename to prog/gameLibs/render/shaders/antialiasing_fxaa.dshl index 7cdd1e7b2..fcdd2bcc2 100644 --- a/prog/gameLibs/render/shaders/antialiasing_fxaa.sh +++ b/prog/gameLibs/render/shaders/antialiasing_fxaa.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "gbuffer.sh" +include "shader_global.dshl" +include "gbuffer.dshl" texture source_color_tex; float4 fxaa_params = (0.5, 0.166, 0.0833, 0); // fxaaQualitySubpix, fxaaQualityEdgeThreshold, fxaaQualityEdgeThresholdMin @@ -34,7 +34,7 @@ shader antialiasing cull_mode = none; z_write = false; - if (use_screen_mask == yes) + if (maybe(screen_mask_enabled)) { z_test=true; } diff --git a/prog/gameLibs/render/shaders/assert.sh b/prog/gameLibs/render/shaders/assert.dshl similarity index 100% rename from prog/gameLibs/render/shaders/assert.sh rename to prog/gameLibs/render/shaders/assert.dshl diff --git a/prog/gameLibs/render/shaders/aurora_borealis.sh b/prog/gameLibs/render/shaders/aurora_borealis.dshl similarity index 96% rename from prog/gameLibs/render/shaders/aurora_borealis.sh rename to prog/gameLibs/render/shaders/aurora_borealis.dshl index b34dc9456..01ec72471 100644 --- a/prog/gameLibs/render/shaders/aurora_borealis.sh +++ b/prog/gameLibs/render/shaders/aurora_borealis.dshl @@ -1,10 +1,10 @@ -include "sky_shader_global.sh" -include "postfx_inc.sh" -include "viewVecVS.sh" -include "clouds2/clouds_alt_fraction.sh" -include "panorama.sh" -include "skies_special_vision.sh" -include "use_custom_fog_sky.sh" +include "sky_shader_global.dshl" +include "postfx_inc.dshl" +include "viewVecVS.dshl" +include "clouds2/clouds_alt_fraction.dshl" +include "panorama.dshl" +include "skies_special_vision.dshl" +include "use_custom_fog_sky.dshl" float4 aurora_borealis_bottom = (0.1, 1.0, 1.0, 5.0); float4 aurora_borealis_top = (1.000, 0.1, 0.3, 9.0); diff --git a/prog/gameLibs/render/shaders/bc1_compression.sh b/prog/gameLibs/render/shaders/bc1_compression.dshl similarity index 91% rename from prog/gameLibs/render/shaders/bc1_compression.sh rename to prog/gameLibs/render/shaders/bc1_compression.dshl index dc7acc931..2cc441a74 100644 --- a/prog/gameLibs/render/shaders/bc1_compression.sh +++ b/prog/gameLibs/render/shaders/bc1_compression.dshl @@ -1,5 +1,5 @@ -include "land_block_inc.sh" -include "bc_compression_inc.sh" +include "land_block_inc.dshl" +include "bc_compression_inc.dshl" texture src_tex; float src_mip = 0; diff --git a/prog/gameLibs/render/shaders/bc3_compression.sh b/prog/gameLibs/render/shaders/bc3_compression.dshl similarity index 90% rename from prog/gameLibs/render/shaders/bc3_compression.sh rename to prog/gameLibs/render/shaders/bc3_compression.dshl index c28927842..5cffe07fe 100644 --- a/prog/gameLibs/render/shaders/bc3_compression.sh +++ b/prog/gameLibs/render/shaders/bc3_compression.dshl @@ -1,5 +1,5 @@ -include "land_block_inc.sh" -include "bc_compression_inc.sh" +include "land_block_inc.dshl" +include "bc_compression_inc.dshl" texture src_tex; float src_mip = 0; diff --git a/prog/gameLibs/render/shaders/bc4_compression.sh b/prog/gameLibs/render/shaders/bc4_compression.dshl similarity index 90% rename from prog/gameLibs/render/shaders/bc4_compression.sh rename to prog/gameLibs/render/shaders/bc4_compression.dshl index fb7976285..85d777e40 100644 --- a/prog/gameLibs/render/shaders/bc4_compression.sh +++ b/prog/gameLibs/render/shaders/bc4_compression.dshl @@ -1,5 +1,5 @@ -include "land_block_inc.sh" -include "bc_compression_inc.sh" +include "land_block_inc.dshl" +include "bc_compression_inc.dshl" texture src_tex; float src_mip = 0; diff --git a/prog/gameLibs/render/shaders/bc5_compression.sh b/prog/gameLibs/render/shaders/bc5_compression.dshl similarity index 90% rename from prog/gameLibs/render/shaders/bc5_compression.sh rename to prog/gameLibs/render/shaders/bc5_compression.dshl index d12f00379..313254fff 100644 --- a/prog/gameLibs/render/shaders/bc5_compression.sh +++ b/prog/gameLibs/render/shaders/bc5_compression.dshl @@ -1,5 +1,5 @@ -include "land_block_inc.sh" -include "bc_compression_inc.sh" +include "land_block_inc.dshl" +include "bc_compression_inc.dshl" texture src_tex; float src_mip = 0; diff --git a/prog/gameLibs/render/shaders/bc6h_compression.sh b/prog/gameLibs/render/shaders/bc6h_compression.dshl similarity index 85% rename from prog/gameLibs/render/shaders/bc6h_compression.sh rename to prog/gameLibs/render/shaders/bc6h_compression.dshl index 7d879bdf1..f7d620dc4 100644 --- a/prog/gameLibs/render/shaders/bc6h_compression.sh +++ b/prog/gameLibs/render/shaders/bc6h_compression.dshl @@ -1,6 +1,6 @@ -include "land_block_inc.sh" -include "bc_compression_inc.sh" -include "bc6h_compression_inc.sh" +include "land_block_inc.dshl" +include "bc_compression_inc.dshl" +include "bc6h_compression_inc.dshl" texture src_tex; float src_mip = 0; diff --git a/prog/gameLibs/render/shaders/bc6h_compression_inc.sh b/prog/gameLibs/render/shaders/bc6h_compression_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/bc6h_compression_inc.sh rename to prog/gameLibs/render/shaders/bc6h_compression_inc.dshl diff --git a/prog/gameLibs/render/shaders/bc_compression_inc.sh b/prog/gameLibs/render/shaders/bc_compression_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/bc_compression_inc.sh rename to prog/gameLibs/render/shaders/bc_compression_inc.dshl diff --git a/prog/gameLibs/render/shaders/beam_tracers_gen.sh b/prog/gameLibs/render/shaders/beam_tracers_gen.dshl similarity index 99% rename from prog/gameLibs/render/shaders/beam_tracers_gen.sh rename to prog/gameLibs/render/shaders/beam_tracers_gen.dshl index bac26aea1..c3517ab7f 100644 --- a/prog/gameLibs/render/shaders/beam_tracers_gen.sh +++ b/prog/gameLibs/render/shaders/beam_tracers_gen.dshl @@ -1,6 +1,6 @@ -include "shader_global.sh" -include "frustum.sh" -include "globtm.sh" +include "shader_global.dshl" +include "frustum.dshl" +include "globtm.dshl" hlsl { #include } diff --git a/prog/gameLibs/render/shaders/bigLightShadows/render_big_light_shadows.sh b/prog/gameLibs/render/shaders/bigLightShadows/render_big_light_shadows.dshl similarity index 98% rename from prog/gameLibs/render/shaders/bigLightShadows/render_big_light_shadows.sh rename to prog/gameLibs/render/shaders/bigLightShadows/render_big_light_shadows.dshl index b9e3bc0b6..b71f03cb2 100644 --- a/prog/gameLibs/render/shaders/bigLightShadows/render_big_light_shadows.sh +++ b/prog/gameLibs/render/shaders/bigLightShadows/render_big_light_shadows.dshl @@ -1,10 +1,10 @@ -include "shader_global.sh" -include "viewVecVS.sh" -include "gbuffer.sh" -include "contact_shadows.sh" -include "depth_above.sh" -include "ssao_reprojection.sh" -include "dagi_reflections.sh" +include "shader_global.dshl" +include "viewVecVS.dshl" +include "gbuffer.dshl" +include "contact_shadows.dshl" +include "depth_above.dshl" +include "ssao_reprojection.dshl" +include "dagi_reflections.dshl" texture downsampled_normals; @@ -146,8 +146,8 @@ shader render_big_light_shadows { float3 rayPos = startPos + dist*rayDir; float vignette_effect; - float2 tc = getWorldBlurredDepthTC(rayPos, vignette_effect); - float rayHeightmap = decode_depth_above(tex2Dlod(blurred_depth, float4(tc,0,0) ).x); + float3 tc = getWorldBlurredDepthTC(rayPos, vignette_effect); + float rayHeightmap = decode_depth_above(tex3Dlod(blurred_depth, float4(tc, 0)).x); if (vignette_effect<0.99 && rayHeightmap - 0.25/dist > rayPos.y)// && rayHeightmap < rayPos.y + 2 + dist)//disocclusion { //shadow *= exp2(-0.1*dist); diff --git a/prog/gameLibs/render/shaders/bloom_ps.sh b/prog/gameLibs/render/shaders/bloom_ps.dshl similarity index 98% rename from prog/gameLibs/render/shaders/bloom_ps.sh rename to prog/gameLibs/render/shaders/bloom_ps.dshl index 450f3e868..bfcbf6dbb 100644 --- a/prog/gameLibs/render/shaders/bloom_ps.sh +++ b/prog/gameLibs/render/shaders/bloom_ps.dshl @@ -1,8 +1,8 @@ -include "shader_global.sh" -include "gbuffer.sh" -include "viewVecVS.sh" -//include "dacloud_mask.sh" -include "tonemapHelpers/use_full_tonemap_lut_inc.sh" +include "shader_global.dshl" +include "gbuffer.dshl" +include "viewVecVS.dshl" +//include "dacloud_mask.dshl" +include "tonemapHelpers/use_full_tonemap_lut_inc.dshl" texture blur_src_tex; diff --git a/prog/gameLibs/render/shaders/burningFoliage/burning_foliage_inc.sh b/prog/gameLibs/render/shaders/burningFoliage/burning_foliage_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/burningFoliage/burning_foliage_inc.sh rename to prog/gameLibs/render/shaders/burningFoliage/burning_foliage_inc.dshl diff --git a/prog/gameLibs/render/shaders/capsuledAO.sh b/prog/gameLibs/render/shaders/capsuledAO.dshl similarity index 100% rename from prog/gameLibs/render/shaders/capsuledAO.sh rename to prog/gameLibs/render/shaders/capsuledAO.dshl diff --git a/prog/gameLibs/render/shaders/caustics.sh b/prog/gameLibs/render/shaders/caustics.dshl similarity index 100% rename from prog/gameLibs/render/shaders/caustics.sh rename to prog/gameLibs/render/shaders/caustics.dshl diff --git a/prog/gameLibs/render/shaders/caustics_render.dshl b/prog/gameLibs/render/shaders/caustics_render.dshl new file mode 100644 index 000000000..986d01c24 --- /dev/null +++ b/prog/gameLibs/render/shaders/caustics_render.dshl @@ -0,0 +1,46 @@ +include "caustics_render_inc.dshl" +include "frustum.dshl" + + + +shader caustics_render +{ + no_ablend; + cull_mode = none; + z_write = false; + z_test = false; + + CAUSTICS_RENDER_CORE(ps) + + USE_AND_INIT_VIEW_VEC_VS() + POSTFX_VS_TEXCOORD_VIEWVEC(0, texcoord, viewVect) + + hlsl(ps) { + half4 caustics_ps(VsOutput input) : SV_Target + { + return caustics(input.texcoord, input.viewVect); + } + } + compile("target_ps", "caustics_ps"); +} + +shader indoor_probe_to_depth +{ + supports global_frame; + supports none; + color_write = 0; + z_test = true; + z_write = true; + cull_mode = none; + channel float3 pos = pos; + (vs) {globtm@f44 = globtm;} + hlsl(vs) + { + float4 very_basic_vs(float3 pos : POSITION) : SV_POSITION + { + return mulPointTm(pos, globtm); + } + } + compile("target_vs", "very_basic_vs"); + compile("ps_null", "null_ps"); +} \ No newline at end of file diff --git a/prog/gameLibs/render/shaders/caustics_render_cs.dshl b/prog/gameLibs/render/shaders/caustics_render_cs.dshl new file mode 100644 index 000000000..55215d28d --- /dev/null +++ b/prog/gameLibs/render/shaders/caustics_render_cs.dshl @@ -0,0 +1,29 @@ +include "caustics_render_inc.dshl" + +shader caustics_render_cs +{ + if (hardware.fsh_5_0) + { + USE_AND_INIT_VIEW_VEC_CS() + CAUSTICS_RENDER_CORE(cs) + + hlsl(cs) { + RWTexture2D caustics_tex : register(u0); + + [numthreads(8, 8, 1)] + void caustics_cs(uint3 DTid : SV_DispatchThreadID) + { + float2 pixelCenter = DTid.xy + 0.5; + float2 texcoord = pixelCenter * inv_caustics_texture_size.xy; + float3 viewVect = lerp_view_vec(texcoord); + + caustics_tex[DTid.xy] = caustics(texcoord, viewVect); + } + } + compile("target_cs", "caustics_cs"); + } + else + { + dont_render; + } +} diff --git a/prog/gameLibs/render/shaders/caustics_render.sh b/prog/gameLibs/render/shaders/caustics_render_inc.dshl similarity index 56% rename from prog/gameLibs/render/shaders/caustics_render.sh rename to prog/gameLibs/render/shaders/caustics_render_inc.dshl index 6e9c53a81..4970203d3 100644 --- a/prog/gameLibs/render/shaders/caustics_render.sh +++ b/prog/gameLibs/render/shaders/caustics_render_inc.dshl @@ -1,10 +1,10 @@ -include "shader_global.sh" -include "gbuffer.sh" -include "viewVecVS.sh" -include "caustics.sh" -include "static_shadow.sh" -include "frustum.sh" -include "water_heightmap.sh" +include "shader_global.dshl" +include "gbuffer.dshl" +include "viewVecVS.dshl" +include "caustics.dshl" +include "static_shadow.dshl" +include "water_heightmap.dshl" + texture downsampled_normals; float4 caustics_texture_size; @@ -86,73 +86,3 @@ macro CAUSTICS_RENDER_CORE(code) } } endmacro - -shader caustics_render -{ - no_ablend; - cull_mode = none; - z_write = false; - z_test = false; - - CAUSTICS_RENDER_CORE(ps) - - USE_AND_INIT_VIEW_VEC_VS() - POSTFX_VS_TEXCOORD_VIEWVEC(0, texcoord, viewVect) - - hlsl(ps) { - half4 caustics_ps(VsOutput input) : SV_Target - { - return caustics(input.texcoord, input.viewVect); - } - } - compile("target_ps", "caustics_ps"); -} - -shader caustics_render_cs -{ - if (hardware.fsh_5_0) - { - USE_AND_INIT_VIEW_VEC_CS() - CAUSTICS_RENDER_CORE(cs) - - hlsl(cs) { - RWTexture2D caustics_tex : register(u0); - - [numthreads(8, 8, 1)] - void caustics_cs(uint3 DTid : SV_DispatchThreadID) - { - float2 pixelCenter = DTid.xy + 0.5; - float2 texcoord = pixelCenter * inv_caustics_texture_size.xy; - float3 viewVect = lerp_view_vec(texcoord); - - caustics_tex[DTid.xy] = caustics(texcoord, viewVect); - } - } - compile("target_cs", "caustics_cs"); - } - else - { - dont_render; - } -} - -shader indoor_probe_to_depth -{ - supports global_frame; - supports none; - color_write = 0; - z_test = true; - z_write = true; - cull_mode = none; - channel float3 pos = pos; - (vs) {globtm@f44 = globtm;} - hlsl(vs) - { - float4 very_basic_vs(float3 pos : POSITION) : SV_POSITION - { - return mulPointTm(pos, globtm); - } - } - compile("target_vs", "very_basic_vs"); - compile("ps_null", "null_ps"); -} \ No newline at end of file diff --git a/prog/gameLibs/render/shaders/clipmap_histogram.sh b/prog/gameLibs/render/shaders/clipmap_histogram.dshl similarity index 98% rename from prog/gameLibs/render/shaders/clipmap_histogram.sh rename to prog/gameLibs/render/shaders/clipmap_histogram.dshl index 8940ee74f..1bffeae99 100644 --- a/prog/gameLibs/render/shaders/clipmap_histogram.sh +++ b/prog/gameLibs/render/shaders/clipmap_histogram.dshl @@ -1,6 +1,6 @@ -include "shader_global.sh" -include "frustum.sh" -include "vtex.sh" +include "shader_global.dshl" +include "frustum.dshl" +include "vtex.dshl" diff --git a/prog/gameLibs/render/shaders/clustered/debug_deferred_lights.sh b/prog/gameLibs/render/shaders/clustered/debug_deferred_lights.dshl similarity index 98% rename from prog/gameLibs/render/shaders/clustered/debug_deferred_lights.sh rename to prog/gameLibs/render/shaders/clustered/debug_deferred_lights.dshl index f55286fb8..518bf3251 100644 --- a/prog/gameLibs/render/shaders/clustered/debug_deferred_lights.sh +++ b/prog/gameLibs/render/shaders/clustered/debug_deferred_lights.dshl @@ -1,5 +1,5 @@ -include "hardware_defines.sh" -include "lights_cb.sh" +include "hardware_defines.dshl" +include "lights_cb.dshl" float4 world_view_pos; diff --git a/prog/gameLibs/render/shaders/clustered/deferred_lights.sh b/prog/gameLibs/render/shaders/clustered/deferred_lights.dshl similarity index 99% rename from prog/gameLibs/render/shaders/clustered/deferred_lights.sh rename to prog/gameLibs/render/shaders/clustered/deferred_lights.dshl index 13eab9685..b4a9ce19b 100644 --- a/prog/gameLibs/render/shaders/clustered/deferred_lights.sh +++ b/prog/gameLibs/render/shaders/clustered/deferred_lights.dshl @@ -1,4 +1,4 @@ -include "lights_cb.sh" +include "lights_cb.dshl" int dynamic_lights_far_specular = 1; interval dynamic_lights_far_specular:off<1, on; @@ -76,7 +76,7 @@ macro DEFERRED_OMNI_LIGHTS_PS_SHADER() { #include "readDeferredGbuffer.hlsl" float4 color_and_attenuation = input.color_and_attenuation; - result = perform_point_light(worldPos.xyz, view, NoV, gbuffer, gbuffer.specularColor, dynamicLightsSpecularStrength, gbuffer.ao, pos_and_radius, color_and_attenuation, shadowTcToAtlas, screenpos.xy);//use gbuffer.specularColor for equality with point_lights.sh + result = perform_point_light(worldPos.xyz, view, NoV, gbuffer, gbuffer.specularColor, dynamicLightsSpecularStrength, gbuffer.ao, pos_and_radius, color_and_attenuation, shadowTcToAtlas, screenpos.xy);//use gbuffer.specularColor for equality with point_lights.dshl result *= pointLightsFinalAO; return true; } diff --git a/prog/gameLibs/render/shaders/clustered/lights_cb.sh b/prog/gameLibs/render/shaders/clustered/lights_cb.dshl similarity index 97% rename from prog/gameLibs/render/shaders/clustered/lights_cb.sh rename to prog/gameLibs/render/shaders/clustered/lights_cb.dshl index fee669712..4545b127a 100644 --- a/prog/gameLibs/render/shaders/clustered/lights_cb.sh +++ b/prog/gameLibs/render/shaders/clustered/lights_cb.dshl @@ -26,28 +26,12 @@ macro USE_PHOTOMETRY_TEXTURES(code) #include #include #include + #include #ifndef M_PI #define M_PI (3.14159265358979323846) #endif - half2 octahedral_mapping(half3 co, float zoom, bool rotate) - { - co /= dot(half3(1, 1, 1), abs(co)); - co.xy = co.y < 0.0 - ? (1.0 - abs(co.zx)) * (co.xz < 0 ? float2(-1, -1) : float2(1, 1)) - : co.xz; - if (rotate) - { - float tempX = co.x; - co.x = (co.x + co.y); - co.y = (co.y - tempX); - } - co.x *= zoom; - co.y *= zoom; - return co.xy * 0.5 + 0.5; - } - half2 getPhotometryTexCoords(half3 lightDir, half3 dir, float zoom, bool rotate) { half3 side = abs(lightDir.x) < 0.707106781186548 // = cos(M_PI/4) ? half3(1, 0, 0) diff --git a/prog/gameLibs/render/shaders/clustered/sample_deferred_lights.sh b/prog/gameLibs/render/shaders/clustered/sample_deferred_lights.dshl similarity index 93% rename from prog/gameLibs/render/shaders/clustered/sample_deferred_lights.sh rename to prog/gameLibs/render/shaders/clustered/sample_deferred_lights.dshl index 14ca0f898..f9a892752 100644 --- a/prog/gameLibs/render/shaders/clustered/sample_deferred_lights.sh +++ b/prog/gameLibs/render/shaders/clustered/sample_deferred_lights.dshl @@ -1,7 +1,7 @@ -include "clustered/deferred_lights.sh" -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "gbuffer.sh" +include "clustered/deferred_lights.dshl" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "gbuffer.dshl" shader point_lights, spot_lights diff --git a/prog/gameLibs/render/shaders/clustered/simple_point_light.sh b/prog/gameLibs/render/shaders/clustered/simple_point_light.dshl similarity index 100% rename from prog/gameLibs/render/shaders/clustered/simple_point_light.sh rename to prog/gameLibs/render/shaders/clustered/simple_point_light.dshl diff --git a/prog/gameLibs/render/shaders/clusteredViewLights.sh b/prog/gameLibs/render/shaders/clusteredViewLights.dshl similarity index 96% rename from prog/gameLibs/render/shaders/clusteredViewLights.sh rename to prog/gameLibs/render/shaders/clusteredViewLights.dshl index bc722e617..dbcf2b4b2 100644 --- a/prog/gameLibs/render/shaders/clusteredViewLights.sh +++ b/prog/gameLibs/render/shaders/clusteredViewLights.dshl @@ -1,7 +1,7 @@ -include "tile_lighting.sh" -include "punctualLights.sh" -include "clustered/lights_cb.sh" -include "dynamic_lights_count.sh" +include "tile_lighting.dshl" +include "punctualLights.dshl" +include "clustered/lights_cb.dshl" +include "dynamic_lights_count.dshl" macro INIT_CLUSTERED_VIEW_LIGHTS(code) INIT_PHOTOMETRY_TEXTURES(code) @@ -103,7 +103,7 @@ macro USE_CLUSTERED_VIEW_LIGHTS(code) #else float4 shadowTcToAtlas = float4(0, 0, 0, 0); #endif - half3 omniLight = perform_point_light(worldPos.xyz, view, NoV, gbuffer, specularColor, dynamicLightsSpecularStrength, gbuffer.ao, pos_and_radius, color_and_specular, shadowTcToAtlas, screenpos);//use gbuffer.specularColor for equality with point_lights.sh + half3 omniLight = perform_point_light(worldPos.xyz, view, NoV, gbuffer, specularColor, dynamicLightsSpecularStrength, gbuffer.ao, pos_and_radius, color_and_specular, shadowTcToAtlas, screenpos);//use gbuffer.specularColor for equality with point_lights.dshl OMNI_CONTACT_SHADOWS_CALC @@ -142,7 +142,7 @@ macro USE_CLUSTERED_VIEW_LIGHTS(code) } } //dynamicLighting += ((clusterGrid[clusterIndex].counts>>8)&0xFF)/8.0; - half pointLightsFinalAO = (enviAO*0.5+0.5);//we use ssao, since we use it in point_lights.sh (works slow, but not much lights are there) + half pointLightsFinalAO = (enviAO*0.5+0.5);//we use ssao, since we use it in point_lights.dshl (works slow, but not much lights are there) result += dynamicLighting*pointLightsFinalAO; } ##endif diff --git a/prog/gameLibs/render/shaders/contrast_adaptive_sharpening.sh b/prog/gameLibs/render/shaders/contrast_adaptive_sharpening.dshl similarity index 98% rename from prog/gameLibs/render/shaders/contrast_adaptive_sharpening.sh rename to prog/gameLibs/render/shaders/contrast_adaptive_sharpening.dshl index bb0c43dfc..3a7c89b11 100644 --- a/prog/gameLibs/render/shaders/contrast_adaptive_sharpening.sh +++ b/prog/gameLibs/render/shaders/contrast_adaptive_sharpening.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" // this is an implementation of AMD's CAS with some minor tweaks diff --git a/prog/gameLibs/render/shaders/copy_depth_region.sh b/prog/gameLibs/render/shaders/copy_depth_region.dshl similarity index 96% rename from prog/gameLibs/render/shaders/copy_depth_region.sh rename to prog/gameLibs/render/shaders/copy_depth_region.dshl index 46799a54c..61692e3d5 100644 --- a/prog/gameLibs/render/shaders/copy_depth_region.sh +++ b/prog/gameLibs/render/shaders/copy_depth_region.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" shader copy_depth_region diff --git a/prog/gameLibs/render/shaders/csm.sh b/prog/gameLibs/render/shaders/csm.dshl similarity index 99% rename from prog/gameLibs/render/shaders/csm.sh rename to prog/gameLibs/render/shaders/csm.dshl index 4d4791aa2..338f6764f 100644 --- a/prog/gameLibs/render/shaders/csm.sh +++ b/prog/gameLibs/render/shaders/csm.dshl @@ -1,4 +1,4 @@ -include "hardware_defines.sh" +include "hardware_defines.dshl" buffer csm_buffer; diff --git a/prog/gameLibs/render/shaders/debugGbuffer.sh b/prog/gameLibs/render/shaders/debugGbuffer.dshl similarity index 98% rename from prog/gameLibs/render/shaders/debugGbuffer.sh rename to prog/gameLibs/render/shaders/debugGbuffer.dshl index baec4f558..177bc169d 100644 --- a/prog/gameLibs/render/shaders/debugGbuffer.sh +++ b/prog/gameLibs/render/shaders/debugGbuffer.dshl @@ -1,11 +1,11 @@ -include "shader_global.sh" -include "ssao_use.sh" -include "gbuffer.sh" -include "ssr_use.sh" -include "viewVecVS.sh" -include "stencil_inc.sh" -include "clustered/lights_cb.sh" -include "taa_inc.sh" +include "shader_global.dshl" +include "ssao_use.dshl" +include "gbuffer.dshl" +include "ssr_use.dshl" +include "viewVecVS.dshl" +include "stencil_inc.dshl" +include "clustered/lights_cb.dshl" +include "taa_inc.dshl" macro MODE(mode, num) mode < num, diff --git a/prog/gameLibs/render/shaders/debug_indoor_boxes.sh b/prog/gameLibs/render/shaders/debug_indoor_boxes.dshl similarity index 97% rename from prog/gameLibs/render/shaders/debug_indoor_boxes.sh rename to prog/gameLibs/render/shaders/debug_indoor_boxes.dshl index c29e96e06..e89811e6e 100644 --- a/prog/gameLibs/render/shaders/debug_indoor_boxes.sh +++ b/prog/gameLibs/render/shaders/debug_indoor_boxes.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "indoor_light_probes.sh" +include "shader_global.dshl" +include "indoor_light_probes.dshl" float debug_indoor_boxes_size = 1.0; diff --git a/prog/gameLibs/render/shaders/debug_indoor_probes_on_screen.sh b/prog/gameLibs/render/shaders/debug_indoor_probes_on_screen.dshl similarity index 88% rename from prog/gameLibs/render/shaders/debug_indoor_probes_on_screen.sh rename to prog/gameLibs/render/shaders/debug_indoor_probes_on_screen.dshl index 20d6b068b..588f3532f 100644 --- a/prog/gameLibs/render/shaders/debug_indoor_probes_on_screen.sh +++ b/prog/gameLibs/render/shaders/debug_indoor_probes_on_screen.dshl @@ -1,8 +1,8 @@ -include "shader_global.sh" -include "postfx_inc.sh" -include "viewVecVS.sh" -include "gbuffer.sh" -include "indoor_light_probes.sh" +include "shader_global.dshl" +include "postfx_inc.dshl" +include "viewVecVS.dshl" +include "gbuffer.dshl" +include "indoor_light_probes.dshl" shader debug_indoor_probes_on_screen { diff --git a/prog/gameLibs/render/shaders/debug_light_probe_spheres.sh b/prog/gameLibs/render/shaders/debug_light_probe_spheres.dshl similarity index 90% rename from prog/gameLibs/render/shaders/debug_light_probe_spheres.sh rename to prog/gameLibs/render/shaders/debug_light_probe_spheres.dshl index 2e4a1f770..d63e9ac55 100644 --- a/prog/gameLibs/render/shaders/debug_light_probe_spheres.sh +++ b/prog/gameLibs/render/shaders/debug_light_probe_spheres.dshl @@ -1,8 +1,8 @@ -include "shader_global.sh" -include "gbuffer.sh" -include "viewVecVS.sh" -include "indoor_light_probes.sh" -include "fake_static_shadow.sh" +include "shader_global.dshl" +include "gbuffer.dshl" +include "viewVecVS.dshl" +include "indoor_light_probes.dshl" +include "fake_static_shadow.dshl" shader debug_mirror_sphere { diff --git a/prog/gameLibs/render/shaders/debug_line_twocolored.sh b/prog/gameLibs/render/shaders/debug_line_twocolored.dshl similarity index 96% rename from prog/gameLibs/render/shaders/debug_line_twocolored.sh rename to prog/gameLibs/render/shaders/debug_line_twocolored.dshl index 738ce80af..1d0b5818c 100644 --- a/prog/gameLibs/render/shaders/debug_line_twocolored.sh +++ b/prog/gameLibs/render/shaders/debug_line_twocolored.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "gbuffer.sh" +include "shader_global.dshl" +include "gbuffer.dshl" shader debug_line_twocolored { diff --git a/prog/gameLibs/render/shaders/debug_ri.sh b/prog/gameLibs/render/shaders/debug_ri.dshl similarity index 98% rename from prog/gameLibs/render/shaders/debug_ri.sh rename to prog/gameLibs/render/shaders/debug_ri.dshl index d86ac008a..81c39f255 100644 --- a/prog/gameLibs/render/shaders/debug_ri.sh +++ b/prog/gameLibs/render/shaders/debug_ri.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" shader debug_ri { diff --git a/prog/gameLibs/render/shaders/debug_ri_shaded.sh b/prog/gameLibs/render/shaders/debug_ri_shaded.dshl similarity index 99% rename from prog/gameLibs/render/shaders/debug_ri_shaded.sh rename to prog/gameLibs/render/shaders/debug_ri_shaded.dshl index 11f836b73..d3f598abd 100644 --- a/prog/gameLibs/render/shaders/debug_ri_shaded.sh +++ b/prog/gameLibs/render/shaders/debug_ri_shaded.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" texture debug_triplanar_tex; int debug_triplanar_tex_size; diff --git a/prog/gameLibs/render/shaders/debug_tex_overlay.sh b/prog/gameLibs/render/shaders/debug_tex_overlay.dshl similarity index 99% rename from prog/gameLibs/render/shaders/debug_tex_overlay.sh rename to prog/gameLibs/render/shaders/debug_tex_overlay.dshl index 34b894f8d..815dbbb64 100644 --- a/prog/gameLibs/render/shaders/debug_tex_overlay.sh +++ b/prog/gameLibs/render/shaders/debug_tex_overlay.dshl @@ -1,5 +1,5 @@ -include "postfx_inc.sh" -include "shader_global.sh" +include "postfx_inc.dshl" +include "shader_global.dshl" int swizzled_texture_type = 0; interval swizzled_texture_type : swizzled_texture_2d < 1, swizzled_texture_cube < 2, swizzled_texture_array < 3, swizzled_texture_3d < 4, swizzled_texture_2d_depth < 5, swizzled_texture_cube_array; diff --git a/prog/gameLibs/render/shaders/debug_tonemap_overlay.sh b/prog/gameLibs/render/shaders/debug_tonemap_overlay.dshl similarity index 94% rename from prog/gameLibs/render/shaders/debug_tonemap_overlay.sh rename to prog/gameLibs/render/shaders/debug_tonemap_overlay.dshl index ed9f873f6..3f46d1c16 100644 --- a/prog/gameLibs/render/shaders/debug_tonemap_overlay.sh +++ b/prog/gameLibs/render/shaders/debug_tonemap_overlay.dshl @@ -1,6 +1,6 @@ -include "postfx_inc.sh" -include "shader_global.sh" -include "tonemapHelpers/use_full_tonemap_lut_inc.sh" +include "postfx_inc.dshl" +include "shader_global.dshl" +include "tonemapHelpers/use_full_tonemap_lut_inc.dshl" float4 tonemap_render_size; float4 tonemap_debug_color; diff --git a/prog/gameLibs/render/shaders/debug_vbuffer_lines.sh b/prog/gameLibs/render/shaders/debug_vbuffer_lines.dshl similarity index 96% rename from prog/gameLibs/render/shaders/debug_vbuffer_lines.sh rename to prog/gameLibs/render/shaders/debug_vbuffer_lines.dshl index 0d2509cf6..a063e2fdc 100644 --- a/prog/gameLibs/render/shaders/debug_vbuffer_lines.sh +++ b/prog/gameLibs/render/shaders/debug_vbuffer_lines.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" float4 debug_line_color = (1, 1, 1, 1); shader debug_shader diff --git a/prog/gameLibs/render/shaders/decals/decals.sh b/prog/gameLibs/render/shaders/decals/decals.dshl similarity index 100% rename from prog/gameLibs/render/shaders/decals/decals.sh rename to prog/gameLibs/render/shaders/decals/decals.dshl diff --git a/prog/gameLibs/render/shaders/decals/dynamic_decals_inc.sh b/prog/gameLibs/render/shaders/decals/dynamic_decals_inc.dshl similarity index 99% rename from prog/gameLibs/render/shaders/decals/dynamic_decals_inc.sh rename to prog/gameLibs/render/shaders/decals/dynamic_decals_inc.dshl index 72fefa41c..f3efb18b1 100644 --- a/prog/gameLibs/render/shaders/decals/dynamic_decals_inc.sh +++ b/prog/gameLibs/render/shaders/decals/dynamic_decals_inc.dshl @@ -1,4 +1,4 @@ -include "decals.sh" +include "decals.dshl" texture dyn_decals_noise; diff --git a/prog/gameLibs/render/shaders/deferred_snow_cover.sh b/prog/gameLibs/render/shaders/deferred_snow_cover.dshl similarity index 99% rename from prog/gameLibs/render/shaders/deferred_snow_cover.sh rename to prog/gameLibs/render/shaders/deferred_snow_cover.dshl index 91c9478b3..03f133369 100644 --- a/prog/gameLibs/render/shaders/deferred_snow_cover.sh +++ b/prog/gameLibs/render/shaders/deferred_snow_cover.dshl @@ -1,4 +1,4 @@ -include "sparkles.sh" +include "sparkles.dshl" float4 envi_cover_albedo = (0.8, 0.98, 1.000, 0.000); float4 envi_cover_specular_color = (0.500, 0.500, 0.500, 0.000); diff --git a/prog/gameLibs/render/shaders/depth_above.sh b/prog/gameLibs/render/shaders/depth_above.dshl similarity index 58% rename from prog/gameLibs/render/shaders/depth_above.sh rename to prog/gameLibs/render/shaders/depth_above.dshl index 3e3872418..d8abd99c0 100644 --- a/prog/gameLibs/render/shaders/depth_above.sh +++ b/prog/gameLibs/render/shaders/depth_above.dshl @@ -7,6 +7,10 @@ float4 world_to_depth_ao; float4 depth_ao_heights; float depth_ao_height_scale = 1; +int depth_ao_extra_enabled = 0; +float4 world_to_depth_ao_extra; +float4 depth_ao_heights_extra; + float depth_ao_texture_size; float depth_ao_texture_rcp_size; @@ -15,11 +19,14 @@ macro INIT_BLURRED_DEPTH_ABOVE_CONSTS(code) world_to_depth_ao@f4 = world_to_depth_ao; depth_ao_heights@f4 = depth_ao_heights; depth_ao_texture_sizes@f2 = (depth_ao_texture_size, depth_ao_texture_rcp_size, 0, 0); + depth_ao_extra_enabled@i1 = depth_ao_extra_enabled; + world_to_depth_ao_extra@f4 = world_to_depth_ao_extra; + depth_ao_heights_extra@f4 = depth_ao_heights_extra; } endmacro macro INIT_DEPTH_ABOVE(code, tex) - (code) {tex@smp2d = tex;} + (code) {tex@smpArray = tex;} INIT_BLURRED_DEPTH_ABOVE_CONSTS(code) endmacro @@ -28,7 +35,7 @@ macro INIT_BLURRED_DEPTH_ABOVE(code) endmacro macro INIT_DEPTH_ABOVE_WITHOUT_SAMPLER(code, tex_name, tex_samplerstate, samplerstate) - (code) { tex_name@tex = tex_name hlsl { Texture2D tex_name@tex; } } + (code) { tex_name@texArray = tex_name; } hlsl(code) { #define tex_samplerstate samplerstate } @@ -40,14 +47,26 @@ macro INIT_BLURRED_DEPTH_ABOVE_WITHOUT_SAMPLER(code, samplerstate) endmacro macro USE_DEPTH_ABOVE_TC(code) - hlsl(code){ - - float2 getWorldBlurredDepthTC(float3 worldPos, out float vignette_effect) + hlsl(code) { + float applyVignette(float2 tc) { - float2 tc = saturate(world_to_depth_ao.xy*worldPos.xz + world_to_depth_ao.zw); - float2 vignette = saturate( abs(tc*2-1) * 10 - 9 ); - vignette_effect = saturate(dot( vignette, vignette )); - return tc - depth_ao_heights.zw; + float2 vignette = saturate(abs(tc * 2 - 1) * 10 - 9); + return saturate(dot(vignette, vignette)); + } + float3 getWorldBlurredDepthTC(float3 worldPos, out float vignette_effect) + { + float2 uncappedTc = world_to_depth_ao.xy * worldPos.xz + world_to_depth_ao.zw; + float2 cappedTc = saturate(uncappedTc); + float3 tcOffset = float3(-depth_ao_heights.zw, 0); + + if (depth_ao_extra_enabled > 0 && any(cappedTc != uncappedTc)) + { + cappedTc = saturate(world_to_depth_ao_extra.xy * worldPos.xz + world_to_depth_ao_extra.zw); + tcOffset = float3(-depth_ao_heights_extra.zw, 1); + } + + vignette_effect = applyVignette(cappedTc); + return float3(cappedTc, 0) + tcOffset; } float decode_depth_above(float depthHt) { @@ -63,21 +82,46 @@ endmacro macro USE_DEPTH_ABOVE(code, tex) USE_DEPTH_ABOVE_TC(code) hlsl(code){ + + float sample_blurred_depth(float3 tc, int2 offset) + { + return textureLodOffset(tex, tc, 0, offset).x; + } + + float getWorldBlurredDepthPrecise(float3 worldPos, out float vignette_effect) + { + float3 tc = getWorldBlurredDepthTC(worldPos, vignette_effect); + + float2 cornerIdF = tc.xy * depth_ao_texture_sizes.xx - 0.5; + float3 cornerTc = float3(floor(cornerIdF) * depth_ao_texture_sizes.yy, tc.z); + float2 fract = frac(cornerIdF); + + float4 height4; + height4.w = sample_blurred_depth(cornerTc, int2(0,0)); + height4.z = sample_blurred_depth(cornerTc, int2(1,0)); + height4.y = sample_blurred_depth(cornerTc, int2(1,1)); + height4.x = sample_blurred_depth(cornerTc, int2(0,1)); + + float2 height2 = lerp(height4.wx, height4.zy, fract.x); + float height = lerp(height2.x, height2.y, fract.y); + return decode_depth_above(height); + } + float getWorldBlurredDepth(float3 worldPos, out float vignette_effect) { - float2 tc = getWorldBlurredDepthTC(worldPos, vignette_effect); - return decode_depth_above(tex2Dlod(tex, float4(tc,0,0) ).x); + float3 tc = getWorldBlurredDepthTC(worldPos, vignette_effect); + return decode_depth_above(tex3Dlod(tex, float4(tc, 0)).x); } float4 gatherWorldBlurredDepth(float3 worldPos, out float vignette_effect, out float2 lerp_factor) { - float2 tc = getWorldBlurredDepthTC(worldPos, vignette_effect); + float3 tc = getWorldBlurredDepthTC(worldPos, vignette_effect); - tc = frac(tc); //to emulate wrap addressing - float2 coordF = tc * depth_ao_texture_sizes.xx - 0.5; + tc.xy = frac(tc.xy); //to emulate wrap addressing + float2 coordF = tc.xy * depth_ao_texture_sizes.xx - 0.5; lerp_factor = frac(coordF); float2 centerTc = (floor(coordF) + 1.0) * depth_ao_texture_sizes.yy; - return decode_depth_above4(textureGather(tex, centerTc)); + return decode_depth_above4(textureGather(tex, float3(centerTc, tc.z))); } float lerpGatheredBlurredDepth(float4 depth_samples, float2 lerp_factor) { diff --git a/prog/gameLibs/render/shaders/depth_above_blur.sh b/prog/gameLibs/render/shaders/depth_above_blur.dshl similarity index 81% rename from prog/gameLibs/render/shaders/depth_above_blur.sh rename to prog/gameLibs/render/shaders/depth_above_blur.dshl index 8d9264f26..fe6b62dfd 100644 --- a/prog/gameLibs/render/shaders/depth_above_blur.sh +++ b/prog/gameLibs/render/shaders/depth_above_blur.dshl @@ -1,7 +1,8 @@ -include "sky_shader_global.sh" +include "sky_shader_global.dshl" texture depth_ao_tex_to_blur; float depth_ao_texture_rcp_size; +int depth_above_blur_layer = 0; shader single_pass_blur11 { @@ -44,7 +45,8 @@ shader single_pass_blur11 } (ps) { - tex0@smp2d = depth_ao_tex_to_blur; + tex0@smpArray = depth_ao_tex_to_blur; + blur_layer@i1 = depth_above_blur_layer; ofs@f1 = (depth_ao_texture_rcp_size, 0, 0, 0); } @@ -69,8 +71,8 @@ shader single_pass_blur11 for( int i = 0; i < stepCount; i++ ) { float2 texCoordOffset = gOffsets[i] * pixelOffset; - out_type col = tex2Dlod(tex0, float4(clamp(centreUV + texCoordOffset, clampTc.xz, clampTc.yw), 0,0)).x + - tex2Dlod(tex0, float4(clamp(centreUV - texCoordOffset, clampTc.xz, clampTc.yw),0,0)).x; + out_type col = tex3Dlod(tex0, float4(clamp(centreUV + texCoordOffset, clampTc.xz, clampTc.yw), blur_layer, 0)).x + + tex3Dlod(tex0, float4(clamp(centreUV - texCoordOffset, clampTc.xz, clampTc.yw), blur_layer, 0)).x; colOut += gWeights[i] * col; } #elif stepCount == 4 @@ -82,7 +84,7 @@ shader single_pass_blur11 for( int i = 0; i < stepCount; i++ ) { float2 texCoordOffset = gOffsets[i] * pixelOffset; - out_type col = tex2Dlod(tex0, float4(centreUV + texCoordOffset,0,0)).x + tex2Dlod(tex0, float4(centreUV - texCoordOffset,0,0)).x; + out_type col = tex3Dlod(tex0, float4(centreUV + texCoordOffset, blur_layer, 0)).x + tex3Dlod(tex0, float4(centreUV - texCoordOffset, blur_layer, 0)).x; colOut += gWeights[i] * col; } #elif stepCount == 9 @@ -94,7 +96,7 @@ shader single_pass_blur11 for( int i = 0; i < stepCount; i++ ) { float2 texCoordOffset = gOffsets[i] * pixelOffset; - out_type col = tex2Dlod(tex0, float4(centreUV + texCoordOffset,0,0)).x + tex2Dlod(tex0, float4(centreUV - texCoordOffset,0,0)).x; + out_type col = tex3Dlod(tex0, float4(centreUV + texCoordOffset, blur_layer, 0)).x + tex3Dlod(tex0, float4(centreUV - texCoordOffset, blur_layer, 0)).x; colOut += gWeights[i] * col; } #endif diff --git a/prog/gameLibs/render/shaders/depth_above_copy.sh b/prog/gameLibs/render/shaders/depth_above_copy.dshl similarity index 53% rename from prog/gameLibs/render/shaders/depth_above_copy.sh rename to prog/gameLibs/render/shaders/depth_above_copy.dshl index 10a30a1a8..ffa55e2ce 100644 --- a/prog/gameLibs/render/shaders/depth_above_copy.sh +++ b/prog/gameLibs/render/shaders/depth_above_copy.dshl @@ -1,8 +1,9 @@ -include "shader_global.sh" -include "depth_above.sh" -include "postfx_inc.sh" +include "shader_global.dshl" +include "depth_above.dshl" +include "postfx_inc.dshl" float4 depth_above_copy_region; +int depth_above_copy_layer = 0; shader depth_above_copy_regions { @@ -13,7 +14,8 @@ shader depth_above_copy_regions no_ablend; (ps) { - depth_above@smp2d = depth_around; + depth_above@smpArray = depth_around; + copy_layer@i1 = depth_above_copy_layer; } POSTFX_VS(0) @@ -22,7 +24,7 @@ shader depth_above_copy_regions hlsl(ps) { float main_ps(VsOutput input) : SV_Depth { - return texelFetch(depth_above, input.pos.xy, 0).x; + return texelFetch(depth_above, int3(input.pos.xy, copy_layer), 0).x; } } compile("target_ps", "main_ps"); diff --git a/prog/gameLibs/render/shaders/depth_hierarchy.sh b/prog/gameLibs/render/shaders/depth_hierarchy.dshl similarity index 99% rename from prog/gameLibs/render/shaders/depth_hierarchy.sh rename to prog/gameLibs/render/shaders/depth_hierarchy.dshl index 55ee91abf..d0b83d111 100644 --- a/prog/gameLibs/render/shaders/depth_hierarchy.sh +++ b/prog/gameLibs/render/shaders/depth_hierarchy.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" int downsample_op = 0; interval downsample_op: mip_min<1, mip_max; diff --git a/prog/gameLibs/render/shaders/dof/dof.sh b/prog/gameLibs/render/shaders/dof/dof.dshl similarity index 99% rename from prog/gameLibs/render/shaders/dof/dof.sh rename to prog/gameLibs/render/shaders/dof/dof.dshl index 67d90ed28..e6830880a 100644 --- a/prog/gameLibs/render/shaders/dof/dof.sh +++ b/prog/gameLibs/render/shaders/dof/dof.dshl @@ -1,10 +1,10 @@ -include "shader_global.sh" -include "gbuffer.sh" -include "reprojected_motion_vectors.sh" -include "viewVecVS.sh" -include "dof/dof_composite.sh" +include "shader_global.dshl" +include "gbuffer.dshl" +include "reprojected_motion_vectors.dshl" +include "viewVecVS.dshl" +include "dof/dof_composite.dshl" -//include "dacloud_mask.sh" +//include "dacloud_mask.dshl" float4 prevViewProjTm0; float4 prevViewProjTm1; diff --git a/prog/gameLibs/render/shaders/dof/dof_composite.sh b/prog/gameLibs/render/shaders/dof/dof_composite.dshl similarity index 100% rename from prog/gameLibs/render/shaders/dof/dof_composite.sh rename to prog/gameLibs/render/shaders/dof/dof_composite.dshl diff --git a/prog/gameLibs/render/shaders/downsampleDepth.sh b/prog/gameLibs/render/shaders/downsampleDepth.dshl similarity index 99% rename from prog/gameLibs/render/shaders/downsampleDepth.sh rename to prog/gameLibs/render/shaders/downsampleDepth.dshl index 1c25631c3..019f039d3 100644 --- a/prog/gameLibs/render/shaders/downsampleDepth.sh +++ b/prog/gameLibs/render/shaders/downsampleDepth.dshl @@ -1,6 +1,6 @@ -include "shader_global.sh" -include "gbuffer.sh" -include "taa_inc.sh" +include "shader_global.dshl" +include "gbuffer.dshl" +include "taa_inc.dshl" float4 downsample_from = (1280, 720,0,0); float4 downsample_to = (1280, 720,0,0); diff --git a/prog/gameLibs/render/shaders/dynamic_lights_count.sh b/prog/gameLibs/render/shaders/dynamic_lights_count.dshl similarity index 100% rename from prog/gameLibs/render/shaders/dynamic_lights_count.sh rename to prog/gameLibs/render/shaders/dynamic_lights_count.dshl diff --git a/prog/gameLibs/render/shaders/emissive/emission_anim_inc.sh b/prog/gameLibs/render/shaders/emissive/emission_anim_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/emissive/emission_anim_inc.sh rename to prog/gameLibs/render/shaders/emissive/emission_anim_inc.dshl diff --git a/prog/gameLibs/render/shaders/esm_ao.sh b/prog/gameLibs/render/shaders/esm_ao.dshl similarity index 97% rename from prog/gameLibs/render/shaders/esm_ao.sh rename to prog/gameLibs/render/shaders/esm_ao.dshl index 7860620a6..0fa68d623 100644 --- a/prog/gameLibs/render/shaders/esm_ao.sh +++ b/prog/gameLibs/render/shaders/esm_ao.dshl @@ -1,7 +1,7 @@ -include "shader_global.sh" -include "dynamic_simple_inc.sh" -include "gbuffer.sh" -include "esm_shadows_inc.sh" +include "shader_global.dshl" +include "dynamic_simple_inc.dshl" +include "gbuffer.dshl" +include "esm_shadows_inc.dshl" buffer esm_ao_decals; texture esm_shadows; diff --git a/prog/gameLibs/render/shaders/esm_shadows.sh b/prog/gameLibs/render/shaders/esm_shadows.dshl similarity index 94% rename from prog/gameLibs/render/shaders/esm_shadows.sh rename to prog/gameLibs/render/shaders/esm_shadows.dshl index 0f26af47c..b62e86895 100644 --- a/prog/gameLibs/render/shaders/esm_shadows.sh +++ b/prog/gameLibs/render/shaders/esm_shadows.dshl @@ -1,7 +1,7 @@ -include "shader_global.sh" -include "esm_shadows_inc.sh" -include "postfx_inc.sh" -include "gaussian_blur.sh" +include "shader_global.dshl" +include "esm_shadows_inc.dshl" +include "postfx_inc.dshl" +include "gaussian_blur.dshl" int esm_slice = 0; int gauss_direction = 0; diff --git a/prog/gameLibs/render/shaders/esm_shadows_inc.sh b/prog/gameLibs/render/shaders/esm_shadows_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/esm_shadows_inc.sh rename to prog/gameLibs/render/shaders/esm_shadows_inc.dshl diff --git a/prog/gameLibs/render/shaders/etc2_compression.sh b/prog/gameLibs/render/shaders/etc2_compression.dshl similarity index 95% rename from prog/gameLibs/render/shaders/etc2_compression.sh rename to prog/gameLibs/render/shaders/etc2_compression.dshl index ab6117b4f..b3f263723 100644 --- a/prog/gameLibs/render/shaders/etc2_compression.sh +++ b/prog/gameLibs/render/shaders/etc2_compression.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "etc2_compression_inc.sh" +include "shader_global.dshl" +include "etc2_compression_inc.dshl" texture src_tex; float src_mip = 0; diff --git a/prog/gameLibs/render/shaders/etc2_compression_inc.sh b/prog/gameLibs/render/shaders/etc2_compression_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/etc2_compression_inc.sh rename to prog/gameLibs/render/shaders/etc2_compression_inc.dshl diff --git a/prog/gameLibs/render/shaders/find_max_depth_2d.sh b/prog/gameLibs/render/shaders/find_max_depth_2d.dshl similarity index 98% rename from prog/gameLibs/render/shaders/find_max_depth_2d.sh rename to prog/gameLibs/render/shaders/find_max_depth_2d.dshl index cba17e62d..62edd1767 100644 --- a/prog/gameLibs/render/shaders/find_max_depth_2d.sh +++ b/prog/gameLibs/render/shaders/find_max_depth_2d.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" float4 proj_values; diff --git a/prog/gameLibs/render/shaders/flare.sh b/prog/gameLibs/render/shaders/flare.dshl similarity index 99% rename from prog/gameLibs/render/shaders/flare.sh rename to prog/gameLibs/render/shaders/flare.dshl index 984ec1b9d..ecc771e83 100644 --- a/prog/gameLibs/render/shaders/flare.sh +++ b/prog/gameLibs/render/shaders/flare.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" // tweak float flare_scale = 0.2; diff --git a/prog/gameLibs/render/shaders/flare_inc.sh b/prog/gameLibs/render/shaders/flare_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/flare_inc.sh rename to prog/gameLibs/render/shaders/flare_inc.dshl diff --git a/prog/gameLibs/render/shaders/flexible_scale_rasterization.sh b/prog/gameLibs/render/shaders/flexible_scale_rasterization.dshl similarity index 100% rename from prog/gameLibs/render/shaders/flexible_scale_rasterization.sh rename to prog/gameLibs/render/shaders/flexible_scale_rasterization.dshl diff --git a/prog/gameLibs/render/shaders/flow_map.sh b/prog/gameLibs/render/shaders/flow_map.dshl similarity index 81% rename from prog/gameLibs/render/shaders/flow_map.sh rename to prog/gameLibs/render/shaders/flow_map.dshl index ba81cfb4c..61513aeb8 100644 --- a/prog/gameLibs/render/shaders/flow_map.sh +++ b/prog/gameLibs/render/shaders/flow_map.dshl @@ -1,13 +1,13 @@ -include "shader_global.sh" -include "snoise.sh" -include "water_heightmap.sh" -include "depth_above.sh" +include "shader_global.dshl" +include "snoise.dshl" +include "water_heightmap.dshl" +include "depth_above.dshl" texture flowmap_temp_tex; int flowmap_texture_size = 1024; float flowmap_texture_size_meters = 200; texture flowmap_heightmap_tex; -int height_texture_size = 1024; +int flowmap_heightmap_texture_size = 1024; float4 flowmap_heightmap_min_max = (0, 0, 0, 0); texture flowmap_floodfill_tex; float wind_dir_x = 0.6; @@ -59,11 +59,11 @@ shader water_flowmap (ps) { flowmap_temp_tex@smp2d = flowmap_temp_tex; wind_dir_dir_scale_water_flowmap_slope@f4 = (wind_dir_x, wind_dir_y, dir_scale*flowmap_texture_size/flowmap_texture_size_meters, water_flowmap_slope); - height_texture_size@f4 = (1.0/height_texture_size, height_texture_size, 1./flowmap_texture_size, flowmap_texture_size); + flowmap_texture_size@f4 = (1.0/flowmap_heightmap_texture_size, flowmap_heightmap_texture_size, 1./flowmap_texture_size, flowmap_texture_size); flowmap_heightmap_tex@smp2d = flowmap_heightmap_tex; flowmap_heightmap_min_max@f4 = flowmap_heightmap_min_max; flowmap_floodfill_tex@smp2d = flowmap_floodfill_tex; - waterLevel_radius_flowmap_damping@f4 = (water_level, height_texture_size/flowmap_texture_size+2, height_texture_size/flowmap_texture_size, flowmap_damping); + waterLevel_radius_flowmap_damping@f4 = (water_level, flowmap_heightmap_texture_size/flowmap_texture_size+2, flowmap_heightmap_texture_size/flowmap_texture_size, flowmap_damping); world_to_flowmap_prev@f4 = world_to_flowmap_prev; world_to_flowmap_heightmap@f4 = world_to_flowmap_heightmap; flowmap_add_to_world@f4 = (1.0/world_to_flowmap_add.x, 1.0/world_to_flowmap_add.y, -world_to_flowmap_add.z/world_to_flowmap_add.x, -world_to_flowmap_add.w/world_to_flowmap_add.y); @@ -98,15 +98,15 @@ shader water_flowmap float2 worldPos = tc*flowmap_add_to_world.xy+flowmap_add_to_world.zw; float2 ftc = worldPos*world_to_flowmap_prev.xy+world_to_flowmap_prev.zw; float2 htc = worldPos*world_to_flowmap_heightmap.xy+world_to_flowmap_heightmap.zw; - htc = floor(htc*height_texture_size.y)*height_texture_size.x; + htc = floor(htc*flowmap_texture_size.y)*flowmap_texture_size.x; float4 f = tex2Dlod(flowmap_temp_tex, float4(ftc,0,0)); - float4 l = tex2Dlod(flowmap_temp_tex, float4(ftc.x-height_texture_size.z,ftc.y,0,0)); - float4 r = tex2Dlod(flowmap_temp_tex, float4(ftc.x+height_texture_size.z,ftc.y,0,0)); - float4 u = tex2Dlod(flowmap_temp_tex, float4(ftc.x,ftc.y-height_texture_size.z,0,0)); - float4 d = tex2Dlod(flowmap_temp_tex, float4(ftc.x,ftc.y+height_texture_size.z,0,0)); + float4 l = tex2Dlod(flowmap_temp_tex, float4(ftc.x-flowmap_texture_size.z,ftc.y,0,0)); + float4 r = tex2Dlod(flowmap_temp_tex, float4(ftc.x+flowmap_texture_size.z,ftc.y,0,0)); + float4 u = tex2Dlod(flowmap_temp_tex, float4(ftc.x,ftc.y-flowmap_texture_size.z,0,0)); + float4 d = tex2Dlod(flowmap_temp_tex, float4(ftc.x,ftc.y+flowmap_texture_size.z,0,0)); - f = tex2Dlod(flowmap_temp_tex, float4(ftc-f.xy*height_texture_size.z,0,0)); + f = tex2Dlod(flowmap_temp_tex, float4(ftc-f.xy*flowmap_texture_size.z,0,0)); f *= flowmap_damping; f.x += (l.w-r.w)*0.5; @@ -128,7 +128,7 @@ shader water_flowmap float waterDepth = abs(waterHeight - h); bool isUp = h > waterHeight ? 1 : 0; - bool isBorder = any(abs(tc*2-1)>1-height_texture_size.z*2); + bool isBorder = any(abs(tc*2-1)>1-flowmap_texture_size.z*2); if (isUp || isBorder) f = 0; @@ -163,10 +163,10 @@ shader water_flowmap ##if flowmap_floodfill_tex != NULL f.xy = (l.xy + r.xy + u.xy + d.xy) * 0.25; float4 heightNeighbours = h; - heightNeighbours.x = tex2Dlod(flowmap_heightmap_tex, float4(htc.x - height_texture_size.x, htc.y, 0, 0)).r * flowmap_heightmap_min_max.z + flowmap_heightmap_min_max.w; - heightNeighbours.y = tex2Dlod(flowmap_heightmap_tex, float4(htc.x + height_texture_size.x, htc.y, 0, 0)).r * flowmap_heightmap_min_max.z + flowmap_heightmap_min_max.w; - heightNeighbours.z = tex2Dlod(flowmap_heightmap_tex, float4(htc.x, htc.y - height_texture_size.x, 0, 0)).r * flowmap_heightmap_min_max.z + flowmap_heightmap_min_max.w; - heightNeighbours.w = tex2Dlod(flowmap_heightmap_tex, float4(htc.x, htc.y + height_texture_size.x, 0, 0)).r * flowmap_heightmap_min_max.z + flowmap_heightmap_min_max.w; + heightNeighbours.x = tex2Dlod(flowmap_heightmap_tex, float4(htc.x - flowmap_texture_size.x, htc.y, 0, 0)).r * flowmap_heightmap_min_max.z + flowmap_heightmap_min_max.w; + heightNeighbours.y = tex2Dlod(flowmap_heightmap_tex, float4(htc.x + flowmap_texture_size.x, htc.y, 0, 0)).r * flowmap_heightmap_min_max.z + flowmap_heightmap_min_max.w; + heightNeighbours.z = tex2Dlod(flowmap_heightmap_tex, float4(htc.x, htc.y - flowmap_texture_size.x, 0, 0)).r * flowmap_heightmap_min_max.z + flowmap_heightmap_min_max.w; + heightNeighbours.w = tex2Dlod(flowmap_heightmap_tex, float4(htc.x, htc.y + flowmap_texture_size.x, 0, 0)).r * flowmap_heightmap_min_max.z + flowmap_heightmap_min_max.w; if (any(heightNeighbours > waterHeight)) { float2 heightGradient = float2(heightNeighbours.w - heightNeighbours.z, heightNeighbours.x - heightNeighbours.y); @@ -174,6 +174,7 @@ shader water_flowmap { heightGradient = normalize(heightGradient); float2 floodfillVec = tex2Dlod(flowmap_floodfill_tex, float4(htc,0,0)).rg * 2 - 1; + floodfillVec *= sign(0.5 - frac(htc.yx * 0.5)); // flipped in the opposite dimension to the heightmap mirroring heightGradient *= heightGradient.x * floodfillVec.x + heightGradient.y * floodfillVec.y; f.xy += heightGradient; } diff --git a/prog/gameLibs/render/shaders/flow_map_inc.sh b/prog/gameLibs/render/shaders/flow_map_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/flow_map_inc.sh rename to prog/gameLibs/render/shaders/flow_map_inc.dshl diff --git a/prog/gameLibs/render/shaders/foam/foam.sh b/prog/gameLibs/render/shaders/foam/foam.dshl similarity index 99% rename from prog/gameLibs/render/shaders/foam/foam.sh rename to prog/gameLibs/render/shaders/foam/foam.dshl index 7fb9ead91..ba4f9dbf3 100644 --- a/prog/gameLibs/render/shaders/foam/foam.sh +++ b/prog/gameLibs/render/shaders/foam/foam.dshl @@ -1,7 +1,7 @@ -include "shader_global.sh" -include "invGlobTm.sh" -include "waveWorks.sh" -include "gaussian_blur.sh" +include "shader_global.dshl" +include "invGlobTm.dshl" +include "waveWorks.dshl" +include "gaussian_blur.dshl" texture foam_mask; texture foam_mask_depth; diff --git a/prog/gameLibs/render/shaders/foliage_a2c_inc.sh b/prog/gameLibs/render/shaders/foliage_a2c_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/foliage_a2c_inc.sh rename to prog/gameLibs/render/shaders/foliage_a2c_inc.dshl diff --git a/prog/gameLibs/render/shaders/fom_shadows.sh b/prog/gameLibs/render/shaders/fom_shadows.dshl similarity index 100% rename from prog/gameLibs/render/shaders/fom_shadows.sh rename to prog/gameLibs/render/shaders/fom_shadows.dshl diff --git a/prog/gameLibs/render/shaders/force_ignore_history.sh b/prog/gameLibs/render/shaders/force_ignore_history.dshl similarity index 100% rename from prog/gameLibs/render/shaders/force_ignore_history.sh rename to prog/gameLibs/render/shaders/force_ignore_history.dshl diff --git a/prog/gameLibs/render/shaders/frustum.sh b/prog/gameLibs/render/shaders/frustum.dshl similarity index 100% rename from prog/gameLibs/render/shaders/frustum.sh rename to prog/gameLibs/render/shaders/frustum.dshl diff --git a/prog/gameLibs/render/shaders/gaussian_blur.sh b/prog/gameLibs/render/shaders/gaussian_blur.dshl similarity index 100% rename from prog/gameLibs/render/shaders/gaussian_blur.sh rename to prog/gameLibs/render/shaders/gaussian_blur.dshl diff --git a/prog/gameLibs/render/shaders/gbuffer_to_temperature_inc.sh b/prog/gameLibs/render/shaders/gbuffer_to_temperature_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/gbuffer_to_temperature_inc.sh rename to prog/gameLibs/render/shaders/gbuffer_to_temperature_inc.dshl diff --git a/prog/gameLibs/render/shaders/get_additional_ao.sh b/prog/gameLibs/render/shaders/get_additional_ao.dshl similarity index 88% rename from prog/gameLibs/render/shaders/get_additional_ao.sh rename to prog/gameLibs/render/shaders/get_additional_ao.dshl index 686a4cbac..7db87a097 100644 --- a/prog/gameLibs/render/shaders/get_additional_ao.sh +++ b/prog/gameLibs/render/shaders/get_additional_ao.dshl @@ -1,7 +1,7 @@ -include "heightmap_common.sh" -include "depth_above.sh" -include "capsuledAO.sh" -include "dagi_quality.sh" +include "heightmap_common.dshl" +include "depth_above.dshl" +include "capsuledAO.dshl" +include "dagi_quality.dshl" texture esm_ao_target_tex; diff --git a/prog/gameLibs/render/shaders/get_additional_shadows.sh b/prog/gameLibs/render/shaders/get_additional_shadows.dshl similarity index 100% rename from prog/gameLibs/render/shaders/get_additional_shadows.sh rename to prog/gameLibs/render/shaders/get_additional_shadows.dshl diff --git a/prog/gameLibs/render/shaders/giHelpers/collision_render.sh b/prog/gameLibs/render/shaders/giHelpers/collision_render.dshl similarity index 93% rename from prog/gameLibs/render/shaders/giHelpers/collision_render.sh rename to prog/gameLibs/render/shaders/giHelpers/collision_render.dshl index 54d7da078..6ebc06c54 100644 --- a/prog/gameLibs/render/shaders/giHelpers/collision_render.sh +++ b/prog/gameLibs/render/shaders/giHelpers/collision_render.dshl @@ -1,9 +1,9 @@ -include "shader_global.sh" -include "gbuffer.sh" -include "postfx_inc.sh" -include "viewVecVS.sh" -include "globtm.sh" -include "giHelpers/common_collision_render.sh" +include "shader_global.dshl" +include "gbuffer.dshl" +include "postfx_inc.dshl" +include "viewVecVS.dshl" +include "globtm.dshl" +include "giHelpers/common_collision_render.dshl" shader render_collision { diff --git a/prog/gameLibs/render/shaders/giHelpers/common_collision_render.sh b/prog/gameLibs/render/shaders/giHelpers/common_collision_render.dshl similarity index 100% rename from prog/gameLibs/render/shaders/giHelpers/common_collision_render.sh rename to prog/gameLibs/render/shaders/giHelpers/common_collision_render.dshl diff --git a/prog/gameLibs/render/shaders/giHelpers/gi_voxelize_shaders.sh b/prog/gameLibs/render/shaders/giHelpers/gi_voxelize_shaders.dshl similarity index 98% rename from prog/gameLibs/render/shaders/giHelpers/gi_voxelize_shaders.sh rename to prog/gameLibs/render/shaders/giHelpers/gi_voxelize_shaders.dshl index de9d1e700..35605e882 100644 --- a/prog/gameLibs/render/shaders/giHelpers/gi_voxelize_shaders.sh +++ b/prog/gameLibs/render/shaders/giHelpers/gi_voxelize_shaders.dshl @@ -1,11 +1,11 @@ -include "shader_global.sh" -include "gi_initial_ambient.sh" -include "dagi_scene_common_write.sh" -include "dagi_scene_voxels_common_25d.sh" -include "giHelpers/trees_above_common.sh" -include "giHelpers/voxelize_gs.sh" -include "giHelpers/common_collision_render.sh" -include_optional "optional_walls_windows.sh" +include "shader_global.dshl" +include "gi_initial_ambient.dshl" +include "dagi_scene_common_write.dshl" +include "dagi_scene_voxels_common_25d.dshl" +include "giHelpers/trees_above_common.dshl" +include "giHelpers/voxelize_gs.dshl" +include "giHelpers/common_collision_render.dshl" +include_optional "optional_walls_windows.dshl" define_macro_if_not_defined OPTIONAL_SKIP_RAY_WINDOWS(code) SKIP_RAY_WINDOWS(code) diff --git a/prog/gameLibs/render/shaders/giHelpers/heightmap_25d.sh b/prog/gameLibs/render/shaders/giHelpers/heightmap_25d.dshl similarity index 96% rename from prog/gameLibs/render/shaders/giHelpers/heightmap_25d.sh rename to prog/gameLibs/render/shaders/giHelpers/heightmap_25d.dshl index e82c38f40..1e4768ba1 100644 --- a/prog/gameLibs/render/shaders/giHelpers/heightmap_25d.sh +++ b/prog/gameLibs/render/shaders/giHelpers/heightmap_25d.dshl @@ -1,5 +1,5 @@ -include "heightmap_common.sh" -include "clipmap_common.sh" +include "heightmap_common.dshl" +include "clipmap_common.dshl" macro USE_VOXELS_HEIGHTMAP_HEIGHT_25D(code) USE_HMAP_HOLES_ZONES(code) diff --git a/prog/gameLibs/render/shaders/giHelpers/initial_ambient.sh b/prog/gameLibs/render/shaders/giHelpers/initial_ambient.dshl similarity index 83% rename from prog/gameLibs/render/shaders/giHelpers/initial_ambient.sh rename to prog/gameLibs/render/shaders/giHelpers/initial_ambient.dshl index 7e5b9f3f6..f6a3ad318 100644 --- a/prog/gameLibs/render/shaders/giHelpers/initial_ambient.sh +++ b/prog/gameLibs/render/shaders/giHelpers/initial_ambient.dshl @@ -1,6 +1,6 @@ -include "depth_above.sh" -include "static_shadow.sh" -include "heightmap_common.sh" +include "depth_above.dshl" +include "static_shadow.dshl" +include "heightmap_common.dshl" macro INIT_INITIAL_GI_AMBIENT_LIGHTING_MODEL(code) INIT_STATIC_SHADOW_BASE(code) @@ -17,8 +17,8 @@ endmacro macro INIT_INITIAL_GI_WORLD_AO(code) (code) { - blurred_depth@smp2d = blurred_depth; - depth_above@smp2d = depth_around; + blurred_depth@smpArray = blurred_depth; + depth_above@smpArray = depth_around; } hlsl(code) { float getWorldBlurredAOInitial(float3 worldPos, float depthHt, float vignetteEffect, float height_bias, float height_scale) @@ -39,7 +39,7 @@ macro SSGI_CLEAR_INITIAL_VOLMAP() INIT_BLURRED_DEPTH_ABOVE_CONSTS(cs) USE_DEPTH_ABOVE_TC(cs) USE_HEIGHTMAP_COMMON(cs) - (cs) { blurred_depth_above@smp2d = blurred_depth; } + (cs) { blurred_depth_above@smpArray = blurred_depth; } hlsl(cs) { @@ -52,8 +52,8 @@ macro SSGI_CLEAR_INITIAL_VOLMAP() float darken = exp2(min(0, 4*invVoxelY*(worldPos.y+0.5*lightVoxelSize.y-htHeight))); { float vignette_effect; - float2 tc = getWorldBlurredDepthTC(worldPos, vignette_effect); - float htBlurred = decode_depth_above(tex2Dlod(blurred_depth_above, float4(tc,0,0) ).x); + float3 tc = getWorldBlurredDepthTC(worldPos, vignette_effect); + float htBlurred = decode_depth_above(tex3Dlod(blurred_depth_above, float4(tc, 0)).x); float ao = lerp(0, 1, saturate(1+0.5*invVoxelY*(worldPos.y-htBlurred))); darken = min(darken, lerp(ao, 1, vignette_effect)); } diff --git a/prog/gameLibs/render/shaders/giHelpers/light_helper_25d.sh b/prog/gameLibs/render/shaders/giHelpers/light_helper_25d.dshl similarity index 89% rename from prog/gameLibs/render/shaders/giHelpers/light_helper_25d.sh rename to prog/gameLibs/render/shaders/giHelpers/light_helper_25d.dshl index d2868e147..b5792ac62 100644 --- a/prog/gameLibs/render/shaders/giHelpers/light_helper_25d.sh +++ b/prog/gameLibs/render/shaders/giHelpers/light_helper_25d.dshl @@ -1,7 +1,7 @@ -include "clouds_vars.sh" -include "clouds_shadow.sh" -include "static_shadow.sh" -include "depth_above.sh" +include "clouds_vars.dshl" +include "clouds_shadow.dshl" +include "static_shadow.dshl" +include "depth_above.dshl" macro INIT_LIGHT_25D_HELPERS(code) supports global_const_block; diff --git a/prog/gameLibs/render/shaders/giHelpers/trees_above.sh b/prog/gameLibs/render/shaders/giHelpers/trees_above.dshl similarity index 89% rename from prog/gameLibs/render/shaders/giHelpers/trees_above.sh rename to prog/gameLibs/render/shaders/giHelpers/trees_above.dshl index 1a05334bd..75adce734 100644 --- a/prog/gameLibs/render/shaders/giHelpers/trees_above.sh +++ b/prog/gameLibs/render/shaders/giHelpers/trees_above.dshl @@ -1,8 +1,8 @@ -include "sky_shader_global.sh" -include "heightmap_common.sh" -include "dagi_scene_25d_common_write.sh" -include "giHelpers/voxelize_gs.sh" -include "giHelpers/trees_above_common.sh" +include "sky_shader_global.dshl" +include "heightmap_common.dshl" +include "dagi_scene_25d_common_write.dshl" +include "giHelpers/voxelize_gs.dshl" +include "giHelpers/trees_above_common.dshl" float4 scene_voxels_size; shader voxelize_trees_albedo diff --git a/prog/gameLibs/render/shaders/giHelpers/trees_above_common.sh b/prog/gameLibs/render/shaders/giHelpers/trees_above_common.dshl similarity index 97% rename from prog/gameLibs/render/shaders/giHelpers/trees_above_common.sh rename to prog/gameLibs/render/shaders/giHelpers/trees_above_common.dshl index 9f8bb1f70..713dcba9f 100644 --- a/prog/gameLibs/render/shaders/giHelpers/trees_above_common.sh +++ b/prog/gameLibs/render/shaders/giHelpers/trees_above_common.dshl @@ -1,4 +1,4 @@ -include "heightmap_common.sh" +include "heightmap_common.dshl" texture trees2d; texture trees2d_depth; float4 world_to_trees_tex_mul; diff --git a/prog/gameLibs/render/shaders/giHelpers/voxelize_gs.sh b/prog/gameLibs/render/shaders/giHelpers/voxelize_gs.dshl similarity index 100% rename from prog/gameLibs/render/shaders/giHelpers/voxelize_gs.sh rename to prog/gameLibs/render/shaders/giHelpers/voxelize_gs.dshl diff --git a/prog/gameLibs/render/shaders/gi_demo.sh b/prog/gameLibs/render/shaders/gi_demo.dshl similarity index 100% rename from prog/gameLibs/render/shaders/gi_demo.sh rename to prog/gameLibs/render/shaders/gi_demo.dshl diff --git a/prog/gameLibs/render/shaders/globe_model.sh b/prog/gameLibs/render/shaders/globe_model.dshl similarity index 99% rename from prog/gameLibs/render/shaders/globe_model.sh rename to prog/gameLibs/render/shaders/globe_model.dshl index d1c1ac7e8..2a8db7fd4 100644 --- a/prog/gameLibs/render/shaders/globe_model.sh +++ b/prog/gameLibs/render/shaders/globe_model.dshl @@ -1,10 +1,10 @@ -include "sky_shader_global.sh" -include "brunetonSkies.sh" -include "viewVecVS.sh" -include "gbuffer.sh" -include "psh_tangent.sh" -include "globe_model_inc.sh" -include "csm.sh" +include "sky_shader_global.dshl" +include "brunetonSkies.dshl" +include "viewVecVS.dshl" +include "gbuffer.dshl" +include "psh_tangent.dshl" +include "globe_model_inc.dshl" +include "csm.dshl" texture globe_color_tex; texture globe_normals_tex; diff --git a/prog/gameLibs/render/shaders/globe_model_inc.sh b/prog/gameLibs/render/shaders/globe_model_inc.dshl similarity index 95% rename from prog/gameLibs/render/shaders/globe_model_inc.sh rename to prog/gameLibs/render/shaders/globe_model_inc.dshl index 9f96355d4..e0802241c 100644 --- a/prog/gameLibs/render/shaders/globe_model_inc.sh +++ b/prog/gameLibs/render/shaders/globe_model_inc.dshl @@ -1,5 +1,5 @@ -include "pbr.sh" -include "fake_static_shadow.sh" +include "pbr.dshl" +include "fake_static_shadow.dshl" texture perlin_noise3d; diff --git a/prog/gameLibs/render/shaders/globtm.sh b/prog/gameLibs/render/shaders/globtm.dshl similarity index 100% rename from prog/gameLibs/render/shaders/globtm.sh rename to prog/gameLibs/render/shaders/globtm.dshl diff --git a/prog/gameLibs/render/shaders/gpu_benchmark.sh b/prog/gameLibs/render/shaders/gpu_benchmark.dshl similarity index 98% rename from prog/gameLibs/render/shaders/gpu_benchmark.sh rename to prog/gameLibs/render/shaders/gpu_benchmark.dshl index 120c0b499..755b95e37 100644 --- a/prog/gameLibs/render/shaders/gpu_benchmark.sh +++ b/prog/gameLibs/render/shaders/gpu_benchmark.dshl @@ -1,4 +1,4 @@ -include "hardware_defines.sh" +include "hardware_defines.dshl" texture gpu_benchmark_tex; diff --git a/prog/gameLibs/render/shaders/gpu_objects_placer.sh b/prog/gameLibs/render/shaders/gpu_objects_placer.dshl similarity index 99% rename from prog/gameLibs/render/shaders/gpu_objects_placer.sh rename to prog/gameLibs/render/shaders/gpu_objects_placer.dshl index 60f3ad848..102f913b6 100644 --- a/prog/gameLibs/render/shaders/gpu_objects_placer.sh +++ b/prog/gameLibs/render/shaders/gpu_objects_placer.dshl @@ -1,13 +1,13 @@ -include "shader_global.sh" -include "heightmap_common.sh" -include "toroidal_heightmap.sh" -include "displacement_inc.sh" -include "biomes.sh" -include "gpuobj_displacement_inc.sh" -include "frustum.sh" -include "shore.sh" -include "rendinst_heightmap_ofs.sh" -include "land_mask_inc.sh" +include "shader_global.dshl" +include "heightmap_common.dshl" +include "toroidal_heightmap.dshl" +include "displacement_inc.dshl" +include "biomes.dshl" +include "gpuobj_displacement_inc.dshl" +include "frustum.dshl" +include "shore.dshl" +include "rendinst_heightmap_ofs.dshl" +include "land_mask_inc.dshl" float4 gpu_objects_world_coord; float gpu_objects_bounding_radius; diff --git a/prog/gameLibs/render/shaders/gpu_objects_prefix_sum.sh b/prog/gameLibs/render/shaders/gpu_objects_prefix_sum.dshl similarity index 99% rename from prog/gameLibs/render/shaders/gpu_objects_prefix_sum.sh rename to prog/gameLibs/render/shaders/gpu_objects_prefix_sum.dshl index b40adacb7..2c54164a1 100644 --- a/prog/gameLibs/render/shaders/gpu_objects_prefix_sum.sh +++ b/prog/gameLibs/render/shaders/gpu_objects_prefix_sum.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" int gpu_objects_max_triangles; buffer gpu_objects_counter; diff --git a/prog/gameLibs/render/shaders/gpu_objects_volume_placer.sh b/prog/gameLibs/render/shaders/gpu_objects_volume_placer.dshl similarity index 99% rename from prog/gameLibs/render/shaders/gpu_objects_volume_placer.sh rename to prog/gameLibs/render/shaders/gpu_objects_volume_placer.dshl index 26fdaf467..7054dd14e 100644 --- a/prog/gameLibs/render/shaders/gpu_objects_volume_placer.sh +++ b/prog/gameLibs/render/shaders/gpu_objects_volume_placer.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "heightmap_common.sh" +include "shader_global.dshl" +include "heightmap_common.dshl" int gpu_objects_ri_pool_id_offset; texture noise_128_tex_hash; diff --git a/prog/gameLibs/render/shaders/gpu_occlusion.sh b/prog/gameLibs/render/shaders/gpu_occlusion.dshl similarity index 99% rename from prog/gameLibs/render/shaders/gpu_occlusion.sh rename to prog/gameLibs/render/shaders/gpu_occlusion.dshl index c705c1961..447c4ad29 100644 --- a/prog/gameLibs/render/shaders/gpu_occlusion.sh +++ b/prog/gameLibs/render/shaders/gpu_occlusion.dshl @@ -1,5 +1,5 @@ -include "separate_depth_mips.sh" -include "globtm.sh" +include "separate_depth_mips.dshl" +include "globtm.dshl" int downsampled_depth_mip_count; diff --git a/prog/gameLibs/render/shaders/gtao.sh b/prog/gameLibs/render/shaders/gtao.dshl similarity index 98% rename from prog/gameLibs/render/shaders/gtao.sh rename to prog/gameLibs/render/shaders/gtao.dshl index b55fb2063..440ba11ec 100644 --- a/prog/gameLibs/render/shaders/gtao.sh +++ b/prog/gameLibs/render/shaders/gtao.dshl @@ -1,11 +1,11 @@ -include "shader_global.sh" -include "viewVecVS.sh" -include "gbuffer.sh" -include "contact_shadows.sh" -include "ssao_use.sh" -include "get_additional_shadows.sh" -include "get_additional_ao.sh" -include "ssao_reprojection.sh" +include "shader_global.dshl" +include "viewVecVS.dshl" +include "gbuffer.dshl" +include "contact_shadows.dshl" +include "ssao_use.dshl" +include "get_additional_shadows.dshl" +include "get_additional_ao.dshl" +include "ssao_reprojection.dshl" float gtao_radius = 2.8; float gtao_temporal_directions = 0; @@ -150,7 +150,7 @@ macro GTAO_MAIN_CORE(code) half2 uv = clamp(tc_base + aoDir * i,float2(0.001,0.001),float2(0.999,0.999)); float rawDepth = tex2Dlod(downsampled_close_depth_tex, float4(uv.xy, 0, targetMip)).x; - ##if (use_screen_mask == yes) + ##if (maybe(screen_mask_enabled)) if (rawDepth >= 1) return; ##endif diff --git a/prog/gameLibs/render/shaders/hardware_defines.sh b/prog/gameLibs/render/shaders/hardware_defines.dshl similarity index 99% rename from prog/gameLibs/render/shaders/hardware_defines.sh rename to prog/gameLibs/render/shaders/hardware_defines.dshl index 737a16329..72d0131d7 100644 --- a/prog/gameLibs/render/shaders/hardware_defines.sh +++ b/prog/gameLibs/render/shaders/hardware_defines.dshl @@ -1,5 +1,5 @@ -include "assert.sh" +include "assert.dshl" hlsl { #if _HARDWARE_METAL diff --git a/prog/gameLibs/render/shaders/hdr/hdr_decode.sh b/prog/gameLibs/render/shaders/hdr/hdr_decode.dshl similarity index 95% rename from prog/gameLibs/render/shaders/hdr/hdr_decode.sh rename to prog/gameLibs/render/shaders/hdr/hdr_decode.dshl index 605cac757..622cc63b4 100644 --- a/prog/gameLibs/render/shaders/hdr/hdr_decode.sh +++ b/prog/gameLibs/render/shaders/hdr/hdr_decode.dshl @@ -1,6 +1,6 @@ -include "hardware_defines.sh" -include "postfx_inc.sh" -include "shader_global.sh" +include "hardware_defines.dshl" +include "postfx_inc.dshl" +include "shader_global.dshl" texture hdr_tex; float paper_white_nits = 200; diff --git a/prog/gameLibs/render/shaders/hdr/hdr_ps_output.sh b/prog/gameLibs/render/shaders/hdr/hdr_ps_output.dshl similarity index 100% rename from prog/gameLibs/render/shaders/hdr/hdr_ps_output.sh rename to prog/gameLibs/render/shaders/hdr/hdr_ps_output.dshl diff --git a/prog/gameLibs/render/shaders/hdr/hdr_render.sh b/prog/gameLibs/render/shaders/hdr/hdr_render.dshl similarity index 84% rename from prog/gameLibs/render/shaders/hdr/hdr_render.sh rename to prog/gameLibs/render/shaders/hdr/hdr_render.dshl index dba60bc4e..c145376a4 100644 --- a/prog/gameLibs/render/shaders/hdr/hdr_render.sh +++ b/prog/gameLibs/render/shaders/hdr/hdr_render.dshl @@ -1,9 +1,9 @@ -include "hardware_defines.sh" -include "postfx_inc.sh" -include "shader_global.sh" -include "hdr/hdr_ps_output.sh" -include "hdr/hdr_render_defaults.sh" -include "hdr/hdr_render_logic.sh" +include "hardware_defines.dshl" +include "postfx_inc.dshl" +include "shader_global.dshl" +include "hdr/hdr_ps_output.dshl" +include "hdr/hdr_render_defaults.dshl" +include "hdr/hdr_render_logic.dshl" texture hdr_fp_tex; float4 hdr_source_offset = (0, 0, 0, 0); diff --git a/prog/gameLibs/render/shaders/hdr/hdr_render_defaults.sh b/prog/gameLibs/render/shaders/hdr/hdr_render_defaults.dshl similarity index 100% rename from prog/gameLibs/render/shaders/hdr/hdr_render_defaults.sh rename to prog/gameLibs/render/shaders/hdr/hdr_render_defaults.dshl diff --git a/prog/gameLibs/render/shaders/hdr/hdr_render_logic.sh b/prog/gameLibs/render/shaders/hdr/hdr_render_logic.dshl similarity index 100% rename from prog/gameLibs/render/shaders/hdr/hdr_render_logic.sh rename to prog/gameLibs/render/shaders/hdr/hdr_render_logic.dshl diff --git a/prog/gameLibs/render/shaders/heatHazeOffset.sh b/prog/gameLibs/render/shaders/heatHazeOffset.dshl similarity index 100% rename from prog/gameLibs/render/shaders/heatHazeOffset.sh rename to prog/gameLibs/render/shaders/heatHazeOffset.dshl diff --git a/prog/gameLibs/render/shaders/hero_matrix_inc.sh b/prog/gameLibs/render/shaders/hero_matrix_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/hero_matrix_inc.sh rename to prog/gameLibs/render/shaders/hero_matrix_inc.dshl diff --git a/prog/gameLibs/render/shaders/hmd_device_inc.sh b/prog/gameLibs/render/shaders/hmd_device_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/hmd_device_inc.sh rename to prog/gameLibs/render/shaders/hmd_device_inc.dshl diff --git a/prog/gameLibs/render/shaders/hudprim/depth_fill_gui_aces.sh b/prog/gameLibs/render/shaders/hudprim/depth_fill_gui_aces.dshl similarity index 94% rename from prog/gameLibs/render/shaders/hudprim/depth_fill_gui_aces.sh rename to prog/gameLibs/render/shaders/hudprim/depth_fill_gui_aces.dshl index ffd47c2de..c806ef769 100644 --- a/prog/gameLibs/render/shaders/hudprim/depth_fill_gui_aces.sh +++ b/prog/gameLibs/render/shaders/hudprim/depth_fill_gui_aces.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "gui_aces_common.sh" +include "shader_global.dshl" +include "gui_aces_common.dshl" shader depth_fill_gui_aces { diff --git a/prog/gameLibs/render/shaders/hudprim/gui_aces.sh b/prog/gameLibs/render/shaders/hudprim/gui_aces.dshl similarity index 97% rename from prog/gameLibs/render/shaders/hudprim/gui_aces.sh rename to prog/gameLibs/render/shaders/hudprim/gui_aces.dshl index 971d9813b..3ef74c412 100644 --- a/prog/gameLibs/render/shaders/hudprim/gui_aces.sh +++ b/prog/gameLibs/render/shaders/hudprim/gui_aces.dshl @@ -1,9 +1,9 @@ -include "shader_global.sh" -include "cloud_mask.sh" -include "gui_aces_helpers.sh" -include "gbuffer.sh" -include "gui_aces_common.sh" -include "flexible_scale_rasterization.sh" +include "shader_global.dshl" +include "cloud_mask.dshl" +include "gui_aces_helpers.dshl" +include "gbuffer.dshl" +include "gui_aces_common.dshl" +include "flexible_scale_rasterization.dshl" float4 gui_to_scene_point_to_eye = (0, 0, 0, 0); diff --git a/prog/gameLibs/render/shaders/hudprim/gui_aces_common.sh b/prog/gameLibs/render/shaders/hudprim/gui_aces_common.dshl similarity index 100% rename from prog/gameLibs/render/shaders/hudprim/gui_aces_common.sh rename to prog/gameLibs/render/shaders/hudprim/gui_aces_common.dshl diff --git a/prog/gameLibs/render/shaders/invGlobTm.sh b/prog/gameLibs/render/shaders/invGlobTm.dshl similarity index 100% rename from prog/gameLibs/render/shaders/invGlobTm.sh rename to prog/gameLibs/render/shaders/invGlobTm.dshl diff --git a/prog/gameLibs/render/shaders/light_mask_helpers.sh b/prog/gameLibs/render/shaders/light_mask_helpers.dshl similarity index 100% rename from prog/gameLibs/render/shaders/light_mask_helpers.sh rename to prog/gameLibs/render/shaders/light_mask_helpers.dshl diff --git a/prog/gameLibs/render/shaders/light_probe.sh b/prog/gameLibs/render/shaders/light_probe.dshl similarity index 97% rename from prog/gameLibs/render/shaders/light_probe.sh rename to prog/gameLibs/render/shaders/light_probe.dshl index 16cc37353..47a847430 100644 --- a/prog/gameLibs/render/shaders/light_probe.sh +++ b/prog/gameLibs/render/shaders/light_probe.dshl @@ -1,6 +1,6 @@ -include "shader_global.sh" -include "monteCarlo.sh" -include "roughToMip.sh" +include "shader_global.dshl" +include "monteCarlo.dshl" +include "roughToMip.dshl" define_macro_if_not_defined SUPPORT_GLOBAL_FRAME() endmacro diff --git a/prog/gameLibs/render/shaders/light_probe_blend.sh b/prog/gameLibs/render/shaders/light_probe_blend.dshl similarity index 99% rename from prog/gameLibs/render/shaders/light_probe_blend.sh rename to prog/gameLibs/render/shaders/light_probe_blend.dshl index d56de7632..fce6d9441 100644 --- a/prog/gameLibs/render/shaders/light_probe_blend.sh +++ b/prog/gameLibs/render/shaders/light_probe_blend.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" texture dynamic_cube_tex_1; texture dynamic_cube_tex_2; diff --git a/prog/gameLibs/render/shaders/lightning.sh b/prog/gameLibs/render/shaders/lightning.dshl similarity index 100% rename from prog/gameLibs/render/shaders/lightning.sh rename to prog/gameLibs/render/shaders/lightning.dshl diff --git a/prog/gameLibs/render/shaders/lightningFlashPanorama.sh b/prog/gameLibs/render/shaders/lightningFlashPanorama.dshl similarity index 100% rename from prog/gameLibs/render/shaders/lightningFlashPanorama.sh rename to prog/gameLibs/render/shaders/lightningFlashPanorama.dshl diff --git a/prog/gameLibs/render/shaders/materials/fur_mat_inc.sh b/prog/gameLibs/render/shaders/materials/fur_mat_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/materials/fur_mat_inc.sh rename to prog/gameLibs/render/shaders/materials/fur_mat_inc.dshl diff --git a/prog/gameLibs/render/shaders/mip_blur_filters.sh b/prog/gameLibs/render/shaders/mip_blur_filters.dshl similarity index 99% rename from prog/gameLibs/render/shaders/mip_blur_filters.sh rename to prog/gameLibs/render/shaders/mip_blur_filters.dshl index f8b32020e..59b958819 100644 --- a/prog/gameLibs/render/shaders/mip_blur_filters.sh +++ b/prog/gameLibs/render/shaders/mip_blur_filters.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" float4 mip_target_size; diff --git a/prog/gameLibs/render/shaders/monteCarlo.sh b/prog/gameLibs/render/shaders/monteCarlo.dshl similarity index 100% rename from prog/gameLibs/render/shaders/monteCarlo.sh rename to prog/gameLibs/render/shaders/monteCarlo.dshl diff --git a/prog/gameLibs/render/shaders/motion_blur.sh b/prog/gameLibs/render/shaders/motion_blur.dshl similarity index 98% rename from prog/gameLibs/render/shaders/motion_blur.sh rename to prog/gameLibs/render/shaders/motion_blur.dshl index 73398edef..ee46efd71 100644 --- a/prog/gameLibs/render/shaders/motion_blur.sh +++ b/prog/gameLibs/render/shaders/motion_blur.dshl @@ -1,6 +1,6 @@ -include "shader_global.sh" -include "viewVecVS.sh" -include "taa_inc.sh" +include "shader_global.dshl" +include "viewVecVS.dshl" +include "taa_inc.dshl" texture accumulation_tex; diff --git a/prog/gameLibs/render/shaders/mulPointTm_inc.sh b/prog/gameLibs/render/shaders/mulPointTm_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/mulPointTm_inc.sh rename to prog/gameLibs/render/shaders/mulPointTm_inc.dshl diff --git a/prog/gameLibs/render/shaders/normaldetail.sh b/prog/gameLibs/render/shaders/normaldetail.dshl similarity index 89% rename from prog/gameLibs/render/shaders/normaldetail.sh rename to prog/gameLibs/render/shaders/normaldetail.dshl index 2dc05dc7f..87b689dcd 100644 --- a/prog/gameLibs/render/shaders/normaldetail.sh +++ b/prog/gameLibs/render/shaders/normaldetail.dshl @@ -1,4 +1,4 @@ -include "psh_tangent.sh" +include "psh_tangent.dshl" //reference! macro USE_NORMAL_DETAIL() diff --git a/prog/gameLibs/render/shaders/normaldetail.hlsl b/prog/gameLibs/render/shaders/normaldetail.hlsl index 6e3ed4ec2..31d8048b9 100644 --- a/prog/gameLibs/render/shaders/normaldetail.hlsl +++ b/prog/gameLibs/render/shaders/normaldetail.hlsl @@ -78,7 +78,7 @@ half3 RNM_ndetail_normalized_worldspace(half3 n1, half3 n2, half3 ws_normal) return r; } -half3 blend_normals_worldspace(half3 baseNormal, half3 detailNormal1, half3 detailNormal2, half mix_weight, half3 normal, float3 pointToEye, float2 baseTC, float4 detailTC12) +half3 blend_normals_worldspace(half3 baseNormal, half3 detailNormal1, half3 detailNormal2, half mix_weight, float3 normal, float3 pointToEye, float2 baseTC, float4 detailTC12) { //mix 3 normal maps, 1-base 2&3 - detailed //1.calculate world normals (current normals are in texture space) @@ -86,7 +86,7 @@ half3 blend_normals_worldspace(half3 baseNormal, half3 detailNormal1, half3 deta //1.calculate world normals (current normals in texture space) //we have 3 different uv's, that's why we need translate all 3 normals to world space separately using right uv's - half3 ws_normal = normalize(normal); + half3 ws_normal = half3(normalize(normal)); // get edge vectors of the pixel triangle (only once, look perturb_normal() ) float3 dp1 = ddx( pointToEye ); //normalize @@ -105,9 +105,9 @@ half3 blend_normals_worldspace(half3 baseNormal, half3 detailNormal1, half3 deta return worldNormal; } -half3 blend_normals_worldspace(half3 base_normal, half3 detail_normal, half3 vertex_normal, float3 point_to_eye, float2 base_texcoord, float2 detail_texcoord) +half3 blend_normals_worldspace(half3 base_normal, half3 detail_normal, float3 vertex_normal, float3 point_to_eye, float2 base_texcoord, float2 detail_texcoord) { - half3 vertexWorldNormal = normalize(vertex_normal); + half3 vertexWorldNormal = half3(normalize(vertex_normal)); // get edge vectors of the pixel triangle (only once, look perturb_normal() ) float3 dp1 = ddx(point_to_eye); diff --git a/prog/gameLibs/render/shaders/octahedral_shadow.sh b/prog/gameLibs/render/shaders/octahedral_shadow.dshl similarity index 98% rename from prog/gameLibs/render/shaders/octahedral_shadow.sh rename to prog/gameLibs/render/shaders/octahedral_shadow.dshl index 594389cf5..24cc406ef 100644 --- a/prog/gameLibs/render/shaders/octahedral_shadow.sh +++ b/prog/gameLibs/render/shaders/octahedral_shadow.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "postfx_inc.sh" +include "shader_global.dshl" +include "postfx_inc.dshl" texture octahedral_temp_shadow; float4 octahedral_texture_size = float4(1, 1, 0, 0); diff --git a/prog/gameLibs/render/shaders/pack_impostor_texture.sh b/prog/gameLibs/render/shaders/pack_impostor_texture.dshl similarity index 99% rename from prog/gameLibs/render/shaders/pack_impostor_texture.sh rename to prog/gameLibs/render/shaders/pack_impostor_texture.dshl index 6d3639827..6f60ef511 100644 --- a/prog/gameLibs/render/shaders/pack_impostor_texture.sh +++ b/prog/gameLibs/render/shaders/pack_impostor_texture.dshl @@ -1,7 +1,7 @@ -include "shader_global.sh" -include "gbuffer.sh" -include "rendinst_inc.sh" -include "rendinst_impostor_inc.sh" +include "shader_global.dshl" +include "gbuffer.dshl" +include "rendinst_inc.dshl" +include "rendinst_impostor_inc.dshl" float4 texture_size = float4(1, 1, 0, 0); int impostor_sdf_max_distance = 8; diff --git a/prog/gameLibs/render/shaders/paint_details_inc.sh b/prog/gameLibs/render/shaders/paint_details_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/paint_details_inc.sh rename to prog/gameLibs/render/shaders/paint_details_inc.dshl diff --git a/prog/gameLibs/render/shaders/particle_system_inc.sh b/prog/gameLibs/render/shaders/particle_system_inc.dshl similarity index 99% rename from prog/gameLibs/render/shaders/particle_system_inc.sh rename to prog/gameLibs/render/shaders/particle_system_inc.dshl index fc2f2ace4..722306af0 100644 --- a/prog/gameLibs/render/shaders/particle_system_inc.sh +++ b/prog/gameLibs/render/shaders/particle_system_inc.dshl @@ -1,5 +1,5 @@ -include "hardware_defines.sh" -include "particle_system_lib.sh" +include "hardware_defines.dshl" +include "particle_system_lib.dshl" hlsl { diff --git a/prog/gameLibs/render/shaders/particle_system_lib.sh b/prog/gameLibs/render/shaders/particle_system_lib.dshl similarity index 100% rename from prog/gameLibs/render/shaders/particle_system_lib.sh rename to prog/gameLibs/render/shaders/particle_system_lib.dshl diff --git a/prog/gameLibs/render/shaders/pivot_painter.sh b/prog/gameLibs/render/shaders/pivot_painter.dshl similarity index 100% rename from prog/gameLibs/render/shaders/pivot_painter.sh rename to prog/gameLibs/render/shaders/pivot_painter.dshl diff --git a/prog/gameLibs/render/shaders/pn_triangulation.sh b/prog/gameLibs/render/shaders/pn_triangulation.dshl similarity index 100% rename from prog/gameLibs/render/shaders/pn_triangulation.sh rename to prog/gameLibs/render/shaders/pn_triangulation.dshl diff --git a/prog/gameLibs/render/shaders/postfx_inc.sh b/prog/gameLibs/render/shaders/postfx_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/postfx_inc.sh rename to prog/gameLibs/render/shaders/postfx_inc.dshl diff --git a/prog/gameLibs/render/shaders/prefilter_gf.sh b/prog/gameLibs/render/shaders/prefilter_gf.dshl similarity index 99% rename from prog/gameLibs/render/shaders/prefilter_gf.sh rename to prog/gameLibs/render/shaders/prefilter_gf.dshl index 8ee4a9adb..240659f07 100644 --- a/prog/gameLibs/render/shaders/prefilter_gf.sh +++ b/prog/gameLibs/render/shaders/prefilter_gf.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" +include "shader_global.dshl" hlsl { #include "BRDF.hlsl" diff --git a/prog/gameLibs/render/shaders/psh_derivate.sh b/prog/gameLibs/render/shaders/psh_derivate.dshl similarity index 100% rename from prog/gameLibs/render/shaders/psh_derivate.sh rename to prog/gameLibs/render/shaders/psh_derivate.dshl diff --git a/prog/gameLibs/render/shaders/psh_tangent.sh b/prog/gameLibs/render/shaders/psh_tangent.dshl similarity index 100% rename from prog/gameLibs/render/shaders/psh_tangent.sh rename to prog/gameLibs/render/shaders/psh_tangent.dshl diff --git a/prog/gameLibs/render/shaders/puddles_inc.sh b/prog/gameLibs/render/shaders/puddles_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/puddles_inc.sh rename to prog/gameLibs/render/shaders/puddles_inc.dshl diff --git a/prog/gameLibs/render/shaders/punctualLights.sh b/prog/gameLibs/render/shaders/punctualLights.dshl similarity index 100% rename from prog/gameLibs/render/shaders/punctualLights.sh rename to prog/gameLibs/render/shaders/punctualLights.dshl diff --git a/prog/gameLibs/render/shaders/rendinst_impostor_inc.sh b/prog/gameLibs/render/shaders/rendinst_impostor_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/rendinst_impostor_inc.sh rename to prog/gameLibs/render/shaders/rendinst_impostor_inc.dshl diff --git a/prog/gameLibs/render/shaders/rendinst_impostor_octahedral.sh b/prog/gameLibs/render/shaders/rendinst_impostor_octahedral.dshl similarity index 99% rename from prog/gameLibs/render/shaders/rendinst_impostor_octahedral.sh rename to prog/gameLibs/render/shaders/rendinst_impostor_octahedral.dshl index fe1d02e84..4aa26f715 100644 --- a/prog/gameLibs/render/shaders/rendinst_impostor_octahedral.sh +++ b/prog/gameLibs/render/shaders/rendinst_impostor_octahedral.dshl @@ -1,9 +1,9 @@ -include "shader_global.sh" -include "rendinst_opaque_inc.sh" -include "rendinst_impostor_inc.sh" -include "rendinst_vegetation_inc.sh" -include "gbuffer.sh" -include "viewVecVS.sh" +include "shader_global.dshl" +include "rendinst_opaque_inc.dshl" +include "rendinst_impostor_inc.dshl" +include "rendinst_vegetation_inc.dshl" +include "gbuffer.dshl" +include "viewVecVS.dshl" int impostor_per_pixel_depth = 0; interval impostor_per_pixel_depth : diff --git a/prog/gameLibs/render/shaders/rendinst_impostor_shadow_atlas.sh b/prog/gameLibs/render/shaders/rendinst_impostor_shadow_atlas.dshl similarity index 95% rename from prog/gameLibs/render/shaders/rendinst_impostor_shadow_atlas.sh rename to prog/gameLibs/render/shaders/rendinst_impostor_shadow_atlas.dshl index 9657c88ff..8213456be 100644 --- a/prog/gameLibs/render/shaders/rendinst_impostor_shadow_atlas.sh +++ b/prog/gameLibs/render/shaders/rendinst_impostor_shadow_atlas.dshl @@ -1,11 +1,11 @@ -include "shader_global.sh" -include "viewVecVS.sh" +include "shader_global.dshl" +include "viewVecVS.dshl" -include "rendinst_opaque_inc.sh" +include "rendinst_opaque_inc.dshl" -include "rendinst_impostor_inc.sh" -include "rendinst_vegetation_inc.sh" -include "rendinst_inc.sh" +include "rendinst_impostor_inc.dshl" +include "rendinst_vegetation_inc.dshl" +include "rendinst_inc.dshl" float4 impostor_slice = float4(0, 0, 0, 0); texture impostor_atlas_mask; diff --git a/prog/gameLibs/render/shaders/rendinst_interior_mapping_inc.sh b/prog/gameLibs/render/shaders/rendinst_interior_mapping_inc.dshl similarity index 99% rename from prog/gameLibs/render/shaders/rendinst_interior_mapping_inc.sh rename to prog/gameLibs/render/shaders/rendinst_interior_mapping_inc.dshl index bd0fa2098..c2101fad8 100644 --- a/prog/gameLibs/render/shaders/rendinst_interior_mapping_inc.sh +++ b/prog/gameLibs/render/shaders/rendinst_interior_mapping_inc.dshl @@ -1,6 +1,6 @@ -include "shader_global.sh" -include "rendinst_opaque_inc.sh" -include "static_shadow.sh" +include "shader_global.dshl" +include "rendinst_opaque_inc.dshl" +include "static_shadow.dshl" macro INIT_RENDINST_INTERIOR_MAPPING() texture tex = material.texture.diffuse; diff --git a/prog/gameLibs/render/shaders/reprojected_motion_vectors.sh b/prog/gameLibs/render/shaders/reprojected_motion_vectors.dshl similarity index 100% rename from prog/gameLibs/render/shaders/reprojected_motion_vectors.sh rename to prog/gameLibs/render/shaders/reprojected_motion_vectors.dshl diff --git a/prog/gameLibs/render/shaders/rgb_to_rgbm.sh b/prog/gameLibs/render/shaders/rgb_to_rgbm.dshl similarity index 94% rename from prog/gameLibs/render/shaders/rgb_to_rgbm.sh rename to prog/gameLibs/render/shaders/rgb_to_rgbm.dshl index c4c13115e..563106932 100644 --- a/prog/gameLibs/render/shaders/rgb_to_rgbm.sh +++ b/prog/gameLibs/render/shaders/rgb_to_rgbm.dshl @@ -1,6 +1,6 @@ -include "postfx_inc.sh" -include "shader_global.sh" -include "rgbm_inc.sh" +include "postfx_inc.dshl" +include "shader_global.dshl" +include "rgbm_inc.dshl" texture rgb_to_rgbm_src_tex; float4 rgbm_stretch_rect = (0, 0, 0, 0); diff --git a/prog/gameLibs/render/shaders/rgbm_inc.sh b/prog/gameLibs/render/shaders/rgbm_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/rgbm_inc.sh rename to prog/gameLibs/render/shaders/rgbm_inc.dshl diff --git a/prog/gameLibs/render/shaders/rotation_palette_inc.sh b/prog/gameLibs/render/shaders/rotation_palette_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/rotation_palette_inc.sh rename to prog/gameLibs/render/shaders/rotation_palette_inc.dshl diff --git a/prog/gameLibs/render/shaders/roughToMip.sh b/prog/gameLibs/render/shaders/roughToMip.dshl similarity index 100% rename from prog/gameLibs/render/shaders/roughToMip.sh rename to prog/gameLibs/render/shaders/roughToMip.dshl diff --git a/prog/gameLibs/render/shaders/screen_droplets.sh b/prog/gameLibs/render/shaders/screen_droplets.dshl similarity index 98% rename from prog/gameLibs/render/shaders/screen_droplets.sh rename to prog/gameLibs/render/shaders/screen_droplets.dshl index c35b813e2..a5c8040fc 100644 --- a/prog/gameLibs/render/shaders/screen_droplets.sh +++ b/prog/gameLibs/render/shaders/screen_droplets.dshl @@ -1,6 +1,6 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "shader_global.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "shader_global.dshl" //Begin time, End time, Rain force, Fadeout R float4 screen_droplets_setup = (0.0, 0.0, -1.0, 0.4); diff --git a/prog/gameLibs/render/shaders/scrollShadow.sh b/prog/gameLibs/render/shaders/scrollShadow.dshl similarity index 96% rename from prog/gameLibs/render/shaders/scrollShadow.sh rename to prog/gameLibs/render/shaders/scrollShadow.dshl index e3f486787..dd44dfdc8 100644 --- a/prog/gameLibs/render/shaders/scrollShadow.sh +++ b/prog/gameLibs/render/shaders/scrollShadow.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "postfx_inc.sh" +include "shader_global.dshl" +include "postfx_inc.dshl" float4 tile_change_depth_scale_ofs; int tile_read_depth_2d = 1; diff --git a/prog/gameLibs/render/shaders/separate_depth_mips.sh b/prog/gameLibs/render/shaders/separate_depth_mips.dshl similarity index 100% rename from prog/gameLibs/render/shaders/separate_depth_mips.sh rename to prog/gameLibs/render/shaders/separate_depth_mips.dshl diff --git a/prog/gameLibs/render/shaders/simple_outline.sh b/prog/gameLibs/render/shaders/simple_outline.dshl similarity index 97% rename from prog/gameLibs/render/shaders/simple_outline.sh rename to prog/gameLibs/render/shaders/simple_outline.dshl index e61c27566..ed31cd90a 100644 --- a/prog/gameLibs/render/shaders/simple_outline.sh +++ b/prog/gameLibs/render/shaders/simple_outline.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" float4 simple_outline_color; texture simple_outline_color_rt; diff --git a/prog/gameLibs/render/shaders/skinning_inc.sh b/prog/gameLibs/render/shaders/skinning_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/skinning_inc.sh rename to prog/gameLibs/render/shaders/skinning_inc.dshl diff --git a/prog/gameLibs/render/shaders/skyLight.sh b/prog/gameLibs/render/shaders/skyLight.dshl similarity index 100% rename from prog/gameLibs/render/shaders/skyLight.sh rename to prog/gameLibs/render/shaders/skyLight.dshl diff --git a/prog/gameLibs/render/shaders/smoke_tracers_gen.sh b/prog/gameLibs/render/shaders/smoke_tracers_gen.dshl similarity index 99% rename from prog/gameLibs/render/shaders/smoke_tracers_gen.sh rename to prog/gameLibs/render/shaders/smoke_tracers_gen.dshl index 0f7cb2e70..666e6828e 100644 --- a/prog/gameLibs/render/shaders/smoke_tracers_gen.sh +++ b/prog/gameLibs/render/shaders/smoke_tracers_gen.dshl @@ -1,6 +1,6 @@ -include "shader_global.sh" -include "frustum.sh" -include "globtm.sh" +include "shader_global.dshl" +include "frustum.dshl" +include "globtm.dshl" hlsl { #include } diff --git a/prog/gameLibs/render/shaders/solid_color.sh b/prog/gameLibs/render/shaders/solid_color.dshl similarity index 87% rename from prog/gameLibs/render/shaders/solid_color.sh rename to prog/gameLibs/render/shaders/solid_color.dshl index a1068f529..48620e45c 100644 --- a/prog/gameLibs/render/shaders/solid_color.sh +++ b/prog/gameLibs/render/shaders/solid_color.dshl @@ -1,5 +1,5 @@ -include "postfx_inc.sh" -include "shader_global.sh" +include "postfx_inc.dshl" +include "shader_global.dshl" float4 solid_color; diff --git a/prog/gameLibs/render/shaders/sparkles.sh b/prog/gameLibs/render/shaders/sparkles.dshl similarity index 100% rename from prog/gameLibs/render/shaders/sparkles.sh rename to prog/gameLibs/render/shaders/sparkles.dshl diff --git a/prog/gameLibs/render/shaders/spherical_harmonics.sh b/prog/gameLibs/render/shaders/spherical_harmonics.dshl similarity index 99% rename from prog/gameLibs/render/shaders/spherical_harmonics.sh rename to prog/gameLibs/render/shaders/spherical_harmonics.dshl index 0b9c60e02..7e1f23ab4 100644 --- a/prog/gameLibs/render/shaders/spherical_harmonics.sh +++ b/prog/gameLibs/render/shaders/spherical_harmonics.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" int sp_harm_cube_face_width; int sp_harm_face_number; diff --git a/prog/gameLibs/render/shaders/spline_solid.sh b/prog/gameLibs/render/shaders/spline_solid.dshl similarity index 98% rename from prog/gameLibs/render/shaders/spline_solid.sh rename to prog/gameLibs/render/shaders/spline_solid.dshl index 3ea106e3a..43ada2b38 100644 --- a/prog/gameLibs/render/shaders/spline_solid.sh +++ b/prog/gameLibs/render/shaders/spline_solid.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "gbuffer.sh" +include "shader_global.dshl" +include "gbuffer.dshl" define_macro_if_not_defined USE_STATIC_SHADOW() endmacro diff --git a/prog/gameLibs/render/shaders/ssao_inc.sh b/prog/gameLibs/render/shaders/ssao_inc.dshl similarity index 93% rename from prog/gameLibs/render/shaders/ssao_inc.sh rename to prog/gameLibs/render/shaders/ssao_inc.dshl index 240a313a0..e40ef6762 100644 --- a/prog/gameLibs/render/shaders/ssao_inc.sh +++ b/prog/gameLibs/render/shaders/ssao_inc.dshl @@ -1,4 +1,4 @@ -include "upscale_use.sh" +include "upscale_use.dshl" hlsl { #define SSAO_TYPE half3 @@ -17,7 +17,7 @@ interval mobile_ssao_active : no < 1, yes; // Used for WTM macro ENABLE_GBUFFER_SSAO() // All this intervals are present in gbuffer. - // Don't use this macro without inclusion of gbuffer.sh + // Don't use this macro without inclusion of gbuffer.dshl if (use_extended_global_frame_block == yes && compatibility_resolve_options == underwater_off_ssao_on && in_editor_assume == no) diff --git a/prog/gameLibs/render/shaders/ssao_reprojection.sh b/prog/gameLibs/render/shaders/ssao_reprojection.dshl similarity index 98% rename from prog/gameLibs/render/shaders/ssao_reprojection.sh rename to prog/gameLibs/render/shaders/ssao_reprojection.dshl index b2ca1322f..ab9887b42 100644 --- a/prog/gameLibs/render/shaders/ssao_reprojection.sh +++ b/prog/gameLibs/render/shaders/ssao_reprojection.dshl @@ -1,7 +1,7 @@ -include "hero_matrix_inc.sh" -include "taa_inc.sh" -include "reprojected_motion_vectors.sh" -include "force_ignore_history.sh" +include "hero_matrix_inc.dshl" +include "taa_inc.dshl" +include "reprojected_motion_vectors.dshl" +include "force_ignore_history.dshl" float4 prev_globtm_no_ofs_psf_0; float4 prev_globtm_no_ofs_psf_1; diff --git a/prog/gameLibs/render/shaders/ssao_use.sh b/prog/gameLibs/render/shaders/ssao_use.dshl similarity index 98% rename from prog/gameLibs/render/shaders/ssao_use.sh rename to prog/gameLibs/render/shaders/ssao_use.dshl index c202e04c2..1eb4df4d8 100644 --- a/prog/gameLibs/render/shaders/ssao_use.sh +++ b/prog/gameLibs/render/shaders/ssao_use.dshl @@ -1,5 +1,5 @@ -include "ssao_inc.sh" -include "wsao.sh" +include "ssao_inc.dshl" +include "wsao.dshl" int use_contact_shadows = 0; interval use_contact_shadows: no_shadows < 1, use_shadows; diff --git a/prog/gameLibs/render/shaders/ssr.sh b/prog/gameLibs/render/shaders/ssr.dshl similarity index 98% rename from prog/gameLibs/render/shaders/ssr.sh rename to prog/gameLibs/render/shaders/ssr.dshl index ecd6385d9..bf82f3590 100644 --- a/prog/gameLibs/render/shaders/ssr.sh +++ b/prog/gameLibs/render/shaders/ssr.dshl @@ -1,16 +1,16 @@ -include "shader_global.sh" -include "hero_matrix_inc.sh" -include "reprojected_motion_vectors.sh" -include "gbuffer.sh" -include "viewVecVS.sh" -include "monteCarlo.sh" -include "ssr_common.sh" -include "vsm.sh" -include "frustum.sh" -include "alternate_reflections.sh" -include "ssr_inc.sh" -include "separate_depth_mips.sh" -include "force_ignore_history.sh" +include "shader_global.dshl" +include "hero_matrix_inc.dshl" +include "reprojected_motion_vectors.dshl" +include "gbuffer.dshl" +include "viewVecVS.dshl" +include "monteCarlo.dshl" +include "ssr_common.dshl" +include "vsm.dshl" +include "frustum.dshl" +include "alternate_reflections.dshl" +include "ssr_inc.dshl" +include "separate_depth_mips.dshl" +include "force_ignore_history.dshl" int ssr_quality = 1; interval ssr_quality : low<1, medium<2, high<3, ultra; diff --git a/prog/samples/commonShaders/get_additional_ao.sh b/prog/gameLibs/render/shaders/ssr_common_use.dshl similarity index 100% rename from prog/samples/commonShaders/get_additional_ao.sh rename to prog/gameLibs/render/shaders/ssr_common_use.dshl diff --git a/prog/gameLibs/render/shaders/ssr_hq.sh b/prog/gameLibs/render/shaders/ssr_hq.dshl similarity index 99% rename from prog/gameLibs/render/shaders/ssr_hq.sh rename to prog/gameLibs/render/shaders/ssr_hq.dshl index 300a05d0a..4925ac67b 100644 --- a/prog/gameLibs/render/shaders/ssr_hq.sh +++ b/prog/gameLibs/render/shaders/ssr_hq.dshl @@ -1,12 +1,12 @@ -include "shader_global.sh" -include "hero_matrix_inc.sh" -include "reprojected_motion_vectors.sh" -include "gbuffer.sh" -include "viewVecVS.sh" -include "monteCarlo.sh" -include "alternate_reflections.sh" -include "ssr_common.sh" +include "shader_global.dshl" +include "hero_matrix_inc.dshl" +include "reprojected_motion_vectors.dshl" +include "gbuffer.dshl" +include "viewVecVS.dshl" +include "monteCarlo.dshl" +include "alternate_reflections.dshl" +include "ssr_common.dshl" buffer ssr_counters; buffer ssr_ray_list; diff --git a/prog/gameLibs/render/shaders/ssr_inc.sh b/prog/gameLibs/render/shaders/ssr_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/ssr_inc.sh rename to prog/gameLibs/render/shaders/ssr_inc.dshl diff --git a/prog/gameLibs/render/shaders/ssr_use.sh b/prog/gameLibs/render/shaders/ssr_use.dshl similarity index 97% rename from prog/gameLibs/render/shaders/ssr_use.sh rename to prog/gameLibs/render/shaders/ssr_use.dshl index 59ee11a73..9d484fc97 100644 --- a/prog/gameLibs/render/shaders/ssr_use.sh +++ b/prog/gameLibs/render/shaders/ssr_use.dshl @@ -1,5 +1,5 @@ -include "ssr_common_use.sh" -include "upscale_use.sh" +include "ssr_common_use.dshl" +include "upscale_use.dshl" texture ssr_target; float4 SSRParams = (0.91, -2.5, 0,0); diff --git a/prog/gameLibs/render/shaders/static_shadow.sh b/prog/gameLibs/render/shaders/static_shadow.dshl similarity index 99% rename from prog/gameLibs/render/shaders/static_shadow.sh rename to prog/gameLibs/render/shaders/static_shadow.dshl index 9771e0354..ecd960ebb 100644 --- a/prog/gameLibs/render/shaders/static_shadow.sh +++ b/prog/gameLibs/render/shaders/static_shadow.dshl @@ -1,4 +1,4 @@ -include "static_shadow_stcode.sh" +include "static_shadow_stcode.dshl" macro STATIC_SHADOW_DEFINE_SAMPLER_TYPE(code) hlsl(code) diff --git a/prog/gameLibs/render/shaders/static_shadow_stcode.sh b/prog/gameLibs/render/shaders/static_shadow_stcode.dshl similarity index 100% rename from prog/gameLibs/render/shaders/static_shadow_stcode.sh rename to prog/gameLibs/render/shaders/static_shadow_stcode.dshl diff --git a/prog/gameLibs/render/shaders/stencil_inc.sh b/prog/gameLibs/render/shaders/stencil_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/stencil_inc.sh rename to prog/gameLibs/render/shaders/stencil_inc.dshl diff --git a/prog/gameLibs/render/shaders/terraform/terraform.sh b/prog/gameLibs/render/shaders/terraform/terraform.dshl similarity index 98% rename from prog/gameLibs/render/shaders/terraform/terraform.sh rename to prog/gameLibs/render/shaders/terraform/terraform.dshl index 24b6c28f2..40a5e4ae3 100644 --- a/prog/gameLibs/render/shaders/terraform/terraform.sh +++ b/prog/gameLibs/render/shaders/terraform/terraform.dshl @@ -1,8 +1,8 @@ -include "hardware_defines.sh" -include "shader_global.sh" -include "land_block_inc.sh" -include "normaldetail.sh" -include "terraform_inc.sh" +include "hardware_defines.dshl" +include "shader_global.dshl" +include "land_block_inc.dshl" +include "normaldetail.dshl" +include "terraform_inc.dshl" texture terraform_tex_data; float4 terraform_tex_data_pivot_size = (0, 0, 0, 0); diff --git a/prog/gameLibs/render/shaders/terraform/terraform_inc.sh b/prog/gameLibs/render/shaders/terraform/terraform_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/terraform/terraform_inc.sh rename to prog/gameLibs/render/shaders/terraform/terraform_inc.dshl diff --git a/prog/gameLibs/render/shaders/tile_lighting.sh b/prog/gameLibs/render/shaders/tile_lighting.dshl similarity index 100% rename from prog/gameLibs/render/shaders/tile_lighting.sh rename to prog/gameLibs/render/shaders/tile_lighting.dshl diff --git a/prog/gameLibs/render/shaders/tiledLights.sh b/prog/gameLibs/render/shaders/tiledLights.dshl similarity index 98% rename from prog/gameLibs/render/shaders/tiledLights.sh rename to prog/gameLibs/render/shaders/tiledLights.dshl index 2bfccf17e..ff45bf23f 100644 --- a/prog/gameLibs/render/shaders/tiledLights.sh +++ b/prog/gameLibs/render/shaders/tiledLights.dshl @@ -1,6 +1,6 @@ -include "shader_global.sh" -include "clustered/lights_cb.sh" -include "viewVecVS.sh" +include "shader_global.dshl" +include "clustered/lights_cb.dshl" +include "viewVecVS.dshl" texture downsampled_close_depth_tex; diff --git a/prog/gameLibs/render/shaders/tonemapHelpers/colorGrading.sh b/prog/gameLibs/render/shaders/tonemapHelpers/colorGrading.dshl similarity index 100% rename from prog/gameLibs/render/shaders/tonemapHelpers/colorGrading.sh rename to prog/gameLibs/render/shaders/tonemapHelpers/colorGrading.dshl diff --git a/prog/gameLibs/render/shaders/tonemapHelpers/fullTonemap.sh b/prog/gameLibs/render/shaders/tonemapHelpers/fullTonemap.dshl similarity index 86% rename from prog/gameLibs/render/shaders/tonemapHelpers/fullTonemap.sh rename to prog/gameLibs/render/shaders/tonemapHelpers/fullTonemap.dshl index 3333f9a39..ca5fc4c08 100644 --- a/prog/gameLibs/render/shaders/tonemapHelpers/fullTonemap.sh +++ b/prog/gameLibs/render/shaders/tonemapHelpers/fullTonemap.dshl @@ -1,6 +1,6 @@ -include "whiteBalance.sh" -include "lottesSCurve.sh" -include "colorGrading.sh" +include "whiteBalance.dshl" +include "lottesSCurve.dshl" +include "colorGrading.dshl" macro FULL_TONEMAP(code) LOTTES_TONEMAP_PARAMS(code) diff --git a/prog/gameLibs/render/shaders/tonemapHelpers/lottesSCurve.sh b/prog/gameLibs/render/shaders/tonemapHelpers/lottesSCurve.dshl similarity index 100% rename from prog/gameLibs/render/shaders/tonemapHelpers/lottesSCurve.sh rename to prog/gameLibs/render/shaders/tonemapHelpers/lottesSCurve.dshl diff --git a/prog/gameLibs/render/shaders/tonemapHelpers/render_full_tonemap_lut.sh b/prog/gameLibs/render/shaders/tonemapHelpers/render_full_tonemap_lut.dshl similarity index 98% rename from prog/gameLibs/render/shaders/tonemapHelpers/render_full_tonemap_lut.sh rename to prog/gameLibs/render/shaders/tonemapHelpers/render_full_tonemap_lut.dshl index 7b776c3d1..e0a25452c 100644 --- a/prog/gameLibs/render/shaders/tonemapHelpers/render_full_tonemap_lut.sh +++ b/prog/gameLibs/render/shaders/tonemapHelpers/render_full_tonemap_lut.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "fullTonemap.sh" +include "shader_global.dshl" +include "fullTonemap.dshl" int tonemap_sim_rt = 0; interval tonemap_sim_rt:four<5, eight; diff --git a/prog/gameLibs/render/shaders/tonemapHelpers/use_full_tonemap_lut_inc.sh b/prog/gameLibs/render/shaders/tonemapHelpers/use_full_tonemap_lut_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/tonemapHelpers/use_full_tonemap_lut_inc.sh rename to prog/gameLibs/render/shaders/tonemapHelpers/use_full_tonemap_lut_inc.dshl diff --git a/prog/gameLibs/render/shaders/tonemapHelpers/whiteBalance.sh b/prog/gameLibs/render/shaders/tonemapHelpers/whiteBalance.dshl similarity index 100% rename from prog/gameLibs/render/shaders/tonemapHelpers/whiteBalance.sh rename to prog/gameLibs/render/shaders/tonemapHelpers/whiteBalance.dshl diff --git a/prog/gameLibs/render/shaders/toroidal_heightmap.sh b/prog/gameLibs/render/shaders/toroidal_heightmap.dshl similarity index 100% rename from prog/gameLibs/render/shaders/toroidal_heightmap.sh rename to prog/gameLibs/render/shaders/toroidal_heightmap.dshl diff --git a/prog/gameLibs/render/shaders/tracer.sh b/prog/gameLibs/render/shaders/tracer.dshl similarity index 99% rename from prog/gameLibs/render/shaders/tracer.sh rename to prog/gameLibs/render/shaders/tracer.dshl index 396b779c0..05465ae1f 100644 --- a/prog/gameLibs/render/shaders/tracer.sh +++ b/prog/gameLibs/render/shaders/tracer.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "cloud_mask.sh" +include "shader_global.dshl" +include "cloud_mask.dshl" int fx_create_cmd = 0; interval fx_create_cmd: fx_create_tracer < 1, fx_create_segment; diff --git a/prog/gameLibs/render/shaders/ui_blur.sh b/prog/gameLibs/render/shaders/ui_blur.dshl similarity index 99% rename from prog/gameLibs/render/shaders/ui_blur.sh rename to prog/gameLibs/render/shaders/ui_blur.dshl index 4c549ca4b..f31700342 100644 --- a/prog/gameLibs/render/shaders/ui_blur.sh +++ b/prog/gameLibs/render/shaders/ui_blur.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "shader_gamma_inc.sh" +include "shader_global.dshl" +include "shader_gamma_inc.dshl" texture blur_src_tex; texture blur_background_tex; diff --git a/prog/gameLibs/render/shaders/upscale_sampling.sh b/prog/gameLibs/render/shaders/upscale_sampling.dshl similarity index 98% rename from prog/gameLibs/render/shaders/upscale_sampling.sh rename to prog/gameLibs/render/shaders/upscale_sampling.dshl index 5e88932a0..564d96c54 100644 --- a/prog/gameLibs/render/shaders/upscale_sampling.sh +++ b/prog/gameLibs/render/shaders/upscale_sampling.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "gbuffer.sh" +include "shader_global.dshl" +include "gbuffer.dshl" texture downsampled_checkerboard_depth_tex; diff --git a/prog/gameLibs/render/shaders/upscale_use.sh b/prog/gameLibs/render/shaders/upscale_use.dshl similarity index 100% rename from prog/gameLibs/render/shaders/upscale_use.sh rename to prog/gameLibs/render/shaders/upscale_use.dshl diff --git a/prog/gameLibs/render/shaders/use_prefiltered_gf.sh b/prog/gameLibs/render/shaders/use_prefiltered_gf.dshl similarity index 100% rename from prog/gameLibs/render/shaders/use_prefiltered_gf.sh rename to prog/gameLibs/render/shaders/use_prefiltered_gf.dshl diff --git a/prog/gameLibs/render/shaders/vertex_density_overlay.sh b/prog/gameLibs/render/shaders/vertex_density_overlay.dshl similarity index 94% rename from prog/gameLibs/render/shaders/vertex_density_overlay.sh rename to prog/gameLibs/render/shaders/vertex_density_overlay.dshl index 091d7f549..a8f293e3e 100644 --- a/prog/gameLibs/render/shaders/vertex_density_overlay.sh +++ b/prog/gameLibs/render/shaders/vertex_density_overlay.dshl @@ -1,5 +1,5 @@ -include "vertex_density_overlay_inc.sh" -include "shader_global.sh" +include "vertex_density_overlay_inc.dshl" +include "shader_global.dshl" shader vertexDensityOverlay { diff --git a/prog/gameLibs/render/shaders/vertex_density_overlay_inc.sh b/prog/gameLibs/render/shaders/vertex_density_overlay_inc.dshl similarity index 99% rename from prog/gameLibs/render/shaders/vertex_density_overlay_inc.sh rename to prog/gameLibs/render/shaders/vertex_density_overlay_inc.dshl index 08e5f9df4..aa48b83ae 100644 --- a/prog/gameLibs/render/shaders/vertex_density_overlay_inc.sh +++ b/prog/gameLibs/render/shaders/vertex_density_overlay_inc.dshl @@ -1,4 +1,4 @@ -include "assert.sh" +include "assert.dshl" buffer vertexDensityAccumulator; int vertexDensityHalfSize = 2048; diff --git a/prog/gameLibs/render/shaders/viewVecVS.sh b/prog/gameLibs/render/shaders/viewVecVS.dshl similarity index 100% rename from prog/gameLibs/render/shaders/viewVecVS.sh rename to prog/gameLibs/render/shaders/viewVecVS.dshl diff --git a/prog/gameLibs/render/shaders/vr_multiview.sh b/prog/gameLibs/render/shaders/vr_multiview.dshl similarity index 96% rename from prog/gameLibs/render/shaders/vr_multiview.sh rename to prog/gameLibs/render/shaders/vr_multiview.dshl index 65ed9bb57..9dacbad16 100644 --- a/prog/gameLibs/render/shaders/vr_multiview.sh +++ b/prog/gameLibs/render/shaders/vr_multiview.dshl @@ -1,4 +1,4 @@ -include "vr_reprojection.sh" +include "vr_reprojection.dshl" int use_vr_multiview = 0; interval use_vr_multiview : no < 1, yes; diff --git a/prog/gameLibs/render/shaders/vr_reprojection.sh b/prog/gameLibs/render/shaders/vr_reprojection.dshl similarity index 100% rename from prog/gameLibs/render/shaders/vr_reprojection.sh rename to prog/gameLibs/render/shaders/vr_reprojection.dshl diff --git a/prog/gameLibs/render/shaders/wake_ps.sh b/prog/gameLibs/render/shaders/wake_ps.dshl similarity index 99% rename from prog/gameLibs/render/shaders/wake_ps.sh rename to prog/gameLibs/render/shaders/wake_ps.dshl index 3777dcccc..a8f5fd9c2 100644 --- a/prog/gameLibs/render/shaders/wake_ps.sh +++ b/prog/gameLibs/render/shaders/wake_ps.dshl @@ -1,7 +1,7 @@ -include "shader_global.sh" -include "viewVecVS.sh" -include "waveWorks.sh" -include "water_heightmap.sh" +include "shader_global.dshl" +include "viewVecVS.dshl" +include "waveWorks.dshl" +include "water_heightmap.dshl" int wfx_count = 0; int wfx_offset = 0; diff --git a/prog/gameLibs/render/shaders/water_foam_trail.sh b/prog/gameLibs/render/shaders/water_foam_trail.dshl similarity index 99% rename from prog/gameLibs/render/shaders/water_foam_trail.sh rename to prog/gameLibs/render/shaders/water_foam_trail.dshl index 97bd523d1..819bb3538 100644 --- a/prog/gameLibs/render/shaders/water_foam_trail.sh +++ b/prog/gameLibs/render/shaders/water_foam_trail.dshl @@ -1,6 +1,6 @@ -include "shader_global.sh" -include "water_foam_trail_inc.sh" -include "snoise.sh" +include "shader_global.dshl" +include "water_foam_trail_inc.dshl" +include "snoise.dshl" texture foam_tex; texture ship_bow_foam; diff --git a/prog/gameLibs/render/shaders/water_foam_trail_inc.sh b/prog/gameLibs/render/shaders/water_foam_trail_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/water_foam_trail_inc.sh rename to prog/gameLibs/render/shaders/water_foam_trail_inc.dshl diff --git a/prog/gameLibs/render/shaders/water_ripples.sh b/prog/gameLibs/render/shaders/water_ripples.dshl similarity index 96% rename from prog/gameLibs/render/shaders/water_ripples.sh rename to prog/gameLibs/render/shaders/water_ripples.dshl index 94a074985..56efde5d0 100644 --- a/prog/gameLibs/render/shaders/water_ripples.sh +++ b/prog/gameLibs/render/shaders/water_ripples.dshl @@ -1,10 +1,10 @@ -include "land_block_inc.sh" -include "land_block_common.sh" -include "displacement_inc.sh" -include "wetness_inc.sh" -include "puddles_inc.sh" -include "toroidal_heightmap.sh" -include "water_heightmap.sh" +include "land_block_inc.dshl" +include "land_block_common.dshl" +include "displacement_inc.dshl" +include "wetness_inc.dshl" +include "puddles_inc.dshl" +include "toroidal_heightmap.dshl" +include "water_heightmap.dshl" texture perlin_tex; diff --git a/prog/gameLibs/render/shaders/wetness_inc.sh b/prog/gameLibs/render/shaders/wetness_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/wetness_inc.sh rename to prog/gameLibs/render/shaders/wetness_inc.dshl diff --git a/prog/gameLibs/render/shaders/wind/apply_tree_wind_inc.sh b/prog/gameLibs/render/shaders/wind/apply_tree_wind_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/wind/apply_tree_wind_inc.sh rename to prog/gameLibs/render/shaders/wind/apply_tree_wind_inc.dshl diff --git a/prog/gameLibs/render/shaders/wind/fluid_wind.sh b/prog/gameLibs/render/shaders/wind/fluid_wind.dshl similarity index 99% rename from prog/gameLibs/render/shaders/wind/fluid_wind.sh rename to prog/gameLibs/render/shaders/wind/fluid_wind.dshl index 2eeb903f6..d645e12d9 100644 --- a/prog/gameLibs/render/shaders/wind/fluid_wind.sh +++ b/prog/gameLibs/render/shaders/wind/fluid_wind.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "wind_simulation_inc.sh" +include "shader_global.dshl" +include "wind_simulation_inc.dshl" int fluid_wind_border_bounds = 0; interval fluid_wind_border_bounds: fluid_wind_border_bounds_off < 1, fluid_wind_border_bounds_on; diff --git a/prog/gameLibs/render/shaders/wind/wind_simulation_inc.sh b/prog/gameLibs/render/shaders/wind/wind_simulation_inc.dshl similarity index 100% rename from prog/gameLibs/render/shaders/wind/wind_simulation_inc.sh rename to prog/gameLibs/render/shaders/wind/wind_simulation_inc.dshl diff --git a/prog/gameLibs/render/shaders/wires.sh b/prog/gameLibs/render/shaders/wires.dshl similarity index 97% rename from prog/gameLibs/render/shaders/wires.sh rename to prog/gameLibs/render/shaders/wires.dshl index 7d1ea10bf..3a28dc0f2 100644 --- a/prog/gameLibs/render/shaders/wires.sh +++ b/prog/gameLibs/render/shaders/wires.dshl @@ -1,8 +1,8 @@ -include "shader_global.sh" -include "gbuffer.sh" -include "wires_helper.sh" -include "static_shadow.sh" -include "vr_multiview.sh" +include "shader_global.dshl" +include "gbuffer.dshl" +include "wires_helper.dshl" +include "static_shadow.dshl" +include "vr_multiview.dshl" buffer cables_buf; float pixel_scale; diff --git a/prog/gameLibs/render/shaders/writeToTex.sh b/prog/gameLibs/render/shaders/writeToTex.dshl similarity index 98% rename from prog/gameLibs/render/shaders/writeToTex.sh rename to prog/gameLibs/render/shaders/writeToTex.dshl index 2af39cd7c..7532fb05e 100644 --- a/prog/gameLibs/render/shaders/writeToTex.sh +++ b/prog/gameLibs/render/shaders/writeToTex.dshl @@ -1,5 +1,5 @@ -include "hardware_defines.sh" -include "postfx_inc.sh" +include "hardware_defines.dshl" +include "postfx_inc.dshl" float slice_offset = 0; float4 dispatch_size = (0, 0, 0, 0); diff --git a/prog/gameLibs/render/shaders/wsao.sh b/prog/gameLibs/render/shaders/wsao.dshl similarity index 94% rename from prog/gameLibs/render/shaders/wsao.sh rename to prog/gameLibs/render/shaders/wsao.dshl index 90f0210cd..f7b9dbad3 100644 --- a/prog/gameLibs/render/shaders/wsao.sh +++ b/prog/gameLibs/render/shaders/wsao.dshl @@ -1,6 +1,6 @@ -include "dagi_volmap_gi.sh" -include "dagi_volmap_common_25d.sh" -include "dagi_quality.sh" +include "dagi_volmap_gi.dshl" +include "dagi_volmap_common_25d.dshl" +include "dagi_quality.dshl" define_macro_if_not_defined USING_ECLIPSE(stage) hlsl(stage) { diff --git a/prog/gameLibs/render/sphHarmCalc.cpp b/prog/gameLibs/render/sphHarmCalc.cpp index 0246a778a..dae3e93b8 100644 --- a/prog/gameLibs/render/sphHarmCalc.cpp +++ b/prog/gameLibs/render/sphHarmCalc.cpp @@ -189,15 +189,17 @@ void SphHarmCalc::processFaceData(uint8_t *buf, int face, int width, int stride, uint8_t *ptr = (uint8_t *)(buf + x * 4); col = Color4(ptr[0] / 255.0f, ptr[1] / 255.0f, ptr[2] / 255.0f, 1); } - if (isLinearTarget) - { - G_ASSERTF(col.r > -0.1f && col.g > -0.1f && col.b > -0.1f, "col=%@", col); // Harmonics are an approximation, be tolerant. - col.clamp0(); - } - else - { + if (!isLinearTarget) col = Color4(powf(max(0.f, col.r), gamma), powf(max(0.f, col.g), gamma), powf(max(0.f, col.b), gamma), 1); + + // Harmonics are an approximation, be tolerant. + if (col.r < -0.1f || col.g < -0.1f || col.b < -0.1f || col.r > 100.f || col.g > 100.f || col.b > 100.f || !check_finite(col.r) || + !check_finite(col.g) || !check_finite(col.b)) + { + LOGERR_ONCE("Invalid SPH sample col=%@", col); + col = Color4(0.1f, 0.2f, 0.4f); // Neutral day color. } + col.clamp0(); float at00 = at01; float at10 = at11; diff --git a/prog/gameLibs/render/volumetricLights/shaders/use_volfog_shadow.sh b/prog/gameLibs/render/volumetricLights/shaders/use_volfog_shadow.dshl similarity index 100% rename from prog/gameLibs/render/volumetricLights/shaders/use_volfog_shadow.sh rename to prog/gameLibs/render/volumetricLights/shaders/use_volfog_shadow.dshl diff --git a/prog/gameLibs/render/volumetricLights/shaders/use_volumetric_light.sh b/prog/gameLibs/render/volumetricLights/shaders/use_volumetric_light.dshl similarity index 100% rename from prog/gameLibs/render/volumetricLights/shaders/use_volumetric_light.sh rename to prog/gameLibs/render/volumetricLights/shaders/use_volumetric_light.dshl diff --git a/prog/gameLibs/render/volumetricLights/shaders/volfog_shadow.sh b/prog/gameLibs/render/volumetricLights/shaders/volfog_shadow.dshl similarity index 92% rename from prog/gameLibs/render/volumetricLights/shaders/volfog_shadow.sh rename to prog/gameLibs/render/volumetricLights/shaders/volfog_shadow.dshl index 869d3ad8c..06ec17b40 100644 --- a/prog/gameLibs/render/volumetricLights/shaders/volfog_shadow.sh +++ b/prog/gameLibs/render/volumetricLights/shaders/volfog_shadow.dshl @@ -1,7 +1,7 @@ -include "sky_shader_global.sh" -include "heightmap_common.sh" -include "volume_light_common.sh" -include "volume_light_hardcoded_media.sh" +include "sky_shader_global.dshl" +include "heightmap_common.dshl" +include "volume_light_common.dshl" +include "volume_light_hardcoded_media.dshl" texture prev_volfog_shadow; diff --git a/prog/gameLibs/render/volumetricLights/shaders/volume_light.sh b/prog/gameLibs/render/volumetricLights/shaders/volume_light.dshl similarity index 99% rename from prog/gameLibs/render/volumetricLights/shaders/volume_light.sh rename to prog/gameLibs/render/volumetricLights/shaders/volume_light.dshl index f461200d2..fb37ad258 100644 --- a/prog/gameLibs/render/volumetricLights/shaders/volume_light.sh +++ b/prog/gameLibs/render/volumetricLights/shaders/volume_light.dshl @@ -1,19 +1,19 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "csm.sh" -include "heightmap_common.sh" -include "static_shadow.sh" -include "fom_shadows.sh" -include "skies_shadows.sh" -include "depth_above.sh" -include "gpu_occlusion.sh" -include "clustered/lights_cb.sh" -include "dagi_volmap_gi.sh" -include "gi_demo.sh" -include "light_mask_helpers.sh" - -include "volume_light_common.sh" -include "volume_light_hardcoded_media.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "csm.dshl" +include "heightmap_common.dshl" +include "static_shadow.dshl" +include "fom_shadows.dshl" +include "skies_shadows.dshl" +include "depth_above.dshl" +include "gpu_occlusion.dshl" +include "clustered/lights_cb.dshl" +include "dagi_volmap_gi.dshl" +include "gi_demo.dshl" +include "light_mask_helpers.dshl" + +include "volume_light_common.dshl" +include "volume_light_hardcoded_media.dshl" // summarizing: current approach is direct implementation of frostbite paper diff --git a/prog/gameLibs/render/volumetricLights/shaders/volume_light_common.sh b/prog/gameLibs/render/volumetricLights/shaders/volume_light_common.dshl similarity index 100% rename from prog/gameLibs/render/volumetricLights/shaders/volume_light_common.sh rename to prog/gameLibs/render/volumetricLights/shaders/volume_light_common.dshl diff --git a/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_common.sh b/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_common.dshl similarity index 96% rename from prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_common.sh rename to prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_common.dshl index 6658a1978..db62ea657 100644 --- a/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_common.sh +++ b/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_common.dshl @@ -1,4 +1,4 @@ -include "volume_light_common.sh" +include "volume_light_common.dshl" int fog_raymarch_frame_id = 0; diff --git a/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_raymarch.sh b/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_raymarch.dshl similarity index 96% rename from prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_raymarch.sh rename to prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_raymarch.dshl index 1dd5d94b0..700c5dba4 100644 --- a/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_raymarch.sh +++ b/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_raymarch.dshl @@ -1,13 +1,13 @@ -include "shader_global.sh" -include "use_volumetric_light.sh" -include "viewVecVS.sh" +include "shader_global.dshl" +include "use_volumetric_light.dshl" +include "viewVecVS.dshl" -include "heightmap_common.sh" +include "heightmap_common.dshl" -include "volume_light_distant_common.sh" +include "volume_light_distant_common.dshl" -include "volume_light_hardcoded_media.sh" +include "volume_light_hardcoded_media.dshl" diff --git a/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_reconstruct.sh b/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_reconstruct.dshl similarity index 99% rename from prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_reconstruct.sh rename to prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_reconstruct.dshl index 861044bfd..fd93088a6 100644 --- a/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_reconstruct.sh +++ b/prog/gameLibs/render/volumetricLights/shaders/volume_light_distant_reconstruct.dshl @@ -1,8 +1,8 @@ -include "sky_shader_global.sh" -include "viewVecVS.sh" -include "gpu_occlusion.sh" +include "sky_shader_global.dshl" +include "viewVecVS.dshl" +include "gpu_occlusion.dshl" -include "volume_light_distant_common.sh" +include "volume_light_distant_common.dshl" hlsl{ diff --git a/prog/gameLibs/render/volumetricLights/shaders/volume_light_fx_mip_gen.sh b/prog/gameLibs/render/volumetricLights/shaders/volume_light_fx_mip_gen.dshl similarity index 98% rename from prog/gameLibs/render/volumetricLights/shaders/volume_light_fx_mip_gen.sh rename to prog/gameLibs/render/volumetricLights/shaders/volume_light_fx_mip_gen.dshl index 60580b0ae..aacbdefe1 100644 --- a/prog/gameLibs/render/volumetricLights/shaders/volume_light_fx_mip_gen.sh +++ b/prog/gameLibs/render/volumetricLights/shaders/volume_light_fx_mip_gen.dshl @@ -1,6 +1,6 @@ -include "shader_global.sh" -include "volume_light_distant_common.sh" +include "shader_global.dshl" +include "volume_light_distant_common.dshl" texture distant_fog_reprojection_dist; texture distant_fog_result_inscatter; diff --git a/prog/gameLibs/render/volumetricLights/shaders/volume_light_hardcoded_media.sh b/prog/gameLibs/render/volumetricLights/shaders/volume_light_hardcoded_media.dshl similarity index 99% rename from prog/gameLibs/render/volumetricLights/shaders/volume_light_hardcoded_media.sh rename to prog/gameLibs/render/volumetricLights/shaders/volume_light_hardcoded_media.dshl index 93ec3ad9f..dd8191808 100644 --- a/prog/gameLibs/render/volumetricLights/shaders/volume_light_hardcoded_media.sh +++ b/prog/gameLibs/render/volumetricLights/shaders/volume_light_hardcoded_media.dshl @@ -1,5 +1,5 @@ -include "depth_above.sh" +include "depth_above.dshl" float volfog_media_fog_input_mul = 1.0; diff --git a/prog/gameLibs/render/volumetricLights/shaders/volume_light_raymarch_mip_gen.sh b/prog/gameLibs/render/volumetricLights/shaders/volume_light_raymarch_mip_gen.dshl similarity index 94% rename from prog/gameLibs/render/volumetricLights/shaders/volume_light_raymarch_mip_gen.sh rename to prog/gameLibs/render/volumetricLights/shaders/volume_light_raymarch_mip_gen.dshl index 1aeeaa01a..10e1b1305 100644 --- a/prog/gameLibs/render/volumetricLights/shaders/volume_light_raymarch_mip_gen.sh +++ b/prog/gameLibs/render/volumetricLights/shaders/volume_light_raymarch_mip_gen.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "volume_light_distant_common.sh" +include "shader_global.dshl" +include "volume_light_distant_common.dshl" texture mip_gen_input_tex; float4 mip_gen_input_tex_size; diff --git a/prog/gameLibs/render/volumetricLights/volumetricLights.cpp b/prog/gameLibs/render/volumetricLights/volumetricLights.cpp index 530c5983e..8917e6e96 100644 --- a/prog/gameLibs/render/volumetricLights/volumetricLights.cpp +++ b/prog/gameLibs/render/volumetricLights/volumetricLights.cpp @@ -117,6 +117,7 @@ CONSOLE_BOOL_VAL("volfog", froxel_fog_enable_linear_accumulation, true); CONSOLE_FLOAT_VAL_MINMAX("volfog", volfog_shadow_voxel_size, 8.0f, 0.1f, 20.0f); CONSOLE_FLOAT_VAL_MINMAX("volfog", volfog_shadow_accumulation_factor, 0.9f, 0.0f, 0.999f); +CONSOLE_BOOL_VAL("volfog", use_fixed_froxel_fog_range, true); CONSOLE_FLOAT_VAL_MINMAX("volfog", froxel_fog_fading_range_ratio, 0.3f, 0.0f, 1.0f); @@ -698,7 +699,8 @@ bool VolumeLight::perform(const TMatrix4 &view_tm, const TMatrix4 &proj_tm, cons resetDistantFog(); } - if (isDistantFogEnabled()) // distant fog is much more stable with a fixed starting depth (depends on froxel range) + if (use_fixed_froxel_fog_range || isDistantFogEnabled()) // distant fog is much more stable with a fixed starting depth (depends on + // froxel range) currentRange = froxel_fog_range; switchOn(); // set range params early for volfog passes diff --git a/prog/gameLibs/soundSystem/soundSystem.cpp b/prog/gameLibs/soundSystem/soundSystem.cpp index 3624a18fd..0e4865073 100644 --- a/prog/gameLibs/soundSystem/soundSystem.cpp +++ b/prog/gameLibs/soundSystem/soundSystem.cpp @@ -446,22 +446,34 @@ static bool system_init(const DataBlock &blk, bool null_output) } #if DAGOR_DBGLEVEL > 0 -static FMOD_RESULT F_CALLBACK fmod_debug_cb(FMOD_DEBUG_FLAGS flags, const char *file, int line, const char *func, const char *message) +static bool treat_fmod_errors_as_warnings = false; +static int get_loglevel(FMOD_DEBUG_FLAGS flags, const char *message) { - G_UNUSED(file); - G_UNUSED(line); - - int ll = LOGLEVEL_DEBUG; if (flags & FMOD_DEBUG_LEVEL_ERROR) { + if (treat_fmod_errors_as_warnings) + return LOGLEVEL_WARN; + if (strstr(message, "assertion: 'inchannels <= mMixMatrixCurrent.numin()' failed")) - ll = LOGLEVEL_DEBUG; // workaround: suppress FMOD assert - // https://qa.fmod.com/t/assertion-inchannels-mmixmatrixcurrent-numin/14511/2 - else - ll = LOGLEVEL_ERR; + return LOGLEVEL_WARN; // workaround: suppress FMOD assert to disable logerr reporting + // qa.fmod.com/t/assertion-inchannels-mmixmatrixcurrent-numin/14511/2 + + if (strstr(message, "returned 0x88890004")) // suppress FMOD assert (0x88890004 = AUDCLNT_E_DEVICE_INVALIDATED) + return LOGLEVEL_WARN; // youtrack.gaijin.team/issue/12-135114 youtrack.gaijin.team/issue/38-45149 + + return LOGLEVEL_ERR; } - else if (flags & FMOD_DEBUG_LEVEL_WARNING) - ll = LOGLEVEL_WARN; + + if (flags & FMOD_DEBUG_LEVEL_WARNING) + return LOGLEVEL_WARN; + + return LOGLEVEL_DEBUG; +} + +static FMOD_RESULT F_CALLBACK fmod_debug_cb(FMOD_DEBUG_FLAGS flags, const char * /*file*/, int /*line*/, const char *func, + const char *message) +{ + const int ll = get_loglevel(flags, message); logmessage(ll, "[FMOD] %s: %.*s", func, /*cut `\n' off */ strlen(message) - 1, message); @@ -491,6 +503,7 @@ bool init(const DataBlock &blk) settings_init(blk); #if DAGOR_DBGLEVEL > 0 + treat_fmod_errors_as_warnings = blk.getBool("fmodErrorsAsWarnings", false); const char *fmodLoglevel = blk.getStr("fmodLoglevel", "errors"); FMOD_DEBUG_FLAGS debugFlags = FMOD_DEBUG_LEVEL_NONE; if (strcmp(fmodLoglevel, "errors") == 0) diff --git a/prog/gameLibs/spirv/compiler_dxc.cpp b/prog/gameLibs/spirv/compiler_dxc.cpp index c54cb5183..bc4c07a9c 100644 --- a/prog/gameLibs/spirv/compiler_dxc.cpp +++ b/prog/gameLibs/spirv/compiler_dxc.cpp @@ -68,29 +68,15 @@ static const SemanticInfo vs_input_table[] = // {"TEXCOORD8", 0x5}, {"TEXCOORD9", 0x2}, {"TEXCOORD10", 0x3}, {"TEXCOORD11", 0x4}, {"TEXCOORD12", 0x1}, {"TEXCOORD13", 0x6}, {"TEXCOORD14", 0x7}, {"NORMAL0", 0x2}, {"COLOR0", 0x3}, {"COLOR1", 0x4}, {"PSIZE0", 0x5}}; -static const SemanticInfo shader_link_table[] = // - {{"NORMAL", 0x0}, {"PSIZE", 0x1}, {"COLOR", 0x2}, {"TEXCOORD0", 0x3}, {"TEXCOORD1", 0x4}, {"TEXCOORD2", 0x5}, {"TEXCOORD3", 0x6}, - {"TEXCOORD4", 0x7}, {"TEXCOORD5", 0x8}, {"TEXCOORD6", 0x9}, {"TEXCOORD7", 0xA}, {"TEXCOORD8", 0xB}, {"TEXCOORD9", 0xC}, - {"TEXCOORD10", 0xD}, {"TEXCOORD11", 0xE}, {"TEXCOORD12", 0xF}, {"TEXCOORD13", 0x10}, {"TEXCOORD14", 0x11}, {"NORMAL0", 0x12}, - {"COLOR0", 0x13}, {"COLOR1", 0x14}, {"PSIZE0", 0x15}}; - dag::ConstSpan getInputSematicTable(const char *profile) { // vs has special input if (profile[0] == 'v' && profile[1] == 's') return make_span(vs_input_table); - return make_span(shader_link_table); + return {}; } -dag::ConstSpan getOutputSematicTable(const char *profile) -{ - // ps has special output - // spiregg guesses the output locations correctly already - // TODO: verify this! - if (profile[0] == 'p' && profile[1] == 's') - return {}; - return make_span(shader_link_table); -} +dag::ConstSpan getOutputSematicTable(const char *profile) { return {}; } std::wstring getSpirvOptimizationConfigString(const eastl::vector &disabledOptims) { diff --git a/prog/gameLibs/textureGen/textureGenCache.cpp b/prog/gameLibs/textureGen/textureGenCache.cpp index a2c4d4fd2..5c9769236 100644 --- a/prog/gameLibs/textureGen/textureGenCache.cpp +++ b/prog/gameLibs/textureGen/textureGenCache.cpp @@ -72,6 +72,9 @@ static class TextureGenCache : public TextureGenShader void cpu_algorithm(dag::ConstSpan &inputs, dag::ConstSpan &outputs, const char *id, bool read_data_from_cache) { + if (!inputs[0].tex) + return; + eastl::vector textureData; if (!read_data_from_cache) @@ -82,6 +85,8 @@ static class TextureGenCache : public TextureGenShader void *cached_data = regcache::get_record_data_ptr(id); + if (!cached_data) + return; int32_t format = 0; memcpy(&format, cached_data, sizeof(format)); diff --git a/prog/gameLibs/textureUtil/shaders/clear_volmap.sh b/prog/gameLibs/textureUtil/shaders/clear_volmap.dshl similarity index 100% rename from prog/gameLibs/textureUtil/shaders/clear_volmap.sh rename to prog/gameLibs/textureUtil/shaders/clear_volmap.dshl diff --git a/prog/gameLibs/textureUtil/shaders/texture_util.sh b/prog/gameLibs/textureUtil/shaders/texture_util.dshl similarity index 95% rename from prog/gameLibs/textureUtil/shaders/texture_util.sh rename to prog/gameLibs/textureUtil/shaders/texture_util.dshl index 588955c79..6184d9a20 100644 --- a/prog/gameLibs/textureUtil/shaders/texture_util.sh +++ b/prog/gameLibs/textureUtil/shaders/texture_util.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "viewVecVS.sh" +include "shader_global.dshl" +include "viewVecVS.dshl" texture texture_util_source_texture; diff --git a/prog/gameLibs/video360/shaders/video360.sh b/prog/gameLibs/video360/shaders/video360.dshl similarity index 97% rename from prog/gameLibs/video360/shaders/video360.sh rename to prog/gameLibs/video360/shaders/video360.dshl index f8e2c4400..21ae1fd0a 100644 --- a/prog/gameLibs/video360/shaders/video360.sh +++ b/prog/gameLibs/video360/shaders/video360.dshl @@ -1,5 +1,5 @@ -include "shader_global.sh" -include "viewVecVS.sh" +include "shader_global.dshl" +include "viewVecVS.dshl" texture video360_screen_env; diff --git a/prog/gameLibs/vr/shaders/vrGuiSurface.sh b/prog/gameLibs/vr/shaders/vrGuiSurface.dshl similarity index 97% rename from prog/gameLibs/vr/shaders/vrGuiSurface.sh rename to prog/gameLibs/vr/shaders/vrGuiSurface.dshl index fbb00c322..0bc81b0f9 100644 --- a/prog/gameLibs/vr/shaders/vrGuiSurface.sh +++ b/prog/gameLibs/vr/shaders/vrGuiSurface.dshl @@ -1,4 +1,4 @@ -include "shader_global.sh" +include "shader_global.dshl" texture source_tex; diff --git a/prog/gameLibs/vr/shaders/vrMirror.sh b/prog/gameLibs/vr/shaders/vrMirror.dshl similarity index 90% rename from prog/gameLibs/vr/shaders/vrMirror.sh rename to prog/gameLibs/vr/shaders/vrMirror.dshl index 125be7f3c..73c795bc4 100644 --- a/prog/gameLibs/vr/shaders/vrMirror.sh +++ b/prog/gameLibs/vr/shaders/vrMirror.dshl @@ -1,5 +1,5 @@ -include "postfx_inc.sh" -include "shader_global.sh" +include "postfx_inc.dshl" +include "shader_global.dshl" texture vr_texture_source; float4 vr_texture_transform; diff --git a/prog/gameLibs/vromfsPacker/jamfile b/prog/gameLibs/vromfsPacker/jamfile index fdd07be9e..741a75a2d 100644 --- a/prog/gameLibs/vromfsPacker/jamfile +++ b/prog/gameLibs/vromfsPacker/jamfile @@ -30,5 +30,6 @@ UseProgLibs += ; CPPopt = ; +if $(Platform) in macosx { CPPopt += -Wno-deprecated-declarations ; } include $(Root)/prog/_jBuild/build.jam ; diff --git a/prog/gameLibs/webui/plugins/ecsviewer/ecsViewerPluginListener.cpp b/prog/gameLibs/webui/plugins/ecsviewer/ecsViewerPluginListener.cpp index c45f7e9c7..c27878bcc 100644 --- a/prog/gameLibs/webui/plugins/ecsviewer/ecsViewerPluginListener.cpp +++ b/prog/gameLibs/webui/plugins/ecsviewer/ecsViewerPluginListener.cpp @@ -131,6 +131,8 @@ static void bson_ecs_component(BsonStream &bson, const char *name, const ecs::En bson_ecs_array(bson, name, comp); else if (comp.is()) bson_ecs_list(bson, name, comp); + else if (comp.is()) + bson_ecs_list(bson, name, comp); else if (comp.is()) bson_ecs_list(bson, name, comp); else if (comp.is()) @@ -700,6 +702,8 @@ struct ECSMessageListener : public websocket::MessageListener SET_TYPE(E3DCOLOR, E3dcolor); else if (type == "ecs::EntityId") SET_TYPE(ecs::EntityId, Int); + else if (type == "TMatrix") + SET_TYPE(TMatrix, Tm); else if (type == "ecs::Object") { ecs::ComponentsList alist; diff --git a/prog/gameLibs/webui/plugins/webView/.gitignore b/prog/gameLibs/webui/plugins/webView/.gitignore index 8c1cbe26a..b0c69b0c9 100644 --- a/prog/gameLibs/webui/plugins/webView/.gitignore +++ b/prog/gameLibs/webui/plugins/webView/.gitignore @@ -1,2 +1,3 @@ web/3rdpartylicenses.txt -*.gypi \ No newline at end of file +*.gypi +*.inl \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/jamfile b/prog/gameLibs/webui/plugins/webView/jamfile index 4e9ce2ea4..27e32034e 100644 --- a/prog/gameLibs/webui/plugins/webView/jamfile +++ b/prog/gameLibs/webui/plugins/webView/jamfile @@ -12,27 +12,44 @@ AddIncludes = $(Root)/prog/dagorInclude ; -Sources = - webViewPlugin.cpp -; +WebViewLocation = $(Root)/$(Location) ; -SourcesWeb = -; +actions together quietly make_serve_files +{ + echo $(var_name) = $(ref_var) ; >$(1:S=.jam) + call $(PYTHON_EXE) $(WebViewLocation)/make_serve_cpp.py $(1) $(var) +} +make_serve_files_DEPS = $(Root)/$(Location)/make_serve_cpp.py ; SourcesWebFolders = - web - web/assets + vue + vue/components + vue/core + vue/vendor + vue/vendor/font-awesome/css + vue/vendor/font-awesome/fonts +; + +ServeFiles = ; -AutoscanBuildLists $(SourcesWebFolders) : *.eot : SourcesWeb ; -AutoscanBuildLists $(SourcesWebFolders) : *.svg : SourcesWeb ; -AutoscanBuildLists $(SourcesWebFolders) : *.ttf : SourcesWeb ; -AutoscanBuildLists $(SourcesWebFolders) : *.woff : SourcesWeb ; -AutoscanBuildLists $(SourcesWebFolders) : *.woff2 : SourcesWeb ; -AutoscanBuildLists $(SourcesWebFolders) : *.js : SourcesWeb ; -AutoscanBuildLists $(SourcesWebFolders) : *.css : SourcesWeb ; -AutoscanBuildLists $(SourcesWebFolders) : *.html : SourcesWeb ; +AutoscanBuildLists $(SourcesWebFolders) : *.vue : ServeFiles ; +AutoscanBuildLists $(SourcesWebFolders) : *.eot : ServeFiles ; +AutoscanBuildLists $(SourcesWebFolders) : *.svg : ServeFiles ; +AutoscanBuildLists $(SourcesWebFolders) : *.ttf : ServeFiles ; +AutoscanBuildLists $(SourcesWebFolders) : *.woff : ServeFiles ; +AutoscanBuildLists $(SourcesWebFolders) : *.woff2 : ServeFiles ; +AutoscanBuildLists $(SourcesWebFolders) : *.js : ServeFiles ; +AutoscanBuildLists $(SourcesWebFolders) : *.css : ServeFiles ; +AutoscanBuildLists $(SourcesWebFolders) : *.html : ServeFiles ; -for s in $(SourcesWeb) { StringifySourceFile $(s) : $(s).inl : webViewPlugin.cpp : --array ; } +StringifySourceFile vue/index.html : vue/index.html.inl : webViewPlugin.cpp : --array ; + +ServeFiles_action = make_serve_files ; + +Sources = + ServeFiles.jamvar + webViewPlugin.cpp +; include $(Root)/prog/_jBuild/build.jam ; diff --git a/prog/gameLibs/webui/plugins/webView/make_serve_cpp.py b/prog/gameLibs/webui/plugins/webView/make_serve_cpp.py new file mode 100644 index 000000000..22bcf1a47 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/make_serve_cpp.py @@ -0,0 +1,49 @@ +import sys +import os + +f = open(sys.argv[1], 'wt') + +srcFiles = sys.argv[2:] +f.write('#include \n') +f.write('#include \n') +f.write('\n') + +funtionTemplate = """static void serve_file_{name}(webui::RequestInfo *params) {{ + static uint8_t inlinedData[] = {{ +#include "{name}.inl" + }}; + webui::html_response_raw(params->conn, "{mime}", (const char *)inlinedData, sizeof(inlinedData) - 1); +}} +""" + +extToMimeType = { + '.html': 'text/html', + '.js': 'text/javascript', + '.css': 'text/css', + '.png': 'image/png', + '.jpg': 'image/jpeg', + '.woff2': 'font/woff2', + '.ttf': 'font/ttf', + '.ico': 'image/x-icon', +} + +rootDir = os.path.dirname(__file__) +dstDir = os.path.abspath(os.path.dirname(sys.argv[1])) +stringifyPy = os.path.normpath(os.path.join(rootDir, '..', '..', '..', '..', '_jBuild', '_scripts', 'stringify.py')) + +for src in srcFiles: + name = os.path.basename(src).replace('.', '_').replace('-', '_') + path = os.path.join(rootDir, src) + ext = os.path.splitext(src)[1] + mime = extToMimeType.get(ext, 'text/plain') + os.system(f'{sys.executable} {stringifyPy} --array {path} {dstDir}/{name}.inl') + f.write(funtionTemplate.format(**locals())) + +f.write('webui::HttpPlugin webui::webview_files_http_plugins[] = {\n') +for src in srcFiles: + name = os.path.basename(src).replace('.', '_').replace('-', '_') + f.write(' {{ "{0}", NULL, NULL, serve_file_{1} }},\n'.format(src, name)) +f.write(' {NULL}\n') +f.write('};\n') + +f.close() diff --git a/prog/gameLibs/webui/plugins/webView/src/.angular-cli.json b/prog/gameLibs/webui/plugins/webView/src/.angular-cli.json deleted file mode 100644 index 320b5b686..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/.angular-cli.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "project": { - "name": "webview" - }, - "apps": [ - { - "root": "app", - "outDir": "dist", - "baseHref": "/webview/", - "assets": [ - "assets", - "favicon.ico" - ], - "index": "index.html", - "main": "main.ts", - "polyfills": "polyfills.ts", - "test": "test.ts", - "tsconfig": "tsconfig.app.json", - "testTsconfig": "tsconfig.spec.json", - "prefix": "my", - "styles": [ - "assets/styles.css", - "../vendor/bootstrap/css/bootstrap-4.0.0.min.css", - "../vendor/font-awesome/css/font-awesome.min.css", - "../node_modules/angular-tree-component/dist/angular-tree-component.css", - "../node_modules/@swimlane/ngx-datatable/src/themes/bootstrap.scss", - "../node_modules/jsoneditor/dist/jsoneditor.min.css" - ], - "scripts": [], - "environmentSource": "environments/environment.ts", - "environments": { - "dev": "environments/environment.ts", - "prod": "environments/environment.prod.ts" - } - } - ], - "defaults": { - "styleExt": "css", - "serve": { - "port": 4010 - }, - "component": {} - } -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/.gitignore b/prog/gameLibs/webui/plugins/webView/src/.gitignore deleted file mode 100644 index 65a5e6034..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules/ -typings/ -dist diff --git a/prog/gameLibs/webui/plugins/webView/src/app/app.component.css b/prog/gameLibs/webui/plugins/webView/src/app/app.component.css deleted file mode 100644 index fb485414e..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/app.component.css +++ /dev/null @@ -1,8 +0,0 @@ -.online { - color: green; - font-weight: bold; -} - -.offline { - color: red; -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/app.component.html b/prog/gameLibs/webui/plugins/webView/src/app/app.component.html deleted file mode 100644 index 7848acd68..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/app.component.html +++ /dev/null @@ -1,14 +0,0 @@ -
-
- Connection status: - {{status}} -
- - - To enable this feature add enableWebSocketStream:b = yes to debug section in config.blk - - -
-
- - \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/app.component.ts b/prog/gameLibs/webui/plugins/webView/src/app/app.component.ts deleted file mode 100644 index 014dac106..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/app.component.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Component, OnInit, NgZone } from '@angular/core'; - -import { StreamService } from './core/stream.service'; -import { CoreService } from './core/core.service'; - -@Component({ - selector: 'my-app', - templateUrl: './app.component.html', - styleUrls: ['./app.component.css'] -}) -export class AppComponent implements OnInit -{ - status: string = "Unknonwn"; - - constructor(private streamService: StreamService, public coreService: CoreService, private zone: NgZone) - { - } - - ngOnInit(): void - { - console.log('AppComponent::OnInit'); - - this.zone.runOutsideAngular(() => - { - setInterval(() => - { - let prev = this.status; - let status = this.streamService.isConnected() ? "Online" : "Offline"; - if (prev !== status) - { - this.zone.run(() => - { - this.status = status; - }) - } - }, 100); - }); - } -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/app.module.ts b/prog/gameLibs/webui/plugins/webView/src/app/app.module.ts deleted file mode 100644 index cf0926160..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/app.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; - -import { CoreModule } from './core/core.module'; -import { AllModule } from './modules/all.module'; - -import { AppComponent } from './app.component'; - -import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { CookieModule } from 'ngx-cookie'; - -@NgModule({ - imports: [BrowserModule, NgbModule.forRoot(), CoreModule.forRoot(/*{userName: 'Miss Marple'}*/), CookieModule.forRoot(), AllModule], - declarations: [AppComponent], - bootstrap: [AppComponent] -}) -export class AppModule { } diff --git a/prog/gameLibs/webui/plugins/webView/src/app/assets/styles.css b/prog/gameLibs/webui/plugins/webView/src/app/assets/styles.css deleted file mode 100644 index 220134592..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/assets/styles.css +++ /dev/null @@ -1,181 +0,0 @@ -/* Master Styles */ -.badge { - display: inline-block; - padding: 0.25em 0.4em; - font-size: 75%; - font-weight: 700; - line-height: 1; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: 0.25rem; -} - -.badge:empty { - display: none; -} - -.btn .badge { - position: relative; - top: -1px; -} - -.badge-pill { - padding-right: 0.6em; - padding-left: 0.6em; - border-radius: 10rem; -} - -.badge-primary { - color: #fff; - background-color: #007bff; -} - -.badge-primary[href]:hover, .badge-primary[href]:focus { - color: #fff; - text-decoration: none; - background-color: #0062cc; -} - -.badge-secondary { - color: #fff; - background-color: #6c757d; -} - -.badge-secondary[href]:hover, .badge-secondary[href]:focus { - color: #fff; - text-decoration: none; - background-color: #545b62; -} - -.badge-success { - color: #fff; - background-color: #28a745; -} - -.badge-success[href]:hover, .badge-success[href]:focus { - color: #fff; - text-decoration: none; - background-color: #1e7e34; -} - -.badge-info { - color: #fff; - background-color: #17a2b8; -} - -.badge-info[href]:hover, .badge-info[href]:focus { - color: #fff; - text-decoration: none; - background-color: #117a8b; -} - -.badge-warning { - color: #212529; - background-color: #ffc107; -} - -.badge-warning[href]:hover, .badge-warning[href]:focus { - color: #212529; - text-decoration: none; - background-color: #d39e00; -} - -.badge-danger { - color: #fff; - background-color: #dc3545; -} - -.badge-danger[href]:hover, .badge-danger[href]:focus { - color: #fff; - text-decoration: none; - background-color: #bd2130; -} - -.badge-light { - color: #212529; - background-color: #f8f9fa; -} - -.badge-light[href]:hover, .badge-light[href]:focus { - color: #212529; - text-decoration: none; - background-color: #dae0e5; -} - -.badge-dark { - color: #fff; - background-color: #343a40; -} - -.badge-dark[href]:hover, .badge-dark[href]:focus { - color: #fff; - text-decoration: none; - background-color: #1d2124; -} - -@media print { - *, - *::before, - *::after { - text-shadow: none !important; - box-shadow: none !important; - } - a:not(.btn) { - text-decoration: underline; - } - abbr[title]::after { - content: " (" attr(title) ")"; - } - pre { - white-space: pre-wrap !important; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } - @page { - size: a3; - } - body { - min-width: 992px !important; - } - .container { - min-width: 992px !important; - } - .navbar { - display: none; - } - .badge { - border: 1px solid #000; - } - .table { - border-collapse: collapse !important; - } - .table td, - .table th { - background-color: #fff !important; - } - .table-bordered th, - .table-bordered td { - border: 1px solid #ddd !important; - } -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/core/core.module.ts b/prog/gameLibs/webui/plugins/webView/src/app/core/core.module.ts deleted file mode 100644 index 8558d9b10..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/core/core.module.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { StreamService } from './stream.service'; -import { CoreService } from './core.service'; -import { SettingsService } from './settings.service'; -import { HttpClientModule } from '@angular/common/http'; - -@NgModule({ - imports: [CommonModule, HttpClientModule], - providers: [StreamService, CoreService, SettingsService] -}) -export class CoreModule { - static forRoot(/*config: UserServiceConfig*/): ModuleWithProviders { - return { - ngModule: CoreModule, - providers: [/*{ provide: UserServiceConfig, useValue: config }*/] - }; - } - - constructor( @Optional() @SkipSelf() parentModule: CoreModule) { - if (parentModule) { - throw new Error('CoreModule is already loaded. Import it in the AppModule only'); - } - } -} diff --git a/prog/gameLibs/webui/plugins/webView/src/app/core/core.service.ts b/prog/gameLibs/webui/plugins/webView/src/app/core/core.service.ts deleted file mode 100644 index 02b146905..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/core/core.service.ts +++ /dev/null @@ -1,344 +0,0 @@ -import { Injectable } from '@angular/core'; -import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap'; - -import { Observable } from 'rxjs/Observable'; -import { Subscription } from 'rxjs/Subscription'; -import { map } from 'rxjs/operator/map'; -import { debounceTime } from 'rxjs/operator/debounceTime'; -import { distinctUntilChanged } from 'rxjs/operator/distinctUntilChanged'; - -import { StreamService, deserializeBSON } from './stream.service'; - -import { CookieService } from 'ngx-cookie'; -import { UUID } from 'angular2-uuid'; - -import * as common from './common'; - -const UPDATE_INTERVAL_MS: number = 500; - -@Injectable() -export class CoreService -{ - private _listeners: Array = []; - - private _observable: Observable = null; - - private _messagesObservable: Observable = null; - - private _updateCount: number = 0; - - private _updateTimeout: NodeJS.Timer = null; - - private _commonParams: any = {}; - - private _commandDomains: string[] = []; - private _commands: any = []; - - private _consoleCommands: any = []; - private _consoleCommandNames: any = []; - private _searchConsoleCommand: Function = null; - - private _lastCommandName: string = ''; - private _lastCommand: any = null; - - constructor(public streamService: StreamService, public cookieService: CookieService, public modalService: NgbModal) - { - console.log('CoreService::CoreService'); - - this._searchConsoleCommand = (text$: Observable) => - { - return map.call(distinctUntilChanged.call(debounceTime.call(text$, 200)), - term => term.length < 2 ? [] : this._consoleCommandNames.filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10)); - }; - - this._lastCommandName = this.cookieService.get("_lastCommandName"); - if (!this._lastCommandName) - this._lastCommandName = ''; - - this.streamService.onOpen(() => { this.processOpen(); }); - - this._observable = Observable.create(observer => - { - this.streamService.onMessage((message) => { this.processMessage(observer, message); }); - }); - - this._observable.subscribe(value => { this.processValue(value); }); - - if (this.streamService.isConnected()) - this.onOpen(); - } - - addListener(listener: common.IMessageListener) - { - this._listeners.push(listener); - - if (this.streamService.isConnected()) - listener.onOpen(); - } - - onOpen(): void - { - console.log('CoreService::onOpen'); - - this.sendCommand('onOpen'); - this.sendCommand('getConsoleCommandsList'); - - if (!this._commandDomains.length) - this.sendCommand('getCommandsList'); - - for (let listener of this._listeners) - { - listener.onOpen(); - } - } - - onMessage(data): void - { - if (data._update) - { - ++this._updateCount; - } - - if (data.commonParams) - this._commonParams = data.commonParams; - - if (data.commandsJson && !this._commandDomains.length) - { - this._commands = JSON.parse(data.commandsJson); - - if (this._commands.common) - { - this._commands.common = this._commands.common.filter(v => v.cmd !== '__sample'); - if (!this._commands.common.length) - delete this._commands.common; - } - - this._commandDomains = Object.keys(this._commands); - - if (this._lastCommandName !== '') - { - for (let domain of this._commandDomains) - { - for (let command of this._commands[domain]) - { - let cmd = command.console ? command.console : command.cmd; - if (this._lastCommandName === cmd) - { - this._lastCommandName; - this._lastCommand = command; - break; - } - } - } - } - } - - if (data.consoleCommands) - { - this._consoleCommands = data.consoleCommands; - this._consoleCommandNames = this._consoleCommands.map(v => v.name + ' x'.repeat(v.minArgs - 1) + ' [x]'.repeat(v.maxArgs - v.minArgs)); - } - - for (let listener of this._listeners) - { - listener.onMessage(data); - } - } - - continueUpdate(force: boolean = false): void - { - if (force) - { - if (this._updateTimeout != null) - clearTimeout(this._updateTimeout); - this._updateTimeout = null; - } - - if (this._updateTimeout === null) - this._updateTimeout = global.setTimeout(() => { this.sendCommand('update'); }, UPDATE_INTERVAL_MS); - } - - processOpen(): void - { - this.onOpen(); - this.continueUpdate(true); - } - - processMessage(observer, message): void - { - if (typeof message === 'object' && message.constructor && message.constructor.name === 'Blob') - { - let reader = new FileReader(); - reader.addEventListener("loadend", () => - { - observer.next(deserializeBSON(new Uint8Array(reader.result))); - this.continueUpdate(); - }); - reader.readAsArrayBuffer(message); - } - else - { - let json = {}; - try - { - json = JSON.parse(message); - } - catch (err) - { - json = { log: message }; - } - observer.next(json); - } - } - - processValue(data): void - { - this.onMessage(data); - - if (data._update) - { - if (this._updateTimeout !== null) - clearTimeout(this._updateTimeout); - this._updateTimeout = null; - } - } - - sendCommand(cmd: string, params: any = null): void - { - let tmp = params || {}; - tmp.cmd = cmd; - this.streamService.send(tmp); - } - - pollData(dataGetter: Function, cmd, params = null): Promise - { - return new Promise((resolve, reject) => - { - let isDataValid = d => { return (typeof (d.length) !== undefined && d.length > 0) || (typeof (d.length) === undefined && d); } - - let data = dataGetter(); - if (isDataValid(data)) - { - resolve(data); - return; - } - - this.sendCommand(cmd, params); - let pollId = global.setInterval(() => - { - let data = dataGetter(); - if (isDataValid(data)) - { - global.clearInterval(pollId); - resolve(data); - } - }, 100); - }); - } - - runConsoleRaw(data: string): void - { - let cmd; - let params = {}; - let args = data.split(' '); - cmd = args[0]; - for (let i = 1; i < args.length; ++i) - { - params['arg' + (i - 1)] = args[i]; - } - this.runConsole(cmd, params); - } - - runConsole(cmd: string, params: any = null): void - { - let tmp = params || {}; - tmp.command = cmd; - this.sendCommand('console', tmp); - } - - runConsoleScript(commands: any): void - { - for (let cmd of commands) - { - this.runConsole(cmd[0], cmd[1] ? cmd[1] : null); - } - } - - buildAndSendCommand(command) - { - this._lastCommandName = command.console ? command.console : command.cmd; - this._lastCommand = command; - this.cookieService.put("_lastCommandName", this._lastCommandName); - - if (command.console) - { - let consoleStr = command.console; - - for (let p of command.params) - { - if (p.value === undefined) - continue; - - if (Array.isArray(p.value)) - consoleStr += ' ' + (>p.value).concat(' '); - else if (typeof (p.value) === 'boolean') - consoleStr += ' ' + (p.value ? 'on' : 'off'); - else - consoleStr += ' ' + p.value; - } - - console.log(command, consoleStr); - - this.runConsoleRaw(consoleStr); - - return; - } - - let params = {}; - - for (let p of command.params) - { - if (p.value === undefined) - continue; - - let type = p.type; - if (['dmPart', 'enum', 'b'].indexOf(p.type) >= 0) - { - params[p.name] = p.value; - } - else - { - params[p.name] = {}; - params[p.name][type] = p.value; - } - } - - console.log(command, params); - - this.sendCommand(command.cmd, params); - } - - resetTimeSpeed() - { - this._commonParams['timespeed'] = 1; - } - - get isConnected() { return this.streamService.isConnected(); }; - - get updateCount(): number { return +this._updateCount; } - - set messagesObservable(value) { this._messagesObservable = value; } - get messagesObservable() { return this._messagesObservable; } - - get observable() { return this._observable; } - - get commonParams() { return this._commonParams; } - - get commandDomains() { return this._commandDomains; } - get commands() { return this._commands; } - - get consoleCommands() { return this._consoleCommands; } - get searchConsoleCommand() { return this._searchConsoleCommand; } - - get lastCommand() { return this._lastCommand; } -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/core/settings.service.ts b/prog/gameLibs/webui/plugins/webView/src/app/core/settings.service.ts deleted file mode 100644 index 37d6e9f6a..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/core/settings.service.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; - -export interface Settings -{ - port: number; -} - -@Injectable() -export class SettingsService -{ - private _defaultSettings: Settings = { port: 9113 }; - private _settings: Settings = null; - - private _settingsPromise: Promise = null; - - constructor(public http: HttpClient) - { - } - - getSettings(): Promise - { - if (this._settingsPromise === null) - { - this._settingsPromise = new Promise((resolve, reject) => - { - let onDone = (data: Settings) => - { - console.log('Settings', data); - - this._settingsPromise = null; - this._settings = data; - resolve(this._settings); - }; - - if (this._settings !== null) - { - resolve(this._settings); - } - else - { - this.http.get(`${location.href}/settings.json`).subscribe((data: Settings) => onDone(data), (error) => { console.log('Settings error', error); onDone(this._defaultSettings); }); - } - }); - } - return this._settingsPromise; - } -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/core/stream.service.ts b/prog/gameLibs/webui/plugins/webView/src/app/core/stream.service.ts deleted file mode 100644 index fbdeb50a5..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/core/stream.service.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Injectable } from '@angular/core'; -import { $WebSocket } from 'angular2-websocket/angular2-websocket'; - -import { Observable } from 'rxjs/Observable'; - -import * as common from './common'; -import { SettingsService } from './settings.service'; -import { resolve } from 'path'; - -var bson = require('../../vendor/bson.js'); - -export function deserializeBSON(buffer: any): any -{ - let BSON = bson().BSON - return BSON.deserialize(buffer); -} - -@Injectable() -export class StreamService -{ - socket: $WebSocket; - - private _socketPromise: Promise<$WebSocket> = null; - - constructor(public settingsService: SettingsService) - { - } - - init(): Promise<$WebSocket> - { - if (this._socketPromise === null) - { - this._socketPromise = new Promise((resolve, reject) => - { - if (this.socket) - { - this._socketPromise = null; - resolve(this.socket); - return; - } - - this.settingsService.getSettings().then(settings => - { - this.socket = new $WebSocket(`ws://localhost:${settings.port}/stream`, null, { initialTimeout: 500, maxTimeout: 5000, reconnectIfNotNormalClose: true }); - - this._socketPromise = null; - resolve(this.socket); - }); - }); - } - return this._socketPromise; - } - - onOpen(callback: Function): void - { - this.init().then(socket => socket.onOpen(() => callback())); - } - - onMessage(callback: Function): void - { - this.init().then(socket => socket.onMessage((event: MessageEvent) => callback(event.data), null)); - } - - isConnected(): boolean - { - this.init(); - return this.socket && this.socket.getReadyState() == 1; - } - - send(json: any): void - { - if (this.socket === null || this.socket.getReadyState() !== 1) - { - return; - } - - this.socket.send(common.jsonToBLK(json)).subscribe(); - } - - sendString(jsonString: string): void - { - if (this.socket === null || this.socket.getReadyState() !== 1) - { - return; - } - - this.socket.send(jsonString).subscribe(); - } -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/environments/environment.prod.ts b/prog/gameLibs/webui/plugins/webView/src/app/environments/environment.prod.ts deleted file mode 100644 index babe05e3e..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/environments/environment.prod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: true -}; \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/environments/environment.ts b/prog/gameLibs/webui/plugins/webView/src/app/environments/environment.ts deleted file mode 100644 index 9923be365..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/environments/environment.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: false -}; \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/index.html b/prog/gameLibs/webui/plugins/webView/src/app/index.html deleted file mode 100644 index 06e9dbf74..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - Enlist Debug - - - - - - Loading... - - \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/main.ts b/prog/gameLibs/webui/plugins/webView/src/app/main.ts deleted file mode 100644 index 91a439a63..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { AppModule } from './app.module'; - -platformBrowserDynamic().bootstrapModule(AppModule); \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/modules/all.module.ts b/prog/gameLibs/webui/plugins/webView/src/app/modules/all.module.ts deleted file mode 100644 index a75f04be2..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/modules/all.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { NgModule } from '@angular/core'; -import { SharedModule } from '../shared/shared.module'; - -import { DMModule } from './dm/dm.module'; -import { EditorModule } from './editor/editor.module'; -import { ECSModule } from './ecs/ecs.module'; - -@NgModule({ - imports: [SharedModule, DMModule, EditorModule, ECSModule], - declarations: [], - exports: [DMModule, EditorModule, ECSModule] -}) -export class AllModule { } \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.component.css b/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.component.css deleted file mode 100644 index e62a206b8..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.component.css +++ /dev/null @@ -1,35 +0,0 @@ -.clickable { - cursor: pointer; -} - -span.clickable { - min-height: 20px; - display: block; -} - -.ngx-datatable.scroll-vertical { - height: 80vh; -} - -.ecs-item-type { - font-size: 8pt; - font-weight: bold; -} - -.ecs-item-es { - color: #12A; -} -.ecs-item-te { - color: #919; -} - -.ecs-info { - font-weight: bold; - font-size: 10px; - vertical-align: bottom; -} - -.btn-in-components-row { - padding: 2px; - font-size: 10px; -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.component.html b/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.component.html deleted file mode 100644 index f14f219ce..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.component.html +++ /dev/null @@ -1,1087 +0,0 @@ - - - - - - - - - - - - - - - - - - - -
-
-
- Systems - - - - - - - - - -
Name
{{s.name}} {{s.tags}}
-
-
-
-
- - -
-
-
- Components - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameType
Read-Write
{{c.name}} optional{{c.type}}
Read-Only
{{c.name}} optional{{c.type}}
Required
{{c.name}} optional{{c.type}}
Required Not
{{c.name}} optional{{c.type}}
-
- -
- Templates - - - - - - - - - - - -
NameCount
{{t}}{{row._templates[t]}}
-
- -
- Events - - - - - - - - - -
Name
{{e}}
-
-
-
-
- - -
-
-
- Components - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameType
Read-Write
{{c.name}} optional{{c.type}}
Read-Only
{{c.name}} optional{{c.type}}
Required
{{c.name}} optional{{c.type}}
Required Not
{{c.name}} optional{{c.type}}
-
- -
- Templates - - - - - - - - - - - -
NameCount
{{t}}{{row._templates[t]}}
-
-
-
-
- - - - -
-
-
- -
-
- -
-
- -
-
-
- - - - - -
-
- Components ({{row.components.length}}) - - - - - - - - - - - - - - - - - - - -
NameTypeValue
{{attr.name}} - tracked - replicated - do not replicate - - {{attr.type}}[Click to see value]{{attr.type}} -
-
-
- - -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
-
- -
-
-
- - -
-
-
- - - {{getAttrValue(attr)}} - {{formatValue(attr.value)}} - - -
-
- -
- Systems ({{row._systemsFn().length}}) -
- {{s.name}} -
- Queries ({{row._queriesFn().length}}) -
- {{s.name}} -
-
-
-
-
- - - - - - - - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - - Systems: {{row._systemsFn().length}} - - - - - - {{column.name}} - - - Queries: {{row._queriesFn().length}} - - -
-
-
- - -
-
-
- -
-
-
- - - - - -
-
-
- Templates - - - - - - - - - - - -
In TemplateFrom Template
{{templates[t.templateId].name}}{{templates[t.sourceTemplateId].name}}
-
- -
- Systems - - - - - - - - - -
Name
{{s.system.name}} {{s.mode}}
-
- -
- Queries - - - - - - - - - -
Name
{{q.query.name}} {{q.mode}}
-
-
-
-
-
- - - - - - - - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - {{value}} - - -
- -
-
- - -
-
-
- -
-
-
- - - - - - - - - - - - - - - - - - - - {{column.name}} - - - {{value}} - {{row.tags}} - - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - - RW: {{row.componentsRW.length}} - RO: {{row.componentsRO.length}} - RQ: {{row.componentsRQ.length}} - NO: {{row.componentsNO.length}} - - - - - -
-
- - -
-
-
- -
-
-
- - - - - - - - - - - - - - - - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - - RW: {{row.componentsRW.length}} - RO: {{row.componentsRO.length}} - RQ: {{row.componentsRQ.length}} - NO: {{row.componentsNO.length}} - - - - - -
-
- - -
-
-
- -
-
-
- - - - - - - - - - - - - - - - - - - - {{column.name}} - - - {{value}} - unicast - broadcast - - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - {{value}} - - - - -
-
- - -
-
-
- -
-
-
- - - - - -
-
-
- Components - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeValue
{{row.name}}
{{attr.name}} tracked replicated{{attr.type}}[Click to see value] - - - {{getAttrValue(attr)}} - {{formatValue(attr.value)}} - - {{formatValue(attr.value)}} - -
{{parent.name}}
{{parentAttr.name}} tracked replicated{{parentAttr.type}}[Click to see value] - - - {{getAttrValue(parentAttr)}} - {{formatValue(parentAttr.value)}} - - {{formatValue(parentAttr.value)}} - -
-
-
- Systems ({{row._systems.length}}) -
- {{s.name}} -
- Queries ({{row._queries.length}}) -
- {{s.name}} -
-
-
-
-
-
- - - - - - - - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - - Components: {{row._componentsCount}} - Tracked: {{row._trackedCount}} - Replicated: {{row._replicatedCount}} - - - - - - {{column.name}} - - - Systems: {{row._systems.length}} - - - - - - {{column.name}} - - - Queries: {{row._queries.length}} - - - -
- -
-
- - -
-
-
- - -
-
-
- - - - - -
-
- Components ({{row.components.length}}) - - - - - - - - - - - - - - - - - - - -
NameTypeValue
{{attr.name}} - tracked - replicated - do not replicate - {{attr.type}}[Click to see value]{{attr.type}} -
-
-
- - -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
-
- -
-
-
- - -
-
-
- - - {{getAttrValue(attr)}} - {{formatValue(attr.value)}} - - -
-
-
-
-
- - - - - - - - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - {{value}} - - - - - {{column.name}} - - {{value}} - -
- -
-
-
\ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.component.ts b/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.component.ts deleted file mode 100644 index 63db081f7..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.component.ts +++ /dev/null @@ -1,492 +0,0 @@ -import { Component, OnInit, OnDestroy, ViewChild, Pipe, PipeTransform, TemplateRef } from '@angular/core'; - -import * as common from '../../core/common'; - -import { StreamService, deserializeBSON } from '../../core/stream.service'; -import { CoreService } from '../../core/core.service'; -import { ECSService } from './ecs.service'; - -import { Observable } from 'rxjs/Observable'; -import { CookieService } from 'ngx-cookie'; -import { DatatableComponent, NgxDatatableModule } from '@swimlane/ngx-datatable'; -import { JsonEditorOptions, JsonEditorComponent } from 'ang-jsoneditor'; - -const UPDATE_INTERVAL_MS = 500; - -@Pipe({ name: 'attrValue' }) -export class AttrValuePipe implements PipeTransform { - transform(attr: any) { - if (attr.type === 'E3DCOLOR') - { - console.log('pipe', attr.value); - const toh = v => ('0' + v.toString(16)).substr(-2); - return '#' + toh(attr.value.r) + toh(attr.value.g) + toh(attr.value.b); - } - return attr.value; - } -} - -@Component - ({ - selector: 'ecs', - templateUrl: './ecs.component.html', - styleUrls: ['./ecs.component.css'] - }) -export class ECSComponent extends common.BaseComponent implements OnInit, OnDestroy -{ - @ViewChild('ecsTable') table: DatatableComponent; - @ViewChild('ecsComponentsTable') componentsTable: DatatableComponent; - @ViewChild('ecsTemplatesTable') templatesTable: DatatableComponent; - @ViewChild('ecsSystemsTable') systemsTable: DatatableComponent; - @ViewChild('ecsQueriesTable') queriesTable: DatatableComponent; - @ViewChild('ecsEventsTable') eventsTable: DatatableComponent; - @ViewChild('ecsDynamicQueryTable') dynamicQueryTableTable: DatatableComponent; - - @ViewChild('ecsInfoPopup') ecsInfoPopupTemplate: TemplateRef; - @ViewChild('systemsRow') systemsRowTemplate: TemplateRef; - @ViewChild('queriesRow') queriesRowTemplate: TemplateRef; - @ViewChild('eventsRow') eventsRowTemplate: TemplateRef; - - currentRow: any = {}; - currentAttr: any = {}; - - currentTemplate: TemplateRef; - currentContext: any = {}; - - editorOptions: JsonEditorOptions; - - constructor(public coreService: CoreService, public ecsService: ECSService) - { - super(coreService); - - this.editorOptions = new JsonEditorOptions(); - this.editorOptions.modes = ['code', 'tree']; - } - - ngOnInit(): void - { - console.log('ECSComponent::OnInit'); - super.ngOnInit(); - } - - ngOnDestroy(): void - { - console.log('ECSComponent::OnDestroy'); - super.ngOnDestroy(); - } - - getRowHeight(row) - { - return 50; - } - - getRowDetailHeight(row) - { - if (!row) - return; - let h = 80 + 30 * (row.components ? row.components.length : 0); - let h1 = 80 + 19 * (row._systemsFn ? row._systemsFn().length : 0); - let h2 = 80 + 19 * (row._queriesFn ? row._queriesFn().length : 0); - return Math.max(h, h1 + h2); - } - - getRowDetailHeightComponent(row) - { - if (!row) - return; - - let h = 80; - if (row._templatesFn) { h += 30 * row._templatesFn().length; } - - let h1 = 80; - if (row._systems) { h1 += 30 * row._systems.length; } - - let h2 = 80; - if (row._queries) { h1 += 30 * row._queries.length; } - - return Math.max(h, h1, h2); - } - - getRowDetailHeightTemplate(row) - { - if (!row) - return; - - let h = 80 + 30; - - if (row.components) { h += 30 * row.components.length; } - if (row.parents) - { - let calcHeight = p => { h += 30 + 30 * p._template.components.length; p._template.parents.forEach(p => calcHeight(p)); } - row.parents.forEach(p => calcHeight(p)); - } - - let h1 = 80 + 19 * (row._systems ? row._systems.length : 0); - let h2 = 80 + 19 * (row._queries ? row._queries.length : 0); - - return Math.max(h, h1 + h2); - } - - getRowDetailHeightSystem(row) - { - if (!row) - return; - let h = 80; - if (row.componentsRW && row.componentsRW.length) { h += 30 + 30 * row.componentsRW.length; } - if (row.componentsRO && row.componentsRO.length) { h += 30 + 30 * row.componentsRO.length; } - if (row.componentsRQ && row.componentsRQ.length) { h += 30 + 30 * row.componentsRQ.length; } - if (row.componentsNO && row.componentsNO.length) { h += 30 + 30 * row.componentsNO.length; } - - let h1 = 80; - if (row._templateNames) { h1 += 30 * row._templateNames.length; } - - let h2 = 80; - if (row.events) { h2 += 30 * row.events.length; } - - return Math.max(h, h1, h2); - } - - getRowDetailHeightQuery(row) - { - if (!row) - return; - let h = 80; - if (row.componentsRW && row.componentsRW.length) { h += 30 + 30 * row.componentsRW.length; } - if (row.componentsRO && row.componentsRO.length) { h += 30 + 30 * row.componentsRO.length; } - if (row.componentsRQ && row.componentsRQ.length) { h += 30 + 30 * row.componentsRQ.length; } - if (row.componentsNO && row.componentsNO.length) { h += 30 + 30 * row.componentsNO.length; } - - let h1 = 80; - if (row._templateNames) { h1 += 30 * row._templateNames.length; } - - return Math.max(h, h1); - } - - getRowDetailHeightEvent(row) - { - if (!row) - return; - return 80 + 30 * (row._systems ? row._systems.length : 0); - } - - fetchEnities(): void - { - this.ecsService.fetchEntities(); - } - - toggleExpandRow(row, expanded) - { - console.log('Toggled Expand Row!', row, expanded); - - if (expanded) { - this.table.rowDetail.toggleExpandRow(row); - } - else { - this.ecsService.fetchEntityAttributes(row.eid).then((entity) => { - console.log('onFetchEntityAttributes', entity); - console.time('EntityAttributesExpand'); - this.table.rowDetail.toggleExpandRow(row); - console.timeEnd('EntityAttributesExpand'); - }); - } - } - - toggleExpandRowDynamicQuery(row, expanded) - { - console.log('Toggled Expand Row!', row, expanded); - - if (expanded) { - this.dynamicQueryTableTable.rowDetail.toggleExpandRow(row); - } - else { - this.dynamicQueryTableTable.rowDetail.toggleExpandRow(row); - } - } - - toggleExpandRowComponent(row) - { - console.log('Toggled Expand Row!', row); - this.componentsTable.rowDetail.toggleExpandRow(row); - } - - toggleExpandRowTemplate(row) - { - console.log('Toggled Expand Row!', row); - this.templatesTable.rowDetail.toggleExpandRow(row); - } - - toggleExpandRowSystem(row) - { - console.log('Toggled Expand Row!', row); - this.systemsTable.rowDetail.toggleExpandRow(row); - } - - toggleExpandRowQuery(row) - { - console.log('Toggled Expand Row!', row); - this.queriesTable.rowDetail.toggleExpandRow(row); - } - - toggleExpandRowEvent(row) - { - console.log('Toggled Expand Row!', row); - this.eventsTable.rowDetail.toggleExpandRow(row); - } - - onDetailToggle(event) - { - console.log('Detail Toggled', event); - } - - updateFilter(event) - { - const val = event.target.value.toLowerCase(); - this.ecsService.filterEntities = val; - this.table.offset = 0; - } - - updateFilterByEid(event) - { - const val = event.target.value.toLowerCase(); - this.ecsService.filterEntitiesByEid = val; - this.table.offset = 0; - } - - updateFilterComponents(event) - { - const val = event.target.value.toLowerCase(); - this.ecsService.filterComponents = val; - this.componentsTable.offset = 0; - } - - updateFilterTemplates(event) - { - const val = event.target.value.toLowerCase(); - this.ecsService.filterTemplates = val; - this.templatesTable.offset = 0; - } - - updateFilterSystems(event) - { - const val = event.target.value.toLowerCase(); - this.ecsService.filterSystems = val; - this.systemsTable.offset = 0; - } - - updateFilterQueries(event) - { - const val = event.target.value.toLowerCase(); - this.ecsService.filterQueries = val; - this.queriesTable.offset = 0; - } - - updateFilterEvents(event) - { - const val = event.target.value.toLowerCase(); - this.ecsService.filterEvents = val; - this.eventsTable.offset = 0; - } - - shouldOpenEditor(comp: any) - { - return [ - 'ecs::Object', - 'ecs::Array', - 'ecs::IntList', - 'ecs::UInt16List', - 'ecs::StringList', - 'ecs::EidList', - 'ecs::FloatList', - 'ecs::Point2List', - 'ecs::Point3List', - 'ecs::Point4List', - 'ecs::IPoint2List', - 'ecs::IPoint3List', - 'ecs::IPoint4List', - 'ecs::BoolList', - 'ecs::ColorList', - 'ecs::TMatrixList', - 'ecs::Int64List', - ].indexOf(comp.type) >= 0; - } - - getAttrValue(attr: any) - { - if (attr.type === 'E3DCOLOR') - { - const toh = v => ('0' + v.toString(16)).substr(-2); - return '#' + toh(attr.value.r) + toh(attr.value.g) + toh(attr.value.b); - } - return attr.value; - } - - openAttr(row, attr, content) - { - if (this.shouldOpenEditor(attr) || attr.type === 'E3DCOLOR') - { - this.currentRow = row; - this.currentAttr = attr; - this.open(content); - } - } - - startEdit(attr) - { - if (attr.type === 'E3DCOLOR') - { - return; - } - - attr._edit = true; - attr._new_value = null; - - console.log('startEdit', attr); - } - - cancelEdit(attr) - { - attr._edit = false; - attr._new_value = null; - } - - saveEdit(row, attr) - { - if (row.eid === undefined) - { - return; - } - - console.log('saveEdit', attr, attr._new_value); - - attr._edit = false; - if (attr._new_value !== null && attr._new_value !== undefined) - { - this.ecsService.setEntityAttribute(row.eid, attr, attr._new_value); - } - } - - updateValue(ev, row, val, attr, key = null) - { - const setByKey = v => - { - let res = {}; - let curVal = attr._new_value === null ? attr.value : attr._new_value; - for (let k in curVal) - { - res[k] = curVal[k]; - } - res[key] = +val; - return res; - }; - - const convert = - { - E3DCOLOR: v => - { - const toi = (v, s) => parseInt(v.substring(1 + s * 2, 3 + s * 2), 16); - return { - r: toi(attr._color, 0), g: toi(attr._color, 1), b: toi(attr._color, 2), a: toi(attr._color, 3) - } - }, - int: v => setByKey(v), - float: v => setByKey(v), - Point2: v => setByKey(v), - Point3: v => setByKey(v), - Point4: v => setByKey(v), - }; - - const valueToSet = convert[attr.type] ? convert[attr.type](val) : val; - - console.log('updateValue', attr, valueToSet); - - attr._new_value = valueToSet; - - console.log(ev); - if (ev.code === "Enter" || ev.type === "change") { - this.saveEdit(row, attr); - } - else if (ev.code === "Escape") { - this.cancelEdit(attr); - } - } - - saveObject(row, attr, editor: JsonEditorComponent = null) - { - if (row.eid === undefined) - { - return; - } - - if (editor) - { - this.updateValue({}, row, editor.get(), attr); - this.ecsService.setEntityAttribute(row.eid, attr, attr._new_value); - } - else - { - this.saveEdit(row, attr); - } - } - - getDisplayForEditor(): string - { - return this.currentAttr.type === 'E3DCOLOR' ? 'none' : 'block'; - } - - clickSystem(sys) - { - this.currentTemplate = this.systemsRowTemplate; - this.currentContext = { $implicit: sys }; - - this.open(this.ecsInfoPopupTemplate, { size: 'lg' }); - } - - clickQuery(q) - { - this.currentTemplate = this.queriesRowTemplate; - this.currentContext = { $implicit: q }; - - this.open(this.ecsInfoPopupTemplate, { size: 'lg' }); - } - - clickEvents(q) - { - this.currentTemplate = this.eventsRowTemplate; - this.currentContext = { $implicit: q }; - - this.open(this.ecsInfoPopupTemplate, { size: 'lg' }); - } - - saveDynamicQuery(editor: JsonEditorComponent = null, filter: HTMLInputElement = null) - { - if (filter) - { - this.ecsService.dynamicQueryFilter = filter.value; - } - if (editor) - { - this.ecsService.dynamicQuery = editor.get(); - } - } - - performDynamicQuery() - { - this.ecsService.performDynamicQuery() - } - - get entities() { return this.ecsService.entities; } - get dynamicQueryEntities() { return this.ecsService.dynamicQueryEntities; } - get components() { return this.ecsService.components; } - get systems() { return this.ecsService.systems; } - get queries() { return this.ecsService.queries; } - get events() { return this.ecsService.events; } - get templates() { return this.ecsService.templates; } - - set dynamicQuery(value) { this.ecsService.dynamicQuery = value; } - get dynamicQuery() { return this.ecsService.dynamicQuery; } - - set dynamicQueryFilter(value) { this.ecsService.dynamicQueryFilter = value; } - get dynamicQueryFilter() { return this.ecsService.dynamicQueryFilter; } - - get dynamicQueryColumns() { return this.ecsService.dynamicQueryColumns; } -} diff --git a/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.module.ts b/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.module.ts deleted file mode 100644 index b76e1f0e0..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { NgModule } from '@angular/core'; -import { SharedModule } from '../../shared/shared.module'; - -import { ECSComponent, AttrValuePipe } from './ecs.component'; -import { ECSService } from './ecs.service'; - -import { TreeModule } from 'angular-tree-component'; -import { NgbModule, NgbTabsetModule } from '@ng-bootstrap/ng-bootstrap'; - -import { NgxDatatableModule } from '@swimlane/ngx-datatable'; -import { ColorPickerModule } from 'ngx-color-picker'; -import { NgJsonEditorModule } from 'ang-jsoneditor' - -@NgModule({ - imports: [SharedModule, TreeModule, NgbModule, NgbTabsetModule, NgxDatatableModule, ColorPickerModule, NgJsonEditorModule], - declarations: [ECSComponent, AttrValuePipe], - exports: [ECSComponent], - providers: [ECSService] -}) -export class ECSModule { } diff --git a/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.component.css b/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.component.css deleted file mode 100644 index 9f1a4fb73..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.component.css +++ /dev/null @@ -1,63 +0,0 @@ -.log textarea, .log code { - display: block; - width: 100%; - /*height: 95%;*/ - border: 0px; - white-space: pre; - /*margin-top: 100px;*/ -} - -#log-stream { - white-space: pre; - height: 56%; - display: block; - overflow-y: scroll; - font-size: 14px; -} - -:host >>> tr.disabled, a.disabled, .edit-mode-disabled { - opacity: 0.5; -} - -.block-with-border { - border: solid 1px black; - padding: 10px; - margin-top: -1px; -} - -.fixed-panel-top { - position: fixed; - top: 0; - z-index: 100; -} - -.fixed-panel-right { - position: fixed; - right: 0; - z-index: 100; -} - -.menu-button { - position: fixed; - right: 0; - top: 0; - z-index: 200; -} - -span.extender { - visibility: hidden; - width: 0px; - display: inline-block; -} - -:host >>> .unit-row { - height: 36px; -} - -:host >>> .card-block-no-padding .card-body { - padding: 0; -} - -:host >>> .fixed-panel-right .card-body { - padding: 0; -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.component.html b/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.component.html deleted file mode 100644 index d41f1a528..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.component.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - -
-
-
-
Console
- - -
- - - - -
-
{{c.name}}
- -
- - - -
-
-
-
-
-
-
- -
-
- -
-
\ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.component.ts b/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.component.ts deleted file mode 100644 index 3a20b0d2b..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.component.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Component, OnInit, OnDestroy, Pipe, PipeTransform } from '@angular/core'; -import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap'; - -import * as common from '../../core/common'; - -import { StreamService, deserializeBSON } from '../../core/stream.service'; -import { CoreService } from '../../core/core.service'; -import { DMService } from '../dm/dm.service'; - -import { Observable } from 'rxjs/Observable'; -import { CookieService } from 'ngx-cookie'; - -const UPDATE_INTERVAL_MS = 500; - -@Component({ - selector: 'editor', - templateUrl: './editor.component.html', - styleUrls: ['./editor.component.css'] -}) -export class EditorComponent extends common.BaseComponent implements OnInit, OnDestroy -{ - showCommands: boolean = false; - - constructor(public coreService: CoreService, public dmService: DMService) - { - super(coreService); - } - - ngOnInit(): void - { - super.ngOnInit(); - - let tab = this.coreService.cookieService.get('_currentTab'); - if (tab) - { - this.currentTab = tab; - this.onTabChange(tab); - } - - console.log('EditorComponent::OnInit'); - } - - ngOnDestroy(): void - { - super.ngOnDestroy(); - } - - resetTimeSpeed() - { - this.coreService.resetTimeSpeed(); - } - - needShowCopyAlert: boolean = false; - - showCopyAlery(): void - { - this.needShowCopyAlert = true; - setTimeout(() => this.needShowCopyAlert = false, 1000); - } - - needShowSaveAlert: boolean = false; - - showSaveAlert(): void - { - this.needShowSaveAlert = true; - setTimeout(() => this.needShowSaveAlert = false, 5000); - } - - menuVisible: boolean = false; - - toggleMenu() - { - this.menuVisible = !this.menuVisible; - } - - currentTab: string = 'Main'; - - selectTab($event, tab): void - { - $event.preventDefault(); - this.currentTab = tab; - - this.coreService.cookieService.put('_currentTab', this.currentTab); - - this.onTabChange(tab); - } - - onTabChange(tab): void - { - } - - setTimeSpeed(speed: number) - { - this.sendCommand('setCommonParam', { param: 'timespeed', value: speed }); - } - - toggleCommand(c) - { - c._expanded = !c._expanded; - } - - get updateCount() { return +this.coreService.updateCount; } - - get commonParams() { return this.coreService.commonParams; } - - get commandDomains() { return this.coreService.commandDomains; } - get commands() { return this.coreService.commands; } - - get consoleCommands() { return this.coreService.consoleCommands; } - get searchConsoleCommand() { return this.coreService.searchConsoleCommand; } - - get lastCommand() { return this.coreService.lastCommand; } -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.module.ts b/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.module.ts deleted file mode 100644 index e1f246717..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/modules/editor/editor.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule, Pipe, PipeTransform, ChangeDetectionStrategy } from '@angular/core'; -import { SharedModule } from '../../shared/shared.module'; -import { DMModule } from '../dm/dm.module'; -import { ECSModule } from '../ecs/ecs.module'; -import { NgbModule, NgbTabsetModule, NgbAccordionModule, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap'; - -import { EditorComponent } from './editor.component'; - -@NgModule({ - imports: [SharedModule, DMModule, ECSModule, NgbModule, NgbTabsetModule, NgbAccordionModule, NgbTypeaheadModule], - declarations: [EditorComponent], - exports: [EditorComponent] -}) -export class EditorModule { } \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/polyfills.ts b/prog/gameLibs/webui/plugins/webView/src/app/polyfills.ts deleted file mode 100644 index 7b5d42938..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/polyfills.ts +++ /dev/null @@ -1,12 +0,0 @@ -// import 'core-js/es5'; -import 'core-js/es6'; -import 'core-js/es7/reflect'; -require('zone.js/dist/zone'); - -if (process.env.ENV === 'production') { - // Production -} else { - // Development - Error['stackTraceLimit'] = Infinity; - require('zone.js/dist/long-stack-trace-zone'); -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/shared/shared.module.ts b/prog/gameLibs/webui/plugins/webView/src/app/shared/shared.module.ts deleted file mode 100644 index b8a623c7d..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/shared/shared.module.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { NgModule, OnInit, OnDestroy, Directive, ElementRef, EventEmitter, Input, Output, NgZone } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; - -import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { TreeModule } from 'angular-tree-component'; - -import * as Clipboard from 'clipboard'; - -@Directive({ - selector: '[ngIIclipboard]' -}) -export class ClipboardDirective implements OnInit, OnDestroy -{ - clipboard: Clipboard; - - @Input('ngIIclipboard') targetElm: ElementRef; - - @Input() cbContent: string; - - @Output('cbOnSuccess') onSuccess: EventEmitter = new EventEmitter(); - - @Output('cbOnError') onError: EventEmitter = new EventEmitter(); - - constructor(private elmRef: ElementRef) { } - - ngOnInit() - { - let option: Clipboard.Options; - option = !!this.targetElm ? { target: () => this.targetElm } : { text: () => this.cbContent }; - this.clipboard = new Clipboard(this.elmRef.nativeElement, option); - this.clipboard.on('success', () => this.onSuccess.emit(true)); - this.clipboard.on('error', () => this.onError.emit(true)); - } - - ngOnDestroy() - { - !!this.clipboard && this.clipboard.destroy(); - } -} - -@NgModule({ - imports: [CommonModule, FormsModule, NgbModule, TreeModule], - declarations: [ClipboardDirective], - exports: [CommonModule, FormsModule, TreeModule, ClipboardDirective] -}) -export class SharedModule { } \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/tsconfig.app.json b/prog/gameLibs/webui/plugins/webView/src/app/tsconfig.app.json deleted file mode 100644 index c74c57c85..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/tsconfig.app.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "allowJs": true, - "outDir": "../out-tsc/app", - "module": "es6", - "baseUrl": "", - "types": [ "node" ], - "typeRoots": [ "../node_modules/@types" ] - }, - "exclude": [ - "test.ts", - "**/*.spec.ts" - ] -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/tsconfig.spec.json b/prog/gameLibs/webui/plugins/webView/src/app/tsconfig.spec.json deleted file mode 100644 index 3641750a6..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/tsconfig.spec.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../out-tsc/spec", - "module": "commonjs", - "target": "es6", - "baseUrl": "", - "types": [ - "jasmine", - "node" - ] - }, - "files": [ - "test.ts" - ], - "include": [ - "**/*.spec.ts", - "**/*.d.ts" - ] -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/vendor.ts b/prog/gameLibs/webui/plugins/webView/src/app/vendor.ts deleted file mode 100644 index 1081875da..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/app/vendor.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Angular -import '@angular/platform-browser'; -import '@angular/platform-browser-dynamic'; -import '@angular/core'; -import '@angular/common'; -import '@angular/http'; -// RxJS -import 'rxjs'; -// Other vendors for example jQuery, Lodash or Bootstrap -// You can import js, ts, css, sass, ... - -require('../vendor/bootstrap/css/bootstrap.min.css'); -require('../vendor/font-awesome/css/font-awesome.min.css'); -require('../node_modules/@swimlane/ngx-datatable/src/themes/bootstrap.scss'); \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/build.bat b/prog/gameLibs/webui/plugins/webView/src/build.bat deleted file mode 100644 index ce1a66c62..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/build.bat +++ /dev/null @@ -1,2 +0,0 @@ -REM npm run build:prod -ng build --prod --aot --output-hashing=none --build-optimizer=false --delete-output-path=false --output-path=../web \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/install.bat b/prog/gameLibs/webui/plugins/webView/src/install.bat deleted file mode 100644 index b61770223..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/install.bat +++ /dev/null @@ -1 +0,0 @@ -npm install --no-audit && npm install webpack@2.4.1 -g && npm install webpack-dev-server@2.4.5 -g && npm install webpack-merge@4.1.0 -g && npm install typescript@2.3.2 -g && npm install @angular/cli@1.7.3 -g diff --git a/prog/gameLibs/webui/plugins/webView/src/package-lock.json b/prog/gameLibs/webui/plugins/webView/src/package-lock.json deleted file mode 100644 index f8cda7030..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/package-lock.json +++ /dev/null @@ -1,15279 +0,0 @@ -{ - "name": "enlisted-webui", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@angular-devkit/build-optimizer": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.3.2.tgz", - "integrity": "sha512-U0BCZtThq5rUfY08shHXpxe8ZhSsiYB/cJjUvAWRTs/ORrs8pbngS6xwseQws8d/vHoVrtqGD9GU9h8AmFRERQ==", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "source-map": "^0.5.6", - "typescript": "~2.6.2", - "webpack-sources": "^1.0.1" - }, - "dependencies": { - "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", - "dev": true - } - } - }, - "@angular-devkit/core": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.3.2.tgz", - "integrity": "sha512-zABk/iP7YX5SVbmK4e+IX7j2d0D37MQJQiKgWdV3JzfvVJhNJzddiirtT980pIafoq+KyvTgVwXtc+vnux0oeQ==", - "dev": true, - "requires": { - "ajv": "~5.5.1", - "chokidar": "^1.7.0", - "rxjs": "^5.5.6", - "source-map": "^0.5.6" - } - }, - "@angular-devkit/schematics": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.3.2.tgz", - "integrity": "sha512-B6zZoqvHaTJy+vVdA6EtlxnCdGMa5elCa4j9lQLC3JI8DLvMXUWkCIPVbPzJ/GSRR9nsKWpvYMYaJyfBDUqfhw==", - "dev": true, - "requires": { - "@ngtools/json-schema": "^1.1.0", - "rxjs": "^5.5.6" - } - }, - "@angular/animations": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-5.2.9.tgz", - "integrity": "sha512-H/3fMs4PhYjKoA81II6D0PHifDrqlKet2u/EXzUBq3ehXby+N/0GBzqsBYwPeU5pTye7WPFfW+5sgoJpN8Ye6Q==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/cli": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-1.7.3.tgz", - "integrity": "sha512-19sh0SbjneG7/R/FvZBfHsHqfIqyj4LQuXdddJKMCDM97UoHQTjfgrpRvBf3a3lR79wdLXchWJBD9Yc6ifosEA==", - "dev": true, - "requires": { - "@angular-devkit/build-optimizer": "0.3.2", - "@angular-devkit/core": "0.3.2", - "@angular-devkit/schematics": "0.3.2", - "@ngtools/json-schema": "1.2.0", - "@ngtools/webpack": "1.10.2", - "@schematics/angular": "0.3.2", - "@schematics/package-update": "0.3.2", - "ajv": "^6.1.1", - "autoprefixer": "^7.2.3", - "cache-loader": "^1.2.0", - "chalk": "~2.2.0", - "circular-dependency-plugin": "^4.2.1", - "clean-css": "^4.1.11", - "common-tags": "^1.3.1", - "copy-webpack-plugin": "~4.4.1", - "core-object": "^3.1.0", - "denodeify": "^1.2.1", - "ember-cli-string-utils": "^1.0.0", - "extract-text-webpack-plugin": "^3.0.2", - "file-loader": "^1.1.5", - "fs-extra": "^4.0.0", - "glob": "^7.0.3", - "html-webpack-plugin": "^2.29.0", - "istanbul-instrumenter-loader": "^3.0.0", - "karma-source-map-support": "^1.2.0", - "less": "^2.7.2", - "less-loader": "^4.0.5", - "license-webpack-plugin": "^1.0.0", - "loader-utils": "1.1.0", - "lodash": "^4.11.1", - "memory-fs": "^0.4.1", - "minimatch": "^3.0.4", - "node-modules-path": "^1.0.0", - "node-sass": "^4.7.2", - "nopt": "^4.0.1", - "opn": "~5.1.0", - "portfinder": "~1.0.12", - "postcss": "^6.0.16", - "postcss-import": "^11.0.0", - "postcss-loader": "^2.0.10", - "postcss-url": "^7.1.2", - "raw-loader": "^0.5.1", - "resolve": "^1.1.7", - "rxjs": "^5.5.6", - "sass-loader": "^6.0.6", - "semver": "^5.1.0", - "silent-error": "^1.0.0", - "source-map-support": "^0.4.1", - "style-loader": "^0.19.1", - "stylus": "^0.54.5", - "stylus-loader": "^3.0.1", - "uglifyjs-webpack-plugin": "^1.1.8", - "url-loader": "^0.6.2", - "webpack": "~3.11.0", - "webpack-dev-middleware": "~1.12.0", - "webpack-dev-server": "~2.11.0", - "webpack-merge": "^4.1.0", - "webpack-sources": "^1.0.0", - "webpack-subresource-integrity": "^1.0.1" - }, - "dependencies": { - "ajv": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz", - "integrity": "sha1-JH1SdBENtlNwa1UPzCt5fKKM/Fk=", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "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 - }, - "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 - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha1-NW/04rDo5D4yLRijckYLvPOszSY=", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "copy-webpack-plugin": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.4.3.tgz", - "integrity": "sha512-v4THQ24Tks2NkyOvZuFDgZVfDD9YaA9rwYLZTrWg2GHIA8lrH5DboEyeoorh5Skki+PUbgSmnsCwhMWqYrQZrA==", - "dev": true, - "requires": { - "cacache": "^10.0.1", - "find-cache-dir": "^1.0.0", - "globby": "^7.1.1", - "is-glob": "^4.0.0", - "loader-utils": "^1.1.0", - "minimatch": "^3.0.4", - "p-limit": "^1.0.0", - "serialize-javascript": "^1.4.0" - } - }, - "debug": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", - "integrity": "sha1-wkGPv9ein01PcP9M6mBNS2TEZAc=", - "dev": true, - "requires": { - "ms": "^2.1.1" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=", - "dev": true - } - } - }, - "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, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "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, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "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=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "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 - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "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==", - "dev": true, - "requires": { - "async": "^2.4.1", - "loader-utils": "^1.1.0", - "schema-utils": "^0.3.0", - "webpack-sources": "^1.0.1" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "file-loader": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", - "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "schema-utils": "^0.4.5" - }, - "dependencies": { - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "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=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - } - } - }, - "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==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "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==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "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, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "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 - }, - "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, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", - "dev": true - }, - "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, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "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, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "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, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "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, - "requires": { - "ajv": "^5.0.0" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "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 - } - } - }, - "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, - "requires": { - "source-map": "^0.5.6" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "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 - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "style-loader": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.1.tgz", - "integrity": "sha512-IRE+ijgojrygQi3rsqT0U4dd+UcPCqcVvauZpCnQrGAlEe+FUIyrK93bUDScamesjP08JlQNsFJU+KmPedP5Og==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "schema-utils": "^0.3.0" - } - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "webpack": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.11.0.tgz", - "integrity": "sha512-3kOFejWqj5ISpJk4Qj/V7w98h9Vl52wak3CLiw/cDOfbVTq7FeoZ0SdoHHY9PYlHr50ZS42OfvzE2vB4nncKQg==", - "dev": true, - "requires": { - "acorn": "^5.0.0", - "acorn-dynamic-import": "^2.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.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" - }, - "dependencies": { - "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, - "requires": { - "source-map": "^0.5.6", - "uglify-js": "^2.8.29", - "webpack-sources": "^1.0.1" - } - } - } - }, - "webpack-dev-server": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.3.tgz", - "integrity": "sha1-P9SKQCFkpladlNPRfxMUMmMbSHM=", - "dev": true, - "requires": { - "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.5", - "spdy": "^3.4.1", - "strip-ansi": "^3.0.0", - "supports-color": "^5.1.0", - "webpack-dev-middleware": "1.12.2", - "yargs": "6.6.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "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, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "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, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "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, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "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, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "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, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "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 - }, - "yargs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", - "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", - "dev": true, - "requires": { - "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" - } - }, - "yargs-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - } - } - }, - "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 - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", - "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - } - } - }, - "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, - "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } - } - } - } - }, - "@angular/common": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-5.2.9.tgz", - "integrity": "sha512-g2hPcI0fnT4TV+Fd+1IohjuqBxPvxwyH9IzTn8PkU9X2M+F6cHCUvHxL1sWI2sF8pYcaHzVjq9WClym10X36Lg==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/compiler": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-5.2.9.tgz", - "integrity": "sha512-mN+ofInk8y/tk2TCJZx8RrGdOKdrfunoCair7tfDy4XoQJE90waGfaYWo07hYU+UYwLhrg19m2Czy6rIDciUJA==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/compiler-cli": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-5.2.9.tgz", - "integrity": "sha512-LAEpL/6PAev3zwTow/43Atzv9AtKLAiLoS285X3EV1f80yQpYAmFRrPUtDlrIZdhZHBBv7CxnyCVpOLU3T8ohw==", - "requires": { - "chokidar": "^1.4.2", - "minimist": "^1.2.0", - "reflect-metadata": "^0.1.2", - "tsickle": "^0.27.2" - } - }, - "@angular/core": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-5.2.9.tgz", - "integrity": "sha512-cvHBJGtasrIoARvbLFyHaOsiWKVwMNrrSTZLwrlyHP8oYzkDrE0qKGer6QCqyKt+51hF53cgWEffGzM/u/0wYg==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/forms": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-5.2.9.tgz", - "integrity": "sha512-zyIOiZV/FAm1iVZWTk3Joz6Jt096hbhfDbBUrssmuiTKi9dU6rWG+Z4b88zStqulKe3HFVZkgdixWlminG8nKA==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/http": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-5.2.9.tgz", - "integrity": "sha512-DKjgIk+Dp0Xv1ieG8LawvUnL4dYZp1KroAq5cfKuO9EojP0zM3tUvBtw2vbPLsHYma7g7ZMjOoAbzVxtmTBZqw==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/platform-browser": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.2.9.tgz", - "integrity": "sha512-P6iviRTuLsLRuqtZNOO0fd4cjTo8DWsDCecwntUlI08R3kH5qeqvqarTzlw/4oD+wBzZY6bfb89JyY+n5XbX3Q==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/platform-browser-dynamic": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.2.9.tgz", - "integrity": "sha512-8C3MtyguJKDTT8FcHIRDlBxswcIdpfugOf4S2t94pVedCr4h9w2da/lcfwJKUISw1aKjfA77Sl8TDUhoS8ymmQ==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/platform-server": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-5.2.9.tgz", - "integrity": "sha512-BXal5+cltR0Qo8xuum5SHkDYaChBrf1ygJUU58nGVn7SptweI9z3B6woRAJxfij8aobf5uDEL9jaAygxUfQECg==", - "requires": { - "domino": "^1.0.29", - "tslib": "^1.7.1", - "xhr2": "^0.1.4" - } - }, - "@angular/router": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-5.2.9.tgz", - "integrity": "sha512-NtDbFK0EA1rfFc+5Dqd5mIv8E1Wcc5rDUnSty4cX2V+HxTEZvQ9DRdpO2Q0abWU5siXyqponuPHJzF08OVGyNA==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@angular/upgrade": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/upgrade/-/upgrade-5.2.9.tgz", - "integrity": "sha512-R3LwId5J8ynlzDaeD+SFe1HWuxM0Xqg6Ugl3vzxDWDKuzbFCdEsc2ZvhMpASrfs+JPdazANHoFPLrRaeXulWeQ==", - "requires": { - "tslib": "^1.7.1" - } - }, - "@ng-bootstrap/ng-bootstrap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-1.0.1.tgz", - "integrity": "sha1-ZdE/stoC9FC7XtwCVlmfKEHl6Rg=" - }, - "@ngtools/json-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.2.0.tgz", - "integrity": "sha512-pMh+HDc6mOjUO3agRfB1tInimo7hf67u+0Cska2bfXFe6oU7rSMnr5PLVtiZVgwMoBHpx/6XjBymvcnWPo2Uzg==", - "dev": true - }, - "@ngtools/webpack": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-1.10.2.tgz", - "integrity": "sha512-3u2zg2rarG3qNLSukBClGADWuq/iNn5SQtlSeAbfKzwBeyLGbF0gN1z1tVx1Bcr8YwFzR6NdRePQmJGcoqq1fg==", - "requires": { - "chalk": "~2.2.0", - "enhanced-resolve": "^3.1.0", - "loader-utils": "^1.0.2", - "magic-string": "^0.22.3", - "semver": "^5.3.0", - "source-map": "^0.5.6", - "tree-kill": "^1.0.0", - "webpack-sources": "^1.1.0" - } - }, - "@schematics/angular": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.3.2.tgz", - "integrity": "sha512-Elrk0BA951s0ScFZU0AWrpUeJBYVR52DZ1QTIO5R0AhwEd1PW4olI8szPLGQlVW5Sd6H0FA/fyFLIvn2r9v6Rw==", - "dev": true, - "requires": { - "typescript": "~2.6.2" - }, - "dependencies": { - "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", - "dev": true - } - } - }, - "@schematics/package-update": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@schematics/package-update/-/package-update-0.3.2.tgz", - "integrity": "sha512-7aVP4994Hu8vRdTTohXkfGWEwLhrdNP3EZnWyBootm5zshWqlQojUGweZe5zwewsKcixeVOiy2YtW+aI4aGSLA==", - "dev": true, - "requires": { - "rxjs": "^5.5.6", - "semver": "^5.3.0", - "semver-intersect": "^1.1.2" - } - }, - "@swimlane/ngx-datatable": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-11.2.0.tgz", - "integrity": "sha512-QlD45YEUwOz6fu7neTtIGBAoV0owY0J9Jkpc2xViXHThWJeW7+mRhg4XRyKm8nvVDuUJZH+7huzAW1lQKN+iYg==" - }, - "@types/clipboard": { - "version": "1.5.30", - "resolved": "https://registry.npmjs.org/@types/clipboard/-/clipboard-1.5.30.tgz", - "integrity": "sha1-fr8H6Q4QUN42j7zq+zr7WAafzUs=" - }, - "@types/core-js": { - "version": "0.9.41", - "resolved": "https://registry.npmjs.org/@types/core-js/-/core-js-0.9.41.tgz", - "integrity": "sha1-z+zrY8K+qin4giUsfBjg6Ucf9OI=", - "dev": true - }, - "@types/geojson": { - "version": "7946.0.4", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.4.tgz", - "integrity": "sha1-TgSXVjg8PwVd2PPSTmP7VD6Y6wc=" - }, - "@types/highcharts": { - "version": "4.2.57", - "resolved": "https://registry.npmjs.org/@types/highcharts/-/highcharts-4.2.57.tgz", - "integrity": "sha512-8/RF3I2Zy4I8ll9Ksa+wTbHA7ne/OHilmaTBQTVpQdNtOX6dL7EWFXfcfwiXQAfL+0r48LifHjYDmqug0t8mQA==", - "requires": { - "@types/geojson": "*" - } - }, - "@types/node": { - "version": "7.0.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.16.tgz", - "integrity": "sha1-40QOPOTUkxYWrEGMxNwWzZS4AJI=", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "dev": true, - "requires": { - "mime-types": "~2.1.18", - "negotiator": "0.6.1" - } - }, - "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha1-Z6ojG/iBKXS4UjWpZ3Hra9B+onk=", - "dev": true - }, - "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=", - "dev": true, - "requires": { - "acorn": "^4.0.3" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } - } - }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true - }, - "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, - "requires": { - "extend": "~3.0.0", - "semver": "~5.0.1" - }, - "dependencies": { - "semver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", - "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", - "dev": true - } - } - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", - "dev": true - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" - }, - "ang-jsoneditor": { - "version": "1.5.12", - "resolved": "https://registry.npmjs.org/ang-jsoneditor/-/ang-jsoneditor-1.5.12.tgz", - "integrity": "sha1-suJ/gK3dkCcgnqYydgpAhqCONK4=", - "requires": { - "tslib": "^1.7.1" - } - }, - "angular-in-memory-web-api": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/angular-in-memory-web-api/-/angular-in-memory-web-api-0.3.2.tgz", - "integrity": "sha1-iDbZ4lNNN7co88taHK9v4ef7vs0=" - }, - "angular-tree-component": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/angular-tree-component/-/angular-tree-component-7.0.1.tgz", - "integrity": "sha1-/I0OctjDS4cTGjuivTKtIJRWiaw=", - "requires": { - "lodash": "4.17.4", - "mobx": ">=3", - "mobx-angular": ">=1" - } - }, - "angular2-clipboard": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/angular2-clipboard/-/angular2-clipboard-2.0.14.tgz", - "integrity": "sha1-d3Vq8IWYbLqK+rH9Da+4nBzpjaM=", - "requires": { - "@angular/core": "^2.4.1", - "@types/clipboard": "1.5.30", - "clipboard": "~1.5.16", - "core-js": "^2.4.1", - "rxjs": "5.0.0-rc.4", - "zone.js": "~0.7.2" - }, - "dependencies": { - "@angular/core": { - "version": "2.4.10", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-2.4.10.tgz", - "integrity": "sha1-C4MgplBlll2ZhkWx9c0892m0Qeo=" - }, - "clipboard": { - "version": "1.5.16", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-1.5.16.tgz", - "integrity": "sha1-kW1ec5sAZL5hsLSKU1cx7K7z02c=", - "requires": { - "good-listener": "^1.2.0", - "select": "^1.0.6", - "tiny-emitter": "^1.0.0" - } - }, - "rxjs": { - "version": "5.0.0-rc.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.0.0-rc.4.tgz", - "integrity": "sha1-pNCLxdfzDUjtcTDimVSQwyajJcQ=", - "requires": { - "symbol-observable": "^1.0.1" - } - }, - "zone.js": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.8.tgz", - "integrity": "sha1-Tz/og01EWX8mOQU6D6Q43zT//e0=" - } - } - }, - "angular2-highcharts": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/angular2-highcharts/-/angular2-highcharts-0.5.5.tgz", - "integrity": "sha1-9KGeqW1jUkQg/VxlE2rAJ7BSZv0=", - "requires": { - "@types/highcharts": "^4.2.47", - "highcharts": "^5.0.7" - } - }, - "angular2-qrcode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/angular2-qrcode/-/angular2-qrcode-2.0.1.tgz", - "integrity": "sha1-G05lwwJpS1B4ygb3ETj35DZ3VNw=", - "requires": { - "qrious": "^2.2.0" - } - }, - "angular2-template-loader": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/angular2-template-loader/-/angular2-template-loader-0.6.2.tgz", - "integrity": "sha1-wNROkP/w+sleiyPwQ6zaf9HFHXw=", - "dev": true, - "requires": { - "loader-utils": "^0.2.15" - }, - "dependencies": { - "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, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - } - } - }, - "angular2-uuid": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/angular2-uuid/-/angular2-uuid-1.1.1.tgz", - "integrity": "sha1-cvA81TK39AAy6x7PufhFc4S+lW4=" - }, - "angular2-websocket": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/angular2-websocket/-/angular2-websocket-0.9.2.tgz", - "integrity": "sha1-+1IzCWMFgjuFx899Nc9SIddOcaY=", - "requires": { - "bluebird": "^3.4.6" - } - }, - "ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", - "dev": true, - "requires": { - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "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 - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "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 - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "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==" - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "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=" - }, - "array-flatten": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", - "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", - "dev": true - }, - "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, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" - } - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" - }, - "arraybuffer.slice": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", - "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true, - "optional": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" - }, - "ast-types": { - "version": "0.9.6", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", - "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", - "dev": true - }, - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha1-skWiPKcZMAROxT+kaqAKPofGphA=", - "dev": true, - "requires": { - "lodash": "^4.17.10" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40=", - "dev": true - } - } - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" - }, - "async-each-series": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz", - "integrity": "sha1-dhfBkXQB/Yykooqtzj266Yr+tDI=", - "dev": true - }, - "async-foreach": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", - "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, - "autoprefixer": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", - "integrity": "sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ==", - "dev": true, - "requires": { - "browserslist": "^2.11.3", - "caniuse-lite": "^1.0.30000805", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^6.0.17", - "postcss-value-parser": "^3.2.3" - } - }, - "awesome-typescript-loader": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/awesome-typescript-loader/-/awesome-typescript-loader-3.1.3.tgz", - "integrity": "sha1-frQd+xNsLqDgmb7wONxwxF+BAiM=", - "dev": true, - "requires": { - "colors": "^1.1.2", - "enhanced-resolve": "^3.1.0", - "loader-utils": "^1.1.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.1", - "source-map-support": "^0.4.15" - }, - "dependencies": { - "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, - "requires": { - "source-map": "^0.5.6" - } - } - } - }, - "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=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha1-8OAD2cqef1nHpQiUXXsu+aBKVC8=" - }, - "axios": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.17.1.tgz", - "integrity": "sha1-LY4+XQvb1zJ/kbyBT1xXZg+Bgk0=", - "dev": true, - "requires": { - "follow-redirects": "^1.2.5", - "is-buffer": "^1.1.5" - } - }, - "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, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - } - }, - "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 - } - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "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.7", - "trim-right": "^1.0.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "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=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "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, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "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, - "requires": { - "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" - } - }, - "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, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "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==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "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==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=" - } - } - }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha1-yrHmEY8FEJXli1KBrqjBzSK/wOM=", - "dev": true - }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, - "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha1-pfwpi4G54Nyi5FiCR4S2XFK6WI4=" - }, - "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha1-wteA9T1Fu6gxeokC1M7q86Y4WxQ=" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", - "dev": true - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "~2.0.0" - } - }, - "bluebird": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", - "integrity": "sha1-G+CQjgVKdRdUVJwnBInBUF1KsVo=" - }, - "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 - }, - "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg=", - "dev": true - } - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "requires": { - "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" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.x.x" - } - }, - "bootstrap": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.3.7.tgz", - "integrity": "sha1-WjiTlFSfIzMIdaOxUGVldPip63E=" - }, - "boxen": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", - "dev": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "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 - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "brace": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/brace/-/brace-0.11.0.tgz", - "integrity": "sha1-FVzYBgdofcjLkI8N+U5ioDPB1WM=" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-sync": { - "version": "2.24.7", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.24.7.tgz", - "integrity": "sha1-D5O8qr+4SjWlyY4HaCyeRcYlGpM=", - "dev": true, - "requires": { - "browser-sync-ui": "v1.0.1", - "bs-recipes": "1.3.4", - "chokidar": "1.7.0", - "connect": "3.6.6", - "connect-history-api-fallback": "^1.5.0", - "dev-ip": "^1.0.1", - "easy-extender": "^2.3.4", - "eazy-logger": "3.0.2", - "etag": "^1.8.1", - "fresh": "^0.5.2", - "fs-extra": "3.0.1", - "http-proxy": "1.15.2", - "immutable": "3.8.2", - "localtunnel": "1.9.0", - "micromatch": "2.3.11", - "opn": "5.3.0", - "portscanner": "2.1.1", - "qs": "6.2.3", - "raw-body": "^2.3.2", - "resp-modifier": "6.0.2", - "rx": "4.1.0", - "serve-index": "1.9.1", - "serve-static": "1.13.2", - "server-destroy": "1.0.1", - "socket.io": "2.1.1", - "ua-parser-js": "0.7.17", - "yargs": "6.4.0" - }, - "dependencies": { - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "engine.io": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.0.tgz", - "integrity": "sha1-VDMlBvQvLtxxaQ0vKkI0k1nzv30=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "ws": "~3.3.1" - } - }, - "engine.io-client": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", - "integrity": "sha1-b1TAR13khxWKGnx30QF4cItq3TY=", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - } - }, - "engine.io-parser": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha1-TA9M/3mq7su9z96maoI8YIVAkZY=", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary2": "~1.0.2" - } - }, - "eventemitter3": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", - "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", - "dev": true - }, - "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^3.0.0", - "universalify": "^0.1.0" - } - }, - "http-proxy": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.15.2.tgz", - "integrity": "sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE=", - "dev": true, - "requires": { - "eventemitter3": "1.x.x", - "requires-port": "1.x.x" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - }, - "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "opn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", - "integrity": "sha1-ZIcVZchjh18FLP31PT48ta21Oxw=", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "qs": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", - "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", - "dev": true - }, - "rx": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", - "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", - "dev": true - }, - "socket.io": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", - "integrity": "sha1-oGnF/qvuPmshSnW0DOBlLhz7mYA=", - "dev": true, - "requires": { - "debug": "~3.1.0", - "engine.io": "~3.2.0", - "has-binary2": "~1.0.2", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.1.1", - "socket.io-parser": "~3.2.0" - } - }, - "socket.io-adapter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", - "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", - "dev": true - }, - "socket.io-client": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", - "integrity": "sha1-3LOBA0NqtFeN2wJmOK4vIbYjZx8=", - "dev": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "engine.io-client": "~3.2.0", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.2.0", - "to-array": "0.1.4" - } - }, - "socket.io-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", - "integrity": "sha1-58Yii2qh+BTmFIrqMltRqpSZ4Hc=", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - } - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=", - "dev": true - }, - "window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", - "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz", - "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=", - "dev": true, - "requires": { - "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", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^4.1.0" - } - }, - "yargs-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - } - } - }, - "browser-sync-ui": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-1.0.1.tgz", - "integrity": "sha1-l0BSeybR16ziWazAx55bXjfQ/fI=", - "dev": true, - "requires": { - "async-each-series": "0.1.1", - "connect-history-api-fallback": "^1.1.0", - "immutable": "^3.7.6", - "server-destroy": "1.0.1", - "socket.io-client": "2.0.4", - "stream-throttle": "^0.1.3" - }, - "dependencies": { - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=", - "dev": true - }, - "engine.io-client": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha1-W96xMPi5SlCsXL63JYPnpKBj3f0=", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "engine.io-parser": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha1-TA9M/3mq7su9z96maoI8YIVAkZY=", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary2": "~1.0.2" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - }, - "socket.io-client": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz", - "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=", - "dev": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~2.6.4", - "engine.io-client": "~3.1.0", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.1.1", - "to-array": "0.1.4" - } - }, - "socket.io-parser": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha1-7S2l7nnxCVUDbj2kE7/X8eTYbI4=", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "has-binary2": "~1.0.2", - "isarray": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=", - "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", - "dev": true - } - } - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "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" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "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, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "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, - "requires": { - "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" - } - }, - "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, - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000792", - "electron-to-chromium": "^1.3.30" - } - }, - "bs-recipes": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", - "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=", - "dev": true - }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "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 - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "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 - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cacache": { - "version": "10.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", - "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", - "requires": { - "bluebird": "^3.5.1", - "chownr": "^1.0.1", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "lru-cache": "^4.1.1", - "mississippi": "^2.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", - "ssri": "^5.2.4", - "unique-filename": "^1.1.0", - "y18n": "^4.0.0" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "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" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "cache-loader": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-1.2.2.tgz", - "integrity": "sha1-bVw43tlZoJzF1YGQq1r29zvTU/U=", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "mkdirp": "^0.5.1", - "neo-async": "^2.5.0", - "schema-utils": "^0.4.2" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", - "dev": true - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, - "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, - "requires": { - "browserslist": "^1.3.6", - "caniuse-db": "^1.0.30000529", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - }, - "dependencies": { - "browserslist": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", - "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", - "dev": true, - "requires": { - "caniuse-db": "^1.0.30000639", - "electron-to-chromium": "^1.2.7" - } - } - } - }, - "caniuse-db": { - "version": "1.0.30000887", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000887.tgz", - "integrity": "sha1-mr9ThhDjNJhw7VJfcGLeZJzDxXA=", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30000887", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000887.tgz", - "integrity": "sha1-F2lFjCe73PYbDLa1Byu2zRH9nCM=", - "dev": true - }, - "canvas": { - "version": "1.6.13", - "resolved": "https://registry.npmjs.org/canvas/-/canvas-1.6.13.tgz", - "integrity": "sha512-XAfzfEOHZ3JIPjEV+WSI6PpISgUta3dgmndWbsajotz+0TQOX/jDpp2kawjRERatOGv9sMMzk5auB3GKEKA6hg==", - "optional": true, - "requires": { - "nan": "^2.10.0" - } - }, - "capture-stack-trace": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz", - "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==", - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^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" - } - }, - "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha1-VHJri4//TfBTxCGH6AH7RBLfFJQ=" - }, - "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true - }, - "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, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "circular-dependency-plugin": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-4.4.0.tgz", - "integrity": "sha512-yEFtUNUYT4jBykEX5ZOHw+5goA3glGZr9wAXIQqoyakjz5H5TeUmScnWRc52douAhb9eYzK3s7V6bXfNnjFdzg==", - "dev": true - }, - "clap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", - "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", - "dev": true, - "requires": { - "chalk": "^1.1.3" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - } - }, - "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 - } - } - }, - "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==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha1-LUEe92uFabbQyEBo2r6FsKpeXBc=", - "dev": true, - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", - "dev": true - } - } - }, - "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", - "dev": true - }, - "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, - "requires": { - "restore-cursor": "^1.0.1" - } - }, - "cli-truncate": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-1.1.0.tgz", - "integrity": "sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA==", - "dev": true, - "requires": { - "slice-ansi": "^1.0.0", - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "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 - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "clipboard": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-1.6.1.tgz", - "integrity": "sha1-ZcW2VIEkZrD6q4Lca6Dx0vjkvlM=", - "requires": { - "good-listener": "^1.2.0", - "select": "^1.1.2", - "tiny-emitter": "^1.0.0" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "clone-deep": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", - "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", - "requires": { - "for-own": "^1.0.0", - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.0", - "shallow-clone": "^1.0.0" - }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "requires": { - "for-in": "^1.0.1" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=" - } - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "coa": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", - "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", - "dev": true, - "requires": { - "q": "^1.1.2" - } - }, - "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=" - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", - "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", - "dev": true, - "requires": { - "clone": "^1.0.2", - "color-convert": "^1.3.0", - "color-string": "^0.3.0" - }, - "dependencies": { - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "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, - "requires": { - "color-name": "^1.0.0" - } - }, - "colormin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", - "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", - "dev": true, - "requires": { - "color": "^0.11.0", - "css-color-names": "0.0.4", - "has": "^1.0.1" - } - }, - "colors": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz", - "integrity": "sha1-Lfj/Vz378lWvVi+M5xgda5caNZs=", - "dev": true - }, - "columnify": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", - "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", - "dev": true, - "requires": { - "strip-ansi": "^3.0.0", - "wcwidth": "^1.0.0" - } - }, - "combine-lists": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", - "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", - "dev": true, - "requires": { - "lodash": "^4.5.0" - } - }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha1-LR0kMXr7ir6V1tLAsHtXgTU52Cg=", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", - "integrity": "sha1-K/Bj3e58eJEXaYGizHmOV1S8aXA=", - "dev": true - }, - "common-tags": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true - }, - "compressible": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", - "integrity": "sha1-hXqasKfloH2Ng37UP+Le//ZP4hI=", - "dev": true, - "requires": { - "mime-db": ">= 1.36.0 < 2" - } - }, - "compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha1-J+DhdqryYPfywoE8PkQK258Zk9s=", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.14", - "debug": "2.6.9", - "on-headers": "~1.0.1", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "concurrently": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.4.0.tgz", - "integrity": "sha1-YGYrPe/eBzdbrhmqwKt4DsdIunk=", - "dev": true, - "requires": { - "chalk": "0.5.1", - "commander": "2.6.0", - "date-fns": "^1.23.0", - "lodash": "^4.5.1", - "rx": "2.3.24", - "spawn-command": "^0.0.2-1", - "supports-color": "^3.2.3", - "tree-kill": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "dev": true - }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dev": true, - "requires": { - "ansi-styles": "^1.1.0", - "escape-string-regexp": "^1.0.0", - "has-ansi": "^0.1.0", - "strip-ansi": "^0.3.0", - "supports-color": "^0.2.0" - }, - "dependencies": { - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "dev": true - } - } - }, - "commander": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", - "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=", - "dev": true - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "dev": true, - "requires": { - "ansi-regex": "^0.2.0" - } - }, - "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 - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dev": true, - "requires": { - "ansi-regex": "^0.2.1" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", - "dev": true, - "requires": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" - }, - "dependencies": { - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "dev": true, - "requires": { - "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" - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - } - } - }, - "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 - }, - "connect-logger": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/connect-logger/-/connect-logger-0.0.1.tgz", - "integrity": "sha1-TZmZeKHSC7RgjnzUNNdBZSJVF0s=", - "dev": true, - "requires": { - "moment": "*" - } - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "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 - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true - }, - "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==", - "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha1-UbU3qMQ+DwTewZk7/83VBOdYrCA=", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "requires": { - "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" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "copy-webpack-plugin": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.5.1.tgz", - "integrity": "sha512-OlTo6DYg0XfTKOF8eLf79wcHm4Ut10xU2cRBRPMW/NA5F9VMjZGTfRHWDIYC3s+1kObGYrBLshXWU1K0hILkNQ==", - "requires": { - "cacache": "^10.0.4", - "find-cache-dir": "^1.0.0", - "globby": "^7.1.1", - "is-glob": "^4.0.0", - "loader-utils": "^1.1.0", - "minimatch": "^3.0.4", - "p-limit": "^1.0.0", - "serialize-javascript": "^1.4.0" - }, - "dependencies": { - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "requires": { - "is-extglob": "^2.1.1" - } - } - } - }, - "core-js": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", - "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=" - }, - "core-object": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/core-object/-/core-object-3.1.5.tgz", - "integrity": "sha512-sA2/4+/PZ/KV6CKgjrVrrUVBKCkdDO02CUlQ0YKTQoYUwPYNOtOAcWlbYhd5v/1JqYaA6oZ4sDlOU4ppVw6Wbg==", - "dev": true, - "requires": { - "chalk": "^2.0.0" - } - }, - "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=" - }, - "cosmiconfig": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", - "integrity": "sha1-dgORVJWAu9LfHlYrwXexPCkJctw=", - "dev": true, - "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^4.0.0", - "require-from-string": "^2.0.1" - }, - "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - } - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true, - "requires": { - "capture-stack-trace": "^1.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "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" - } - }, - "cross-spawn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", - "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.x.x" - } - }, - "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, - "requires": { - "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" - } - }, - "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "dev": true - }, - "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 - }, - "css-loader": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.1.tgz", - "integrity": "sha1-IgMlWZ+PAEUtnOtMPKbIpmeYZC0=", - "dev": true, - "requires": { - "babel-code-frame": "^6.11.0", - "css-selector-tokenizer": "^0.7.0", - "cssnano": ">=2.6.1 <4", - "loader-utils": "^1.0.2", - "lodash.camelcase": "^4.3.0", - "object-assign": "^4.0.1", - "postcss": "^5.0.6", - "postcss-modules-extract-imports": "^1.0.0", - "postcss-modules-local-by-default": "^1.0.1", - "postcss-modules-scope": "^1.0.0", - "postcss-modules-values": "^1.1.0", - "postcss-value-parser": "^3.3.0", - "source-list-map": "^0.1.7" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "source-list-map": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", - "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "css-parse": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", - "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", - "dev": true - }, - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "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, - "requires": { - "cssesc": "^0.1.0", - "fastparse": "^1.1.1", - "regexpu-core": "^1.0.0" - } - }, - "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 - }, - "cssesc": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", - "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", - "dev": true - }, - "cssnano": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", - "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "autoprefixer": { - "version": "6.7.7", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", - "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", - "dev": true, - "requires": { - "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" - } - }, - "browserslist": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", - "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", - "dev": true, - "requires": { - "caniuse-db": "^1.0.30000639", - "electron-to-chromium": "^1.2.7" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "csso": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", - "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", - "dev": true, - "requires": { - "clap": "^1.0.9", - "source-map": "^0.5.3" - } - }, - "cuint": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", - "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=", - "dev": true - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "requires": { - "array-find-index": "^1.0.1" - } - }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", - "dev": true - }, - "cyclist": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=" - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "^0.10.9" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-fns": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz", - "integrity": "sha1-EuYJzcuTUScxHQTTMzTilgoqVOY=", - "dev": true - }, - "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 - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "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=" - }, - "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 - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "^1.0.2" - }, - "dependencies": { - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - } - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "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==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "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==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=" - } - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "del": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", - "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "denodeify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", - "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true - }, - "dev-ip": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", - "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=", - "dev": true - }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", - "integrity": "sha1-CyBdK2rvmCOMooZZioIE0p0KADQ=", - "requires": { - "arrify": "^1.0.1", - "path-type": "^3.0.0" - } - }, - "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 - }, - "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, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "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, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "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, - "requires": { - "utila": "~0.3" - }, - "dependencies": { - "utila": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", - "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", - "dev": true - } - } - }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", - "dev": true, - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "dom-serializer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", - "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", - "dev": true, - "requires": { - "domelementtype": "~1.1.1", - "entities": "~1.1.1" - }, - "dependencies": { - "domelementtype": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", - "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", - "dev": true - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", - "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", - "dev": true - }, - "domhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", - "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domino": { - "version": "1.0.30", - "resolved": "https://registry.npmjs.org/domino/-/domino-1.0.30.tgz", - "integrity": "sha512-ikq8WiDSkICdkElud317F2Sigc6A3EDpWsxWBwIZqOl95km4p/Vc9Rj98id7qKgsjDmExj0AVM7JOd4bb647Xg==" - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", - "dev": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "duplexify": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", - "integrity": "sha1-WSkD9dgLONA3IgVBJk1poZj7NBA=", - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "easy-extender": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz", - "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40=", - "dev": true - } - } - }, - "eazy-logger": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.0.2.tgz", - "integrity": "sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw=", - "dev": true, - "requires": { - "tfunk": "^3.0.1" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "optional": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "ejs": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", - "integrity": "sha1-SY7A1JVlWrxvI81hho2SZGQHGqA=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.70", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.70.tgz", - "integrity": "sha1-3tN3JW2S2BtCV9NsZaqJAnSvz9I=", - "dev": true - }, - "elegant-spinner": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", - "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", - "dev": true - }, - "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha1-wtC3d2kRuGcixjLDwGxg8vgZk5o=", - "dev": true, - "requires": { - "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" - } - }, - "ember-cli-string-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ember-cli-string-utils/-/ember-cli-string-utils-1.1.0.tgz", - "integrity": "sha1-ObZ3/CgF9VFzc1N2/O8njqpEUqE=", - "dev": true - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha1-7SljTRm6ukY7bOa4CjchPqtx7EM=", - "requires": { - "once": "^1.4.0" - } - }, - "engine.io": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz", - "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=", - "dev": true, - "requires": { - "accepts": "1.3.3", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "ws": "1.1.2" - }, - "dependencies": { - "accepts": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", - "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", - "dev": true, - "requires": { - "mime-types": "~2.1.11", - "negotiator": "0.6.1" - } - }, - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "engine.io-client": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz", - "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parsejson": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "1.1.2", - "xmlhttprequest-ssl": "1.5.3", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "engine.io-parser": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", - "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "0.0.6", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary": "0.1.7", - "wtf-8": "1.0.0" - } - }, - "enhanced-resolve": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", - "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "object-assign": "^4.0.1", - "tapable": "^0.2.7" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "dev": true - }, - "entities": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", - "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", - "dev": true - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha1-nbvdJ8aFbwABQhyhh4LXhr+KYWU=", - "dev": true, - "requires": { - "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" - } - }, - "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, - "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" - } - }, - "es5-ext": { - "version": "0.10.46", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz", - "integrity": "sha1-79mfZ8Wn7Hibqj2qf3mHA4j39XI=", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" - } - }, - "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, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "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, - "requires": { - "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" - } - }, - "es6-promise": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz", - "integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI=", - "dev": true - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-templates": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz", - "integrity": "sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ=", - "dev": true, - "requires": { - "recast": "~0.11.12", - "through": "~2.3.6" - } - }, - "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, - "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "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=" - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "eventemitter3": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", - "dev": true - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true - }, - "eventsource": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", - "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", - "dev": true, - "requires": { - "original": ">=0.0.5" - } - }, - "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, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "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 - }, - "expand-braces": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", - "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", - "dev": true, - "requires": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" - }, - "dependencies": { - "braces": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", - "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", - "dev": true, - "requires": { - "expand-range": "^0.1.0" - } - }, - "expand-range": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", - "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", - "dev": true, - "requires": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" - } - }, - "is-number": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", - "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", - "dev": true - }, - "repeat-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", - "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", - "dev": true - } - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "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=", - "requires": { - "fill-range": "^2.1.0" - } - }, - "express": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", - "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "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.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.1.1", - "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.3", - "qs": "6.5.1", - "range-parser": "~1.2.0", - "safe-buffer": "5.1.1", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "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==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extract-text-webpack-plugin": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.1.2.tgz", - "integrity": "sha1-dW7076gVXDaBgz+8NNpTuUF0bWw=", - "dev": true, - "requires": { - "async": "^2.1.2", - "loader-utils": "^1.0.2", - "schema-utils": "^0.3.0", - "webpack-sources": "^1.0.1" - }, - "dependencies": { - "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, - "requires": { - "ajv": "^5.0.0" - } - } - } - }, - "extract-zip": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.5.0.tgz", - "integrity": "sha1-ksz22B73Cp+kwXRxFMzvbYaIpsQ=", - "dev": true, - "requires": { - "concat-stream": "1.5.0", - "debug": "0.7.4", - "mkdirp": "0.5.0", - "yauzl": "2.4.1" - }, - "dependencies": { - "concat-stream": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.0.tgz", - "integrity": "sha1-U/fUPFHF5D+ByP3QMyHGMb5o1hE=", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~2.0.0", - "typedarray": "~0.0.5" - } - }, - "debug": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", - "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", - "dev": true - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", - "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "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=", - "dev": true - }, - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - }, - "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 - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" - }, - "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=" - }, - "fastparse": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", - "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", - "dev": true - }, - "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, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "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, - "requires": { - "pend": "~1.2.0" - } - }, - "file-loader": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-0.11.1.tgz", - "integrity": "sha1-azKO4SNKcp5OR9Njdd1tNcDh24Q=", - "dev": true, - "requires": { - "loader-utils": "^1.0.2" - } - }, - "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==", - "optional": true - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha1-7r9O2EAHnIP0JJA4ydcDAIMBsQU=", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", - "unpipe": "~1.0.0" - } - }, - "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=", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "flatten": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", - "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", - "dev": true - }, - "flush-write-stream": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", - "integrity": "sha1-xdWG7zivYJdlC0m8QbVfq7GfNb0=", - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.4" - } - }, - "follow-redirects": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.8.tgz", - "integrity": "sha1-Hb/hPkWtlp+BPobADlKW9SXIhaE=", - "dev": true, - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - }, - "dependencies": { - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "requires": { - "delayed-stream": "~1.0.0" - } - } - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "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=", - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", - "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.4", - "bundled": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "optional": true, - "requires": { - "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" - } - }, - "glob": { - "version": "7.1.6", - "bundled": true, - "optional": true, - "requires": { - "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" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "bundled": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.3", - "bundled": true, - "optional": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "optional": true - }, - "needle": { - "version": "2.3.3", - "bundled": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.3", - "bundled": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.8", - "bundled": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "bundled": true, - "optional": true, - "requires": { - "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" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true, - "optional": true - } - } - }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "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" - } - }, - "gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "requires": { - "globule": "^1.0.0" - } - }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "dev": true, - "requires": { - "is-property": "^1.0.2" - } - }, - "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, - "requires": { - "is-property": "^1.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "dependencies": { - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - } - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=", - "requires": { - "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" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "requires": { - "is-glob": "^2.0.0" - } - }, - "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", - "dev": true, - "requires": { - "ini": "^1.3.4" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", - "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", - "requires": { - "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" - } - }, - "globule": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.3.tgz", - "integrity": "sha512-mb1aYtDbIjTu4ShMB85m3UzjX9BVKe9WCzsnfMSZk+K5GpIbBOexgg4PPCt5eHDEG5/ZQAUX2Kct02zfiPLsKg==", - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" - }, - "dependencies": { - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - } - } - }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "requires": { - "delegate": "^3.1.2" - } - }, - "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", - "dev": true, - "requires": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - }, - "handle-thing": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", - "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-binary": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", - "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", - "dev": true, - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "dev": true, - "requires": { - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - } - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "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=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", - "integrity": "sha1-44q0uF37HgxA/pJlwOm1SFTCOBI=", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hasha": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", - "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", - "dev": true, - "requires": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - } - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "highcharts": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-5.0.15.tgz", - "integrity": "sha512-+LTe57ntLyWgkjsHzLmvRspM3FVKtds7iDswOTwuTAmZD3FtG1I/DqHiVSRjX92RQmQMZ1M7dcoRb7T648m1xA==" - }, - "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, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha1-l/I2l3vW4SVAiTD/bePuxigewEc=" - }, - "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, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "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 - }, - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", - "dev": true - }, - "html-loader": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-0.4.5.tgz", - "integrity": "sha1-X7zYfNY6XEmn/OL+VvQl4Fcpxow=", - "dev": true, - "requires": { - "es6-templates": "^0.2.2", - "fastparse": "^1.1.1", - "html-minifier": "^3.0.1", - "loader-utils": "^1.0.2", - "object-assign": "^4.1.0" - } - }, - "html-minifier": { - "version": "3.5.20", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.20.tgz", - "integrity": "sha1-exn9PKoMt5983l7lw6vfjsqmuxQ=", - "dev": true, - "requires": { - "camel-case": "3.0.x", - "clean-css": "4.2.x", - "commander": "2.17.x", - "he": "1.1.x", - "param-case": "2.1.x", - "relateurl": "0.2.x", - "uglify-js": "3.4.x" - }, - "dependencies": { - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha1-vXerfebelCBc6sxy8XFtKfIKd78=", - "dev": true - } - } - }, - "html-webpack-plugin": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.28.0.tgz", - "integrity": "sha1-LnhjtX5f1I/iYzA+L/yTTDBk0Ak=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - } - } - }, - "htmlparser2": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", - "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", - "dev": true, - "requires": { - "domelementtype": "1", - "domhandler": "2.1", - "domutils": "1.1", - "readable-stream": "1.0" - }, - "dependencies": { - "domutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", - "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "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, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "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 - } - } - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "http-parser-js": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", - "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=", - "dev": true - }, - "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", - "dev": true, - "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "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, - "requires": { - "agent-base": "2", - "debug": "2", - "extend": "3" - } - }, - "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, - "requires": { - "http-proxy": "^1.16.2", - "is-glob": "^3.1.0", - "lodash": "^4.17.2", - "micromatch": "^2.3.11" - }, - "dependencies": { - "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 - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "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 - }, - "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, - "requires": { - "agent-base": "2", - "debug": "2", - "extend": "3" - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs=", - "dev": true - }, - "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 - }, - "ieee754": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha1-UL8k5bnIu5ivSWTJQc2wkY2ntgs=", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" - }, - "image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", - "dev": true, - "optional": true - }, - "immutable": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", - "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=", - "dev": true - }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dev": true, - "requires": { - "import-from": "^2.1.0" - } - }, - "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true - }, - "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, - "requires": { - "pkg-dir": "^2.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "in-publish": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", - "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==" - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "requires": { - "repeating": "^2.0.0" - } - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "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, - "requires": { - "meow": "^3.3.0" - } - }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "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=" - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=", - "dev": true - }, - "is-absolute": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", - "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", - "dev": true, - "requires": { - "is-relative": "^0.2.1", - "is-windows": "^0.2.0" - }, - "dependencies": { - "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", - "dev": true - } - } - }, - "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 - }, - "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=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "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=", - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "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=", - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha1-HhrfIZ4e62hNaR+dagX/DTCiTXU=", - "dev": true - }, - "is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", - "dev": true, - "requires": { - "ci-info": "^1.5.0" - } - }, - "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=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "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 - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "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==" - } - } - }, - "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 - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" - }, - "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=", - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "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=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", - "dev": true, - "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" - } - }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true - }, - "is-my-json-valid": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz", - "integrity": "sha1-j9bkA2PNBrlj+od9REv7Xt3GIXU=", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, - "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", - "dev": true - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-number-like": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", - "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", - "dev": true, - "requires": { - "lodash.isfinite": "^3.3.2" - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "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 - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "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, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "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=", - "dev": true - }, - "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==", - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "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=" - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" - }, - "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 - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true - }, - "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, - "requires": { - "has": "^1.0.1" - } - }, - "is-relative": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", - "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", - "dev": true, - "requires": { - "is-unc-path": "^0.1.1" - } - }, - "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=", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-svg": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", - "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", - "dev": true, - "requires": { - "html-comment-regex": "^1.1.0" - } - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha1-oFX2rlcZLK7jKeeoYBGLSXqVDzg=", - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unc-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", - "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.0" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", - "dev": true, - "requires": { - "buffer-alloc": "^1.2.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "istanbul-instrumenter-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.1.tgz", - "integrity": "sha512-a5SPObZgS0jB/ixaKSMdn6n/gXSrK2S6q/UfRJBT3e6gQmVjwZROTODQsYW5ZNwOu78hG62Y3fWlebaVOL0C+w==", - "dev": true, - "requires": { - "convert-source-map": "^1.5.0", - "istanbul-lib-instrument": "^1.7.3", - "loader-utils": "^1.1.0", - "schema-utils": "^0.3.0" - }, - "dependencies": { - "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, - "requires": { - "ajv": "^5.0.0" - } - } - } - }, - "istanbul-lib-coverage": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", - "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", - "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", - "dev": true, - "requires": { - "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.2.1", - "semver": "^5.3.0" - } - }, - "jasmine-core": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.6.1.tgz", - "integrity": "sha1-ZqYc3baZlY42E+3vNGyZb2MR/Ds=", - "dev": true - }, - "javascript-natural-sort": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", - "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=" - }, - "js-base64": { - "version": "2.4.9", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz", - "integrity": "sha1-dIkR+wT0imDEdxs3XKxFqA3xHAM=" - }, - "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 - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha1-6u1lbsg0TxD1J8a/obbiJE3hZ9E=", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "optional": true - }, - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "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 - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "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=" - }, - "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, - "requires": { - "jsonify": "~0.0.0" - } - }, - "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=" - }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" - }, - "jsoneditor": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/jsoneditor/-/jsoneditor-5.16.0.tgz", - "integrity": "sha512-Lb5JYBLTE5gAZ0QEwd8qkgjCfSzL4OXZX0NM7ZiFKtL4AeB0unF1jSuR6bGZJ5xRMl0hpdxbuC9cVoUv7vVcSA==", - "requires": { - "ajv": "5.5.2", - "brace": "0.11.0", - "javascript-natural-sort": "0.7.1" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "jspm-config": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/jspm-config/-/jspm-config-0.3.4.tgz", - "integrity": "sha1-RMJpAuSujs4jZs7cn/FrEKXzkcY=", - "dev": true, - "requires": { - "any-promise": "^1.3.0", - "graceful-fs": "^4.1.4", - "make-error-cause": "^1.2.1", - "object.pick": "^1.1.2", - "parse-json": "^2.2.0", - "strip-bom": "^3.0.0", - "thenify": "^3.2.0", - "throat": "^3.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "karma": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/karma/-/karma-1.6.0.tgz", - "integrity": "sha1-DocdRSfV6sVsQdGB8DxcCn5tvz4=", - "dev": true, - "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^1.4.1", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^3.8.0", - "log4js": "^0.6.31", - "mime": "^1.3.4", - "minimatch": "^3.0.2", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", - "socket.io": "1.7.3", - "source-map": "^0.5.3", - "tmp": "0.0.31", - "useragent": "^2.1.12" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, - "karma-jasmine": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.0.tgz", - "integrity": "sha1-IuTAa/mhguUpTR9wXjczgRuBCs8=", - "dev": true - }, - "karma-phantomjs-launcher": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz", - "integrity": "sha1-0jyjSAG9qYY60xjju0vUBisTrNI=", - "dev": true, - "requires": { - "lodash": "^4.0.1", - "phantomjs-prebuilt": "^2.1.7" - } - }, - "karma-source-map-support": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.3.0.tgz", - "integrity": "sha1-Nt1NjKFUtirOlWliNvrjfK8Kfd4=", - "dev": true, - "requires": { - "source-map-support": "^0.5.5" - } - }, - "karma-sourcemap-loader": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz", - "integrity": "sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2" - } - }, - "karma-webpack": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.3.tgz", - "integrity": "sha1-Oc6/XKJYATmyf5rmm3iBa5yC+uY=", - "dev": true, - "requires": { - "async": "~0.9.0", - "loader-utils": "^0.2.5", - "lodash": "^3.8.0", - "source-map": "^0.1.41", - "webpack-dev-middleware": "^1.0.11" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "dev": true - }, - "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, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "kew": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", - "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", - "dev": true - }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", - "dev": true, - "requires": { - "package-json": "^4.0.0" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "less": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", - "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", - "dev": true, - "requires": { - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "mime": "^1.2.11", - "mkdirp": "^0.5.0", - "promise": "^7.1.1", - "request": "2.81.0", - "source-map": "^0.5.3" - }, - "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "optional": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true, - "optional": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.12" - } - }, - "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", - "dev": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", - "dev": true, - "optional": true, - "requires": { - "ajv": "^4.9.1", - "har-schema": "^1.0.5" - } - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "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, - "optional": true - }, - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true, - "optional": true - }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~4.2.1", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "performance-now": "^0.2.0", - "qs": "~6.4.0", - "safe-buffer": "^5.0.1", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.0.0" - } - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "dev": true, - "optional": true, - "requires": { - "punycode": "^1.4.1" - } - } - } - }, - "less-loader": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.1.0.tgz", - "integrity": "sha512-KNTsgCE9tMOM70+ddxp9yyt9iHqgmSs0yTZc5XH5Wo+g80RWRIYNqE58QJKm/yMud5wZEvz50ugRDuzVIkyahg==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "loader-utils": "^1.1.0", - "pify": "^3.0.0" - } - }, - "license-webpack-plugin": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-1.5.0.tgz", - "integrity": "sha512-Of/H79rZqm2aeg4RnP9SMSh19qkKemoLT5VaJV58uH5AxeYWEcBgGFs753JEJ/Hm6BPvQVfIlrrjoBwYj8p7Tw==", - "dev": true, - "requires": { - "ejs": "^2.5.7" - } - }, - "limiter": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.3.tgz", - "integrity": "sha1-MuLrVbIyQHaUPl0EwRhf+zh5aO8=", - "dev": true - }, - "listify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", - "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=", - "dev": true - }, - "lite-server": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/lite-server/-/lite-server-2.3.0.tgz", - "integrity": "sha1-W0zI9dX9SDYQVICrKsSKOg3isMg=", - "dev": true, - "requires": { - "browser-sync": "^2.18.5", - "connect-history-api-fallback": "^1.2.0", - "connect-logger": "0.0.1", - "lodash": "^4.11.1", - "minimist": "1.2.0" - } - }, - "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=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "loader-runner": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.1.tgz", - "integrity": "sha1-Am8S/nwxFZkolqwCugIrqSlxuXk=", - "dev": true - }, - "loader-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", - "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0" - } - }, - "localtunnel": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.0.tgz", - "integrity": "sha1-j/7Nz4yKFPYt8QVs+dVKy7C7mo8=", - "dev": true, - "requires": { - "axios": "0.17.1", - "debug": "2.6.8", - "openurl": "1.1.1", - "yargs": "6.6.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", - "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", - "dev": true, - "requires": { - "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" - } - }, - "yargs-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lockfile": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", - "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", - "dev": true, - "requires": { - "signal-exit": "^3.0.2" - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "lodash.isfinite": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", - "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", - "dev": true - }, - "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 - }, - "lodash.tail": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", - "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=" - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "log-update": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", - "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", - "dev": true, - "requires": { - "ansi-escapes": "^1.0.0", - "cli-cursor": "^1.0.2" - } - }, - "log4js": { - "version": "0.6.38", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", - "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=", - "dev": true, - "requires": { - "readable-stream": "~1.0.2", - "semver": "~4.3.3" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "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, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", - "dev": true - }, - "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 - } - } - }, - "loglevel": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", - "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", - "dev": true - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha1-oRdc80lt/IQ2wVbDNLSVWZK85pw=", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "magic-string": { - "version": "0.22.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", - "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", - "requires": { - "vlq": "^0.2.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "requires": { - "pify": "^3.0.0" - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha1-7+ToH22yjK3WBccPKcgxtY73dsg=", - "dev": true - }, - "make-error-cause": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", - "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=", - "dev": true, - "requires": { - "make-error": "^1.2.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } - }, - "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 - }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=" - }, - "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, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "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=", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "requires": { - "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" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "requires": { - "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" - } - }, - "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, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", - "integrity": "sha1-UCBHjbPH/pOq17vMTc+GnEM2M5c=" - }, - "mime-types": { - "version": "2.1.20", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", - "integrity": "sha1-kwy3GdVx6QNzhSD4RwkRVIyizBk=", - "requires": { - "mime-db": "~1.36.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "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 - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "mississippi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", - "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", - "requires": { - "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": "^2.0.1", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha1-pJ5yaNzhoNlpjkUybFYm3zVD0P4=", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mixin-object": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", - "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", - "requires": { - "for-in": "^0.1.3", - "is-extendable": "^0.1.1" - }, - "dependencies": { - "for-in": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", - "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=" - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } - } - }, - "mobx": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.1.2.tgz", - "integrity": "sha512-1kZW9KiJnq0YsrV/EeE8g1wDbGcgnlrqH7cYBqFUGVDwW93nX/fD93S9df3dCPh+j0le2zOWQXtoir/XLs+d9Q==" - }, - "mobx-angular": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mobx-angular/-/mobx-angular-3.0.1.tgz", - "integrity": "sha512-PoEUEw74LoR7Ib6iGGCqvw8xMlmA/Zr5/0TVyhshq4kuzA8pHdvtCiE5AeyRK0w4LhyS7J0Qt0GboTgdhuys+A==" - }, - "moment": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", - "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", - "dev": true - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "requires": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } - }, - "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 - }, - "nan": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.0.tgz", - "integrity": "sha1-V042Dk2VSrFpZuwQLAwEn9lhoJk=", - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=" - } - } - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true - }, - "neo-async": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.2.tgz", - "integrity": "sha1-SJEFznvFTnCdc2sZX4ITUEjFD8w=" - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "ngx-color-picker": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/ngx-color-picker/-/ngx-color-picker-6.3.3.tgz", - "integrity": "sha512-0uoxt+3BtanTTbQj9elpsZe/6a/BWAl8jdl0m6OyrCXlCiO3q4zGZjWee4905RF0NXGxQvDWT27coqmDeXGsvw==" - }, - "ngx-cookie": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ngx-cookie/-/ngx-cookie-2.0.1.tgz", - "integrity": "sha512-3+agXZkoPxRP3IyELf7Eiuhk6TX+EAX974kkCR6Xjm+N7boEA+Fin2Q90AAE4XZzY48skkVzLH96TOikb5yU3g==" - }, - "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, - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-forge": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha1-bBUsNFzhHFL0ZcKr2VfoY5zWdN8=", - "dev": true - }, - "node-gyp": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", - "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - } - } - }, - "node-libs-browser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", - "integrity": "sha1-X5QmPUBPbkR2fXJpAf/wVHjWAN8=", - "dev": true, - "requires": { - "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-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/node-modules-path/-/node-modules-path-1.0.1.tgz", - "integrity": "sha1-QAlrCM560OoUaAhjr0ScfHWl0cg=", - "dev": true - }, - "node-sass": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.0.tgz", - "integrity": "sha512-W1XBrvoJ1dy7VsvTAS5q1V45lREbTlZQqFbiHb3R3OTTCma0XBtuG6xZ6Z4506nR4lmHPTqVRwxT6KgtWC97CA==", - "requires": { - "async-foreach": "^0.1.3", - "chalk": "^1.1.1", - "cross-spawn": "^3.0.0", - "gaze": "^1.0.0", - "get-stdin": "^4.0.1", - "glob": "^7.0.3", - "in-publish": "^2.0.0", - "lodash": "^4.17.15", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "nan": "^2.13.2", - "node-gyp": "^3.8.0", - "npmlog": "^4.0.0", - "request": "^2.88.0", - "sass-graph": "^2.2.4", - "stdout-stream": "^1.4.0", - "true-case-path": "^1.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "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" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - } - } - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "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 - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - }, - "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, - "requires": { - "path-key": "^2.0.0" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "nth-check": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", - "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "null-loader": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-0.1.1.tgz", - "integrity": "sha1-F76av80/8OFRL2/Er8sfUDk3j64=", - "dev": true - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "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=" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha1-CcU4VTd1dTEMymL1W7M0q/97PtI=" - }, - "object-path": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz", - "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "dependencies": { - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "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 - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "openurl": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz", - "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=", - "dev": true - }, - "opn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", - "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - } - } - }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", - "dev": true - }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, - "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 - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, - "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=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "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 - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", - "dev": true, - "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - } - }, - "pako": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", - "integrity": "sha1-AQEhG6pwxLykoPY/Igbpe3368lg=", - "dev": true - }, - "parallel-transform": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", - "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", - "requires": { - "cyclist": "~0.2.2", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "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, - "requires": { - "no-case": "^2.2.0" - } - }, - "parse-asn1": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha1-9r8pOBgzK9DatU77Fgh3JHRebKg=", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "parsejson": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", - "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "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 - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "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=" - }, - "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 - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "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=", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "requires": { - "pify": "^3.0.0" - } - }, - "pbkdf2": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", - "integrity": "sha1-dAQgjsawG2LYW/g4U6gGT42cKlw=", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "phantomjs-prebuilt": { - "version": "2.1.14", - "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.14.tgz", - "integrity": "sha1-1T0xH8+30dCN2yQBRVjxGIxRbaA=", - "dev": true, - "requires": { - "es6-promise": "~4.0.3", - "extract-zip": "~1.5.0", - "fs-extra": "~1.0.0", - "hasha": "~2.2.0", - "kew": "~0.7.0", - "progress": "~1.1.8", - "request": "~2.79.0", - "request-progress": "~2.0.1", - "which": "~1.2.10" - }, - "dependencies": { - "fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "requires": { - "find-up": "^2.1.0" - } - }, - "popsicle": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/popsicle/-/popsicle-9.2.0.tgz", - "integrity": "sha512-petRj39w05GvH1WKuGFmzxR9+k+R9E7zX5XWTFee7P/qf88hMuLT7aAO/RsmldpQMtJsWQISkTQlfMRECKlxhw==", - "dev": true, - "requires": { - "concat-stream": "^1.4.7", - "form-data": "^2.0.0", - "make-error-cause": "^1.2.1", - "tough-cookie": "^2.0.0" - } - }, - "popsicle-proxy-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/popsicle-proxy-agent/-/popsicle-proxy-agent-3.0.0.tgz", - "integrity": "sha1-uRM8VdlFdZq37mG3cRNkYg066tw=", - "dev": true, - "requires": { - "http-proxy-agent": "^1.0.0", - "https-proxy-agent": "^1.0.0" - } - }, - "popsicle-retry": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/popsicle-retry/-/popsicle-retry-3.2.1.tgz", - "integrity": "sha1-4G6GZTO0KnoSPrMwy+Y6fOvLoQw=", - "dev": true, - "requires": { - "any-promise": "^1.1.0", - "xtend": "^4.0.1" - } - }, - "popsicle-rewrite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/popsicle-rewrite/-/popsicle-rewrite-1.0.0.tgz", - "integrity": "sha1-HdTo6pwxgjUfuCD4eTTZkvf7kAc=", - "dev": true - }, - "popsicle-status": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/popsicle-status/-/popsicle-status-2.0.1.tgz", - "integrity": "sha1-jdcMT+fGlBCa3XhP/oDqysHnso0=", - "dev": true - }, - "portfinder": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.17.tgz", - "integrity": "sha1-qKFpEUPkbEc17e/PT7zM7a0mRWo=", - "dev": true, - "requires": { - "async": "^1.5.2", - "debug": "^2.2.0", - "mkdirp": "0.5.x" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - } - } - }, - "portscanner": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz", - "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=", - "dev": true, - "requires": { - "async": "1.5.2", - "is-number-like": "^1.0.3" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - } - } - }, - "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=" - }, - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "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 - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-calc": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", - "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", - "dev": true, - "requires": { - "postcss": "^5.0.2", - "postcss-message-helpers": "^2.0.0", - "reduce-css-calc": "^1.2.6" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "postcss-colormin": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", - "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", - "dev": true, - "requires": { - "colormin": "^1.0.5", - "postcss": "^5.0.13", - "postcss-value-parser": "^3.2.3" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.11", - "postcss-value-parser": "^3.1.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.14" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.4" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.14" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.16" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.14", - "uniqs": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "postcss-filter-plugins": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz", - "integrity": "sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ==", - "dev": true, - "requires": { - "postcss": "^5.0.4" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "postcss-import": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.1.0.tgz", - "integrity": "sha512-5l327iI75POonjxkXgdRCUS+AlzAdBx4pOvMEhTKTCjb1p8IEeVR9yx3cPbmN7LIWJLbfnIXxAhoB4jpD0c/Cw==", - "dev": true, - "requires": { - "postcss": "^6.0.1", - "postcss-value-parser": "^3.2.3", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - } - }, - "postcss-load-config": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", - "integrity": "sha1-8TEt2/WRLNdHF3CDxe96GdYu5IQ=", - "dev": true, - "requires": { - "cosmiconfig": "^4.0.0", - "import-cwd": "^2.0.0" - } - }, - "postcss-loader": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.6.tgz", - "integrity": "sha512-hgiWSc13xVQAq25cVw80CH0l49ZKlAnU1hKPOdRrNj89bokRr/bZF2nT+hebPPF9c9xs8c3gw3Fr2nxtmXYnNg==", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "postcss": "^6.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^0.4.0" - } - }, - "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, - "requires": { - "has": "^1.0.1", - "postcss": "^5.0.10", - "postcss-value-parser": "^3.1.1" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.4" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "browserslist": "^1.5.2", - "caniuse-api": "^1.5.2", - "postcss": "^5.0.4", - "postcss-selector-parser": "^2.2.2", - "vendors": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "browserslist": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", - "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", - "dev": true, - "requires": { - "caniuse-db": "^1.0.30000639", - "electron-to-chromium": "^1.2.7" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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 - }, - "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, - "requires": { - "object-assign": "^4.0.1", - "postcss": "^5.0.4", - "postcss-value-parser": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.12", - "postcss-value-parser": "^3.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "alphanum-sort": "^1.0.1", - "postcss": "^5.0.2", - "postcss-value-parser": "^3.0.2", - "uniqs": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "alphanum-sort": "^1.0.2", - "has": "^1.0.1", - "postcss": "^5.0.14", - "postcss-selector-parser": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^6.0.1" - } - }, - "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, - "requires": { - "css-selector-tokenizer": "^0.7.0", - "postcss": "^6.0.1" - } - }, - "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, - "requires": { - "css-selector-tokenizer": "^0.7.0", - "postcss": "^6.0.1" - } - }, - "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, - "requires": { - "icss-replace-symbols": "^1.1.0", - "postcss": "^6.0.1" - } - }, - "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, - "requires": { - "postcss": "^5.0.5" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^1.4.0", - "postcss": "^5.0.14", - "postcss-value-parser": "^3.2.3" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.4", - "postcss-value-parser": "^3.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.4", - "postcss-value-parser": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "postcss": "^5.0.4" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "has": "^1.0.1", - "postcss": "^5.0.8", - "postcss-value-parser": "^3.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "postcss-svgo": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", - "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", - "dev": true, - "requires": { - "is-svg": "^2.0.0", - "postcss": "^5.0.14", - "postcss-value-parser": "^3.2.3", - "svgo": "^0.7.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "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, - "requires": { - "alphanum-sort": "^1.0.1", - "postcss": "^5.0.4", - "uniqs": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "postcss-url": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.2.tgz", - "integrity": "sha512-QMV5mA+pCYZQcUEPQkmor9vcPQ2MT+Ipuu8qdi1gVxbNiIiErEGft+eny1ak19qALoBkccS5AHaCaCDzh7b9MA==", - "dev": true, - "requires": { - "mime": "^1.4.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.0", - "postcss": "^6.0.1", - "xxhashjs": "^0.2.1" - } - }, - "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 - }, - "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, - "requires": { - "has": "^1.0.1", - "postcss": "^5.0.4", - "uniqs": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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 - } - } - }, - "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 - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" - }, - "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, - "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" - } - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=" - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "optional": true, - "requires": { - "asap": "~2.0.3" - } - }, - "promise-finally": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/promise-finally/-/promise-finally-3.0.0.tgz", - "integrity": "sha1-3dXQ+JVDKxIGzrjaEnUGTRjnqiM=", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, - "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha1-7PxzO/Iv+Mb0B/onUye5q2fki5M=", - "dev": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.8.0" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha1-YPWA02AXC7cip5fMcEQR5tqFDGc=" - }, - "public-encrypt": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", - "integrity": "sha1-RuuRByBr9zSJ+LhbadkTNMZhCZQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true - }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true - }, - "qrious": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/qrious/-/qrious-2.3.0.tgz", - "integrity": "sha1-ynzmioIJmmepDkl59LHN9R7zJHU=", - "requires": { - "canvas": "^1.6.5" - } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "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, - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz", - "integrity": "sha1-+j7W5o6xUVlFfImze8ZHKDMZV1U=", - "dev": true - }, - "randomatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", - "integrity": "sha1-NvLKcI6eVn9e0uwBlJAm1QqhARY=", - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha1-ACbjf1RU1z41bf5lZGmYZ8an8P8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=" - } - } - }, - "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha1-0wLFIpSFiISKjTAMkytEwkIx2oA=", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, - "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, - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", - "unpipe": "1.0.0" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" - } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true - } - } - }, - "raw-loader": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", - "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", - "dev": true - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "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, - "requires": { - "pify": "^2.3.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "dependencies": { - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "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=", - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", - "requires": { - "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" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "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=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "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==" - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "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==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "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==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "recast": { - "version": "0.11.23", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", - "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", - "dev": true, - "requires": { - "ast-types": "0.9.6", - "esprima": "~3.1.0", - "private": "~0.1.5", - "source-map": "~0.5.0" - }, - "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - } - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "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, - "requires": { - "balanced-match": "^0.4.2", - "math-expression-evaluator": "^1.2.14", - "reduce-function-call": "^1.0.1" - }, - "dependencies": { - "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 - } - } - }, - "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, - "requires": { - "balanced-match": "^0.4.2" - }, - "dependencies": { - "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 - } - } - }, - "reflect-metadata": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.10.tgz", - "integrity": "sha1-tPg3BEFqytiZiMmxVjXUfgO5NEo=" - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexpu-core": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", - "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "registry-auth-token": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha1-hR/UkDjuy1hpERFa+EUmDuyYPyA=", - "dev": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true, - "requires": { - "rc": "^1.0.1" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "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=" - }, - "renderkid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", - "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=", - "dev": true, - "requires": { - "css-select": "^1.1.0", - "dom-converter": "~0.1", - "htmlparser2": "~3.3.0", - "strip-ansi": "^3.0.0", - "utila": "~0.3" - }, - "dependencies": { - "utila": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", - "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", - "dev": true - } - } - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.79.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", - "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", - "dev": true, - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.11.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~2.0.6", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "qs": "~6.3.0", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "~0.4.1", - "uuid": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - } - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.12" - } - }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "is-my-json-valid": "^2.12.4", - "pinkie-promise": "^2.0.0" - } - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "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 - }, - "qs": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", - "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", - "dev": true - }, - "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 - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "dev": true, - "requires": { - "punycode": "^1.4.1" - } - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true - } - } - }, - "request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", - "dev": true, - "requires": { - "throttleit": "^1.0.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha1-iaf92TgmEmcxjq/hT5wy5ZjDaQk=", - "dev": true - }, - "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=" - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha1-gvHsGaQjrB+9CAsLqwa6NuhKeiY=", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, - "resp-modifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz", - "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=", - "dev": true, - "requires": { - "debug": "^2.2.0", - "minimatch": "^3.0.2" - } - }, - "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, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "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, - "requires": { - "align-text": "^0.1.1" - } - }, - "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "requires": { - "glob": "^7.0.5" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "requires": { - "aproba": "^1.1.1" - } - }, - "rx": { - "version": "2.3.24", - "resolved": "https://registry.npmjs.org/rx/-/rx-2.3.24.tgz", - "integrity": "sha1-FPlQpCF9fjXapxu8vljv9o6ksrc=", - "dev": true - }, - "rxjs": { - "version": "5.5.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.7.tgz", - "integrity": "sha512-Hxo2ac8gRQjwjtKgukMIwBRbq5+KAeEV5hXM4obYBOAghev41bDQWgFH4svYiU9UnQ5kNww2LgfyBdevCd2HXA==", - "requires": { - "symbol-observable": "1.0.1" - }, - "dependencies": { - "symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sass-graph": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.6.tgz", - "integrity": "sha512-MKuEYXFSGuRSi8FZ3A7imN1CeVn9Gpw0/SFJKdL1ejXJneI9a5rwlEZrKejhEFAA3O6yr3eIyl/WuvASvlT36g==", - "requires": { - "glob": "^7.0.0", - "lodash": "^4.0.0", - "scss-tokenizer": "^0.2.3", - "yargs": "^7.0.0" - } - }, - "sass-loader": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.7.tgz", - "integrity": "sha512-JoiyD00Yo1o61OJsoP2s2kb19L1/Y2p3QFcCdWdF6oomBGKVYuZyqHWemRBfQ2uGYsk+CH3eCguXNfpjzlcpaA==", - "requires": { - "clone-deep": "^2.0.1", - "loader-utils": "^1.0.1", - "lodash.tail": "^4.1.1", - "neo-async": "^2.5.0", - "pify": "^3.0.0" - } - }, - "sax": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - }, - "dependencies": { - "ajv": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz", - "integrity": "sha1-JH1SdBENtlNwa1UPzCt5fKKM/Fk=", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - } - } - }, - "script-loader": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/script-loader/-/script-loader-0.7.0.tgz", - "integrity": "sha1-aF3H5waeDe56kmdPDrxbD1W6pew=", - "dev": true, - "requires": { - "raw-loader": "~0.5.1" - } - }, - "scss-tokenizer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", - "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", - "requires": { - "js-base64": "^2.1.8", - "source-map": "^0.4.2" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.3.tgz", - "integrity": "sha1-1ijs+eNzX4TouvupNrPPhb6kOCM=", - "dev": true, - "requires": { - "node-forge": "0.7.5" - } - }, - "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha1-ff3YgUvbfKvHvg+x1zTPtmyUBHc=" - }, - "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", - "dev": true, - "requires": { - "semver": "^5.0.3" - } - }, - "semver-intersect": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.4.0.tgz", - "integrity": "sha512-d8fvGg5ycKAq0+I6nfWeCx6ffaWJCsBYU0H2Rq56+/zFePYfT8mXkB3tWBSjR5BerkHNZ5eTPIk1/LBYas35xQ==", - "dev": true, - "requires": { - "semver": "^5.0.0" - } - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha1-bsyh4PjBVtFBWXVZhI32RzCmu8E=", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "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.4.0" - }, - "dependencies": { - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha1-Eh+evEnjdm8xGnbh+hyAA8SwOqY=", - "dev": true - } - } - }, - "serialize-javascript": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", - "integrity": "sha1-GqM2FiyIqJDdrVOEuuvJOmVRYf4=" - }, - "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, - "requires": { - "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" - } - }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha1-CV6Ecv1bRiN9tQzkhqQ/S4bGzsE=", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" - } - }, - "server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha1-ca5KiPD+77v1LR6mBPP7MV67YnQ=", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", - "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", - "requires": { - "is-extendable": "^0.1.1", - "kind-of": "^5.0.0", - "mixin-object": "^2.0.1" - }, - "dependencies": { - "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==" - } - } - }, - "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, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "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 - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "silent-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/silent-error/-/silent-error-1.1.0.tgz", - "integrity": "sha1-IglwbxyFCp8dENDYQJGLRvJuG8k=", - "dev": true, - "requires": { - "debug": "^2.2.0" - } - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "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 - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "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": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "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==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "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==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "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==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=" - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - } - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.x.x" - } - }, - "socket.io": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz", - "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=", - "dev": true, - "requires": { - "debug": "2.3.3", - "engine.io": "1.8.3", - "has-binary": "0.1.7", - "object-assign": "4.1.0", - "socket.io-adapter": "0.5.0", - "socket.io-client": "1.7.3", - "socket.io-parser": "2.3.1" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - }, - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true - } - } - }, - "socket.io-adapter": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", - "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", - "dev": true, - "requires": { - "debug": "2.3.3", - "socket.io-parser": "2.3.1" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "socket.io-client": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz", - "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=", - "dev": true, - "requires": { - "backo2": "1.0.2", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "2.3.3", - "engine.io-client": "1.8.3", - "has-binary": "0.1.7", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseuri": "0.0.5", - "socket.io-parser": "2.3.1", - "to-array": "0.1.4" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "socket.io-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", - "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", - "dev": true, - "requires": { - "component-emitter": "1.1.2", - "debug": "2.2.0", - "isarray": "0.0.1", - "json3": "3.3.2" - }, - "dependencies": { - "component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", - "dev": true - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", - "dev": true, - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" - } - }, - "sockjs-client": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.5.tgz", - "integrity": "sha1-G7fA9yIsQPQq3xT0RCy9Eml3GoM=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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, - "requires": { - "websocket-driver": ">=0.5.1" - } - } - } - }, - "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, - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "source-list-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha1-qqR0A/eyRakvvJfqCPJQ1gh+0IU=" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha1-cuLMNAlVQ+Q7LGKyxMENSpBU8lk=", - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha1-QbyVOyU0Jn6i1gW8z6e/oxEc7V8=", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=" - } - } - }, - "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=" - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", - "dev": true - }, - "spdx-correct": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha1-BaW01xU6GVvJLDxCW2nzsqlSTII=", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha1-LHrmEFbHFKW5ubKyr30xHvXHj+k=" - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz", - "integrity": "sha1-4qMDI2ysVLBAMfp6WnnH5wHfhS8=" - }, - "spdy": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", - "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=", - "dev": true, - "requires": { - "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" - } - }, - "spdy-transport": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz", - "integrity": "sha1-S7sVqv/tC+791WrWHb3Iuj4st6E=", - "dev": true, - "requires": { - "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" - } - }, - "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==", - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", - "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", - "requires": { - "safe-buffer": "^5.1.1" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha1-u3PURtonlhBu/MG2AaJT1sRr0Ic=", - "dev": true - }, - "stdout-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", - "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", - "requires": { - "readable-stream": "^2.0.1" - } - }, - "stream-browserify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" - }, - "stream-throttle": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", - "integrity": "sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=", - "dev": true, - "requires": { - "commander": "^2.2.0", - "limiter": "^1.0.5" - } - }, - "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 - }, - "string-template": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", - "integrity": "sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "stringstream": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "^0.2.0" - } - }, - "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 - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "requires": { - "get-stdin": "^4.0.1" - } - }, - "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 - }, - "style-loader": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.17.0.tgz", - "integrity": "sha1-6CVLzNt690vVgnTjYQe01atN8xA=", - "dev": true, - "requires": { - "loader-utils": "^1.0.2" - } - }, - "stylus": { - "version": "0.54.5", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", - "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", - "dev": true, - "requires": { - "css-parse": "1.7.x", - "debug": "*", - "glob": "7.0.x", - "mkdirp": "0.5.x", - "sax": "0.5.x", - "source-map": "0.1.x" - }, - "dependencies": { - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", - "dev": true, - "requires": { - "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" - } - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "stylus-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", - "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "lodash.clonedeep": "^4.5.0", - "when": "~3.6.x" - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "requires": { - "has-flag": "^2.0.0" - } - }, - "svgo": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", - "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "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, - "requires": { - "argparse": "^1.0.7", - "esprima": "^2.6.0" - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", - "dev": true - } - } - }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - }, - "systemjs": { - "version": "0.20.12", - "resolved": "https://registry.npmjs.org/systemjs/-/systemjs-0.20.12.tgz", - "integrity": "sha1-E1zEcSgESEUzR4Keu5Y5oJpn8QE=" - }, - "tapable": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", - "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=" - }, - "tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", - "requires": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" - } - }, - "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", - "dev": true, - "requires": { - "execa": "^0.7.0" - } - }, - "tfunk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-3.1.0.tgz", - "integrity": "sha1-OORBT8ZJd9h6/apy+sttKfgve1s=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "object-path": "^0.9.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - } - }, - "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 - } - } - }, - "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", - "dev": true, - "requires": { - "any-promise": "^1.0.0" - } - }, - "throat": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-3.2.0.tgz", - "integrity": "sha512-/EY8VpvlqJ+sFtLPeOgc8Pl7kQVOWv0woD87KTXVHPIAE842FGT+rokxIhe8xIUP1cfgrkt0as0vDLjDiMtr8w==", - "dev": true - }, - "throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" - } - }, - "thunky": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz", - "integrity": "sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E=", - "dev": true - }, - "time-stamp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.1.0.tgz", - "integrity": "sha1-bFwLK8g1okRharz934HOE6GXXJ8=", - "dev": true - }, - "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=", - "dev": true - }, - "timers-browserify": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", - "integrity": "sha1-HSjj0qrfHVpZlsTp+VYBzQU0gK4=", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "tiny-emitter": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-1.2.0.tgz", - "integrity": "sha1-bchFBSywjr78GHRyO1jySmSMO28=" - }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.1" - } - }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, - "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 - }, - "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 - }, - "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=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "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=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "to-string-loader": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/to-string-loader/-/to-string-loader-1.1.5.tgz", - "integrity": "sha1-e3qheJG3u0lHp6Eb+wO1/enG5pU=", - "dev": true, - "requires": { - "loader-utils": "^0.2.16" - }, - "dependencies": { - "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, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - } - } - }, - "toposort": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", - "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", - "dev": true - }, - "touch": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-1.0.0.tgz", - "integrity": "sha1-RJy+LbrlqMgDjjDXH6D/RklHxN4=", - "dev": true, - "requires": { - "nopt": "~1.0.10" - }, - "dependencies": { - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "requires": { - "abbrev": "1" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha1-U/Nto/R3g7CSWvoG/587FlKA94E=", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" - }, - "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 - }, - "true-case-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", - "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", - "requires": { - "glob": "^7.1.2" - } - }, - "tsickle": { - "version": "0.27.5", - "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.27.5.tgz", - "integrity": "sha512-NP+CjM1EXza/M8mOXBLH3vkFEJiu1zfEAlC5WdJxHPn8l96QPz5eooP6uAgYtw1CcKfuSyIiheNUdKxtDWCNeg==", - "requires": { - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map": "^0.6.0", - "source-map-support": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha1-1+TdeSRdhUKMTX5IIqeZF5VMooY=" - }, - "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 - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "optional": true - }, - "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha1-+JzjQVQcZysl7nrjxz3uOyvlAZQ=", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.18" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "typescript": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.4.2.tgz", - "integrity": "sha1-+DlfhdRZJ2BnyYiqQYN6j4KHCEQ=" - }, - "typings": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/typings/-/typings-2.1.1.tgz", - "integrity": "sha1-usxp0lWXCkeOCfdsf2iZddU1p4o=", - "dev": true, - "requires": { - "archy": "^1.0.0", - "bluebird": "^3.1.1", - "chalk": "^1.0.0", - "cli-truncate": "^1.0.0", - "columnify": "^1.5.2", - "elegant-spinner": "^1.0.1", - "has-unicode": "^2.0.1", - "listify": "^1.0.0", - "log-update": "^1.0.2", - "minimist": "^1.2.0", - "promise-finally": "^3.0.0", - "typings-core": "^2.3.3", - "update-notifier": "^2.0.0", - "wordwrap": "^1.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "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" - } - }, - "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 - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, - "typings-core": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/typings-core/-/typings-core-2.3.3.tgz", - "integrity": "sha1-CexUzVsR3V8e8vwKsx03ACyita0=", - "dev": true, - "requires": { - "array-uniq": "^1.0.2", - "configstore": "^3.0.0", - "debug": "^2.2.0", - "detect-indent": "^5.0.0", - "graceful-fs": "^4.1.2", - "has": "^1.0.1", - "invariant": "^2.2.0", - "is-absolute": "^0.2.3", - "jspm-config": "^0.3.0", - "listify": "^1.0.0", - "lockfile": "^1.0.1", - "make-error-cause": "^1.2.1", - "mkdirp": "^0.5.1", - "object.pick": "^1.1.1", - "parse-json": "^2.2.0", - "popsicle": "^9.0.0", - "popsicle-proxy-agent": "^3.0.0", - "popsicle-retry": "^3.2.0", - "popsicle-rewrite": "^1.0.0", - "popsicle-status": "^2.0.0", - "promise-finally": "^3.0.0", - "rc": "^1.1.5", - "rimraf": "^2.4.4", - "sort-keys": "^1.0.0", - "string-template": "^1.0.0", - "strip-bom": "^3.0.0", - "thenify": "^3.1.0", - "throat": "^3.0.0", - "touch": "^1.0.0", - "typescript": "^2.1.4", - "xtend": "^4.0.0", - "zip-object": "^0.1.0" - }, - "dependencies": { - "detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", - "dev": true - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "ua-parser-js": { - "version": "0.7.17", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", - "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==", - "dev": true - }, - "uglify-js": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha1-rwLxgMEgfXZDLkc+0koo9KeCuuM=", - "dev": true, - "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha1-vXerfebelCBc6sxy8XFtKfIKd78=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", - "dev": true - } - } - }, - "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 - }, - "uglifyjs-webpack-plugin": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz", - "integrity": "sha512-ovHIch0AMlxjD/97j9AYovZxG5wnHOPkL7T1GKochBADp/Zwc44pEWNqpKl1Loupp1WhFg7SlYmHZRUfdAacgw==", - "dev": true, - "requires": { - "cacache": "^10.0.4", - "find-cache-dir": "^1.0.0", - "schema-utils": "^0.4.5", - "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" - }, - "dependencies": { - "commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true - }, - "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 - }, - "uglify-es": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", - "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", - "dev": true, - "requires": { - "commander": "~2.13.0", - "source-map": "~0.6.1" - } - } - } - }, - "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", - "integrity": "sha1-Xp7cbRzo+yZNsYpQfvm9hURFHKY=", - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", - "dev": true, - "requires": { - "crypto-random-string": "^1.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", - "dev": true - }, - "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha1-NSVll+RqWB20eT0M5H+prr/J+r0=", - "dev": true - }, - "update-notifier": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", - "dev": true, - "requires": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=" - } - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-loader": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.6.2.tgz", - "integrity": "sha512-h3qf9TNn53BpuXTTcpC+UehiRrl0Cv45Yr/xWayApjw6G8Bg2dGke7rIwDQ39piciWCWrC+WiqLjOh3SUp9n0Q==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "mime": "^1.4.1", - "schema-utils": "^0.3.0" - }, - "dependencies": { - "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, - "requires": { - "ajv": "^5.0.0" - } - } - } - }, - "url-parse": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz", - "integrity": "sha1-v67kVciJAjIZ11fgRfpqaE7DbBU=", - "dev": true, - "requires": { - "querystringify": "^2.0.0", - "requires-port": "^1.0.0" - } - }, - "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=", - "dev": true, - "requires": { - "prepend-http": "^1.0.1" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" - }, - "useragent": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", - "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", - "dev": true, - "requires": { - "lru-cache": "4.1.x", - "tmp": "0.0.x" - } - }, - "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha1-OqASW/5mikZy3liFfTrOJ+y3aQE=", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha1-G0r0lV6zB3xQHCOHL8ZROBFYcTE=" - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "vendors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", - "integrity": "sha1-f8te759WI7FWvOqJ7DfWNnbyGAE=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==" - }, - "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, - "requires": { - "indexof": "0.0.1" - } - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha1-S8EsLr6KonenHx0/FNaFx7RGzQA=", - "dev": true, - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "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 - }, - "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 - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha1-NW/04rDo5D4yLRijckYLvPOszSY=", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "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, - "requires": { - "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" - }, - "dependencies": { - "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, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "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=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "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 - }, - "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, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "webpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.4.1.tgz", - "integrity": "sha1-FakdvjSWbYpLmcfWVu/ZKi5ab2o=", - "dev": true, - "requires": { - "acorn": "^5.0.0", - "acorn-dynamic-import": "^2.0.0", - "ajv": "^4.7.0", - "ajv-keywords": "^1.1.1", - "async": "^2.1.2", - "enhanced-resolve": "^3.0.0", - "interpret": "^1.0.0", - "json-loader": "^0.5.4", - "json5": "^0.5.1", - "loader-runner": "^2.3.0", - "loader-utils": "^0.2.16", - "memory-fs": "~0.4.1", - "mkdirp": "~0.5.0", - "node-libs-browser": "^2.0.0", - "source-map": "^0.5.3", - "supports-color": "^3.1.0", - "tapable": "~0.2.5", - "uglify-js": "^2.8.5", - "watchpack": "^1.3.1", - "webpack-sources": "^0.2.3", - "yargs": "^6.0.0" - }, - "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "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 - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "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 - }, - "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, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - }, - "source-list-map": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-1.1.2.tgz", - "integrity": "sha1-mIkBnRAkzOVc3AaUmDN+9hhqEaE=", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "webpack-sources": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz", - "integrity": "sha1-F8Yr+vE8cH+dAsR54Nzd6DgGl/s=", - "dev": true, - "requires": { - "source-list-map": "^1.1.1", - "source-map": "~0.5.3" - } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", - "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - } - } - }, - "yargs-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - } - } - } - } - }, - "webpack-core": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", - "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", - "dev": true, - "requires": { - "source-list-map": "~0.1.7", - "source-map": "~0.4.1" - }, - "dependencies": { - "source-list-map": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", - "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", - "dev": true - }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "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, - "requires": { - "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" - } - }, - "webpack-dev-server": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.4.5.tgz", - "integrity": "sha1-MThM6BE2vhCAtLTN4OubkOVO5s8=", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "chokidar": "^1.6.0", - "compression": "^1.5.2", - "connect-history-api-fallback": "^1.3.0", - "express": "^4.13.3", - "html-entities": "^1.2.0", - "http-proxy-middleware": "~0.17.4", - "opn": "4.0.2", - "portfinder": "^1.0.9", - "serve-index": "^1.7.2", - "sockjs": "0.3.18", - "sockjs-client": "1.1.2", - "spdy": "^3.4.1", - "strip-ansi": "^3.0.0", - "supports-color": "^3.1.1", - "webpack-dev-middleware": "^1.10.2", - "yargs": "^6.0.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "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 - }, - "opn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", - "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "sockjs": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.18.tgz", - "integrity": "sha1-2bKJMWyn33dZXvKZ4HXw+TfrQgc=", - "dev": true, - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^2.0.2" - } - }, - "sockjs-client": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.2.tgz", - "integrity": "sha1-8CEqhVDkyUaMjM6u79LjSTwDOtU=", - "dev": true, - "requires": { - "debug": "^2.2.0", - "eventsource": "0.1.6", - "faye-websocket": "~0.11.0", - "inherits": "^2.0.1", - "json3": "^3.3.2", - "url-parse": "^1.1.1" - }, - "dependencies": { - "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, - "requires": { - "websocket-driver": ">=0.5.1" - } - } - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - }, - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", - "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", - "dev": true, - "requires": { - "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" - } - }, - "yargs-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - } - } - }, - "webpack-merge": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.0.tgz", - "integrity": "sha1-atciI7PguDflMeRZfBmfkJNhUR4=", - "dev": true, - "requires": { - "lodash": "^4.17.4" - } - }, - "webpack-sources": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", - "integrity": "sha1-KijcufH0X+lg2PFJMlK17mUw+oU=", - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=" - } - } - }, - "webpack-subresource-integrity": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.0.4.tgz", - "integrity": "sha1-j6yKfo61n8ahZ2ioXJ2U7n+dDts=", - "dev": true, - "requires": { - "webpack-core": "^0.6.8" - } - }, - "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, - "requires": { - "http-parser-js": ">=0.4.0", - "websocket-extensions": ">=0.1.1" - } - }, - "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 - }, - "when": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", - "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=", - "dev": true - }, - "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 - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "widest-line": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz", - "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=", - "dev": true, - "requires": { - "string-width": "^2.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "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 - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "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 - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - }, - "worker-farm": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", - "integrity": "sha1-rsxAWXb6talVJhgIRvDboojzpKA=", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha1-H/YVdcLipOjlENb6TiQ8zhg5mas=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "ws": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", - "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", - "dev": true, - "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" - } - }, - "wtf-8": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", - "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", - "dev": true - }, - "xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", - "dev": true - }, - "xhr2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", - "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=" - }, - "xmlhttprequest-ssl": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", - "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", - "dev": true - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "xxhashjs": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", - "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", - "dev": true, - "requires": { - "cuint": "^0.2.2" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "yargs": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", - "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", - "requires": { - "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": "^5.0.1" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" - } - } - }, - "yargs-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", - "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", - "requires": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - } - } - }, - "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", - "dev": true, - "requires": { - "fd-slicer": "~1.0.1" - } - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true - }, - "zip-object": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/zip-object/-/zip-object-0.1.0.tgz", - "integrity": "sha1-waDaBMiMg3dW4khoCgP/kC7D9To=", - "dev": true - }, - "zone.js": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.10.tgz", - "integrity": "sha1-bRtpZJLAKc2+gI5Z6Hu9lJG5iqg=" - } - } -} diff --git a/prog/gameLibs/webui/plugins/webView/src/package.json b/prog/gameLibs/webui/plugins/webView/src/package.json deleted file mode 100644 index 496aabc2d..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/package.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "name": "enlisted-webui", - "version": "1.0.0", - "scripts": { - "start": "webpack-dev-server --inline --progress --port 4010", - "lite": "lite-server", - "postinstall": "typings install", - "tsc": "tsc", - "tsc:w": "tsc -w", - "typings": "typings", - "build": "webpack --display-error-details --config config/webpack.dev.js --progress --profile --bail", - "build:prod": "webpack --display-error-details --config config/webpack.prod.js --progress --profile --bail" - }, - "license": "ISC", - "dependencies": { - "@angular/animations": "5.2.9", - "@angular/common": "5.2.9", - "@angular/compiler": "5.2.9", - "@angular/compiler-cli": "5.2.9", - "@angular/core": "5.2.9", - "@angular/forms": "5.2.9", - "@angular/http": "5.2.9", - "@angular/platform-browser": "5.2.9", - "@angular/platform-browser-dynamic": "5.2.9", - "@angular/platform-server": "5.2.9", - "@angular/router": "5.2.9", - "@angular/upgrade": "5.2.9", - "@ng-bootstrap/ng-bootstrap": "1.0.1", - "@ngtools/webpack": "1.10.2", - "@swimlane/ngx-datatable": "11.2.0", - "ang-jsoneditor": "1.5.12", - "angular-in-memory-web-api": "0.3.2", - "angular-tree-component": "7.0.1", - "angular2-clipboard": "2.0.14", - "angular2-highcharts": "0.5.5", - "angular2-qrcode": "2.0.1", - "angular2-uuid": "1.1.1", - "angular2-websocket": "0.9.2", - "bootstrap": "3.3.7", - "clipboard": "1.6.1", - "copy-webpack-plugin": "4.5.1", - "core-js": "2.4.1", - "jsoneditor": "5.16.0", - "lodash": "4.17.4", - "ngx-color-picker": "6.3.3", - "ngx-cookie": "2.0.1", - "node-sass": "4.13.0", - "reflect-metadata": "0.1.10", - "rxjs": "5.5.7", - "sass-loader": "6.0.7", - "systemjs": "0.20.12", - "typescript": "2.4", - "zone.js": "0.8.10", - "tree-kill": "1.2.2" - }, - "devDependencies": { - "@angular/cli": "1.7.3", - "@angular/compiler-cli": "5.2.9", - "@types/core-js": "0.9.41", - "@types/node": "7.0.16", - "angular2-template-loader": "0.6.2", - "awesome-typescript-loader": "3.1.3", - "concurrently": "3.4.0", - "css-loader": "0.28.1", - "extract-text-webpack-plugin": "2.1.2", - "file-loader": "0.11.1", - "html-loader": "0.4.5", - "html-webpack-plugin": "2.28.0", - "jasmine-core": "2.6.1", - "karma": "1.6.0", - "karma-jasmine": "1.1.0", - "karma-phantomjs-launcher": "1.0.4", - "karma-sourcemap-loader": "0.3.7", - "karma-webpack": "2.0.3", - "lite-server": "2.3.0", - "null-loader": "0.1.1", - "phantomjs-prebuilt": "2.1.14", - "raw-loader": "0.5.1", - "rimraf": "2.6.1", - "script-loader": "0.7.0", - "style-loader": "0.17.0", - "to-string-loader": "1.1.5", - "typings": "2.1.1", - "webpack": "2.4.1", - "webpack-dev-server": "2.4.5", - "webpack-merge": "4.1.0" - } -} diff --git a/prog/gameLibs/webui/plugins/webView/src/start.bat b/prog/gameLibs/webui/plugins/webView/src/start.bat deleted file mode 100644 index b18eb1f48..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/start.bat +++ /dev/null @@ -1,2 +0,0 @@ -start ng serve -:EOF \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/tsconfig.json b/prog/gameLibs/webui/plugins/webView/src/tsconfig.json deleted file mode 100644 index 687d7b0be..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "target": "es6", - "module": "commonjs", - "moduleResolution": "node", - "sourceMap": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "removeComments": false, - "noImplicitAny": false - }, - "exclude": [ - "typings", - "node_modules", - "dist", - "**/*.ngfactory.ts", - "**/*.shim.ts", - "app/bootstrap*.ts", - "app/polyfill.ts" - ], - "awesomeTypescriptLoaderOptions": { - "forkChecker": true, - "useWebpackText": true - } -} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/typings.json b/prog/gameLibs/webui/plugins/webView/src/typings.json deleted file mode 100644 index 7da31ca0a..000000000 --- a/prog/gameLibs/webui/plugins/webView/src/typings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "globalDependencies": { - "core-js": "registry:dt/core-js#0.0.0+20160725163759", - "jasmine": "registry:dt/jasmine#2.2.0+20160621224255", - "node": "registry:dt/node#6.0.0+20160909174046" - } -} diff --git a/prog/gameLibs/webui/plugins/webView/vue/app.js b/prog/gameLibs/webui/plugins/webView/vue/app.js new file mode 100644 index 000000000..6907bcf62 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/app.js @@ -0,0 +1,73 @@ +const { createApp, ref, reactive, computed, defineComponent, defineAsyncComponent } = Vue; + +import helpers from "./core/helpers.js"; +import services from "./core/services.js"; + +const plugins = { + install() { + Vue.helpers = helpers; + Vue.services = services; + Vue.prototype.$helpers = helpers; + Vue.prototype.$services = services; + } +} +Vue.use(plugins); + +export const status = ref("Offline"); +export const statusClass = computed(() => { + return status.value.toLowerCase() !== 'online' ? 'offline' : 'online'; +}); + +export const SortableColumn = defineComponent({ + props: { + columnTitle: String, + columnClass: String | Object, + columnStyle: String | Object, + }, + setup(props) { + const sorted = ref(''); + + function sortValues() { + if (sorted.value === 'up') { + sorted.value = 'down'; + } else if (sorted.value === 'down') { + sorted.value = ''; + } else { + sorted.value = 'up'; + } + this.$emit('sort'); + } + + return { + sorted, + sortValues, + } + }, + template: ` +
+ {{ columnTitle }} + + +
+ ` +}); + +const MyApp = { + setup() { + return { + status, + statusClass, + } + }, + components: { + 'editor': defineAsyncComponent(() => Vue.helpers.loadModule('./vue/components/editor.vue')) + } +} + +export var app = null; + +export function createMyApp() { + app = createApp(MyApp).mount('#app'); + + Vue.myApp = app; +} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/dm-effects.vue b/prog/gameLibs/webui/plugins/webView/vue/components/dm-effects.vue new file mode 100644 index 000000000..b257f7a66 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/dm-effects.vue @@ -0,0 +1,112 @@ + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/dm-events.vue b/prog/gameLibs/webui/plugins/webView/vue/components/dm-events.vue new file mode 100644 index 000000000..acd09ddda --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/dm-events.vue @@ -0,0 +1,71 @@ + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/dm-meta-parts.vue b/prog/gameLibs/webui/plugins/webView/vue/components/dm-meta-parts.vue new file mode 100644 index 000000000..6ba07d700 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/dm-meta-parts.vue @@ -0,0 +1,53 @@ + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/dm-parts.vue b/prog/gameLibs/webui/plugins/webView/vue/components/dm-parts.vue new file mode 100644 index 000000000..20c284190 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/dm-parts.vue @@ -0,0 +1,76 @@ + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/dm.vue b/prog/gameLibs/webui/plugins/webView/vue/components/dm.vue new file mode 100644 index 000000000..e8f4d6943 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/dm.vue @@ -0,0 +1,75 @@ + + + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/ecs-components.vue b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-components.vue new file mode 100644 index 000000000..8ae77d009 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-components.vue @@ -0,0 +1,134 @@ + + + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/ecs-dynamic-query.vue b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-dynamic-query.vue new file mode 100644 index 000000000..199265664 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-dynamic-query.vue @@ -0,0 +1,422 @@ + + + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/ecs-entities.vue b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-entities.vue new file mode 100644 index 000000000..a1f632ffa --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-entities.vue @@ -0,0 +1,558 @@ + + + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/ecs-events.vue b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-events.vue new file mode 100644 index 000000000..ae8f185cb --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-events.vue @@ -0,0 +1,85 @@ + + + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/ecs-queries.vue b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-queries.vue new file mode 100644 index 000000000..db22f9f56 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-queries.vue @@ -0,0 +1,169 @@ + + + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/ecs-systems.vue b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-systems.vue new file mode 100644 index 000000000..8bb86da77 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-systems.vue @@ -0,0 +1,188 @@ + + + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/ecs-templates.vue b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-templates.vue new file mode 100644 index 000000000..935ad89f8 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/ecs-templates.vue @@ -0,0 +1,442 @@ + + + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/ecs.vue b/prog/gameLibs/webui/plugins/webView/vue/components/ecs.vue new file mode 100644 index 000000000..530e86597 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/ecs.vue @@ -0,0 +1,222 @@ + + + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/components/editor.vue b/prog/gameLibs/webui/plugins/webView/vue/components/editor.vue new file mode 100644 index 000000000..c59f6180d --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/components/editor.vue @@ -0,0 +1,261 @@ + + + + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/core/common.ts b/prog/gameLibs/webui/plugins/webView/vue/core/common.js similarity index 64% rename from prog/gameLibs/webui/plugins/webView/src/app/core/common.ts rename to prog/gameLibs/webui/plugins/webView/vue/core/common.js index 91444196a..59ac1ca0a 100644 --- a/prog/gameLibs/webui/plugins/webView/src/app/core/common.ts +++ b/prog/gameLibs/webui/plugins/webView/vue/core/common.js @@ -1,17 +1,4 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { StreamService, deserializeBSON } from '../core/stream.service'; -import { CoreService } from '../core/core.service'; - -import { Observable } from 'rxjs/Observable'; -import { Subscription } from 'rxjs/Subscription'; - -export interface Dictionary -{ - [K: string]: T; -} - -export function compToString(v, pretty:boolean = false): string -{ +export function compToString(v, pretty = false) { let formatFloat = (v) => { return parseFloat(v).toFixed(3); }; let isSet = (v) => { return typeof v !== 'undefined'; } @@ -27,125 +14,107 @@ export function compToString(v, pretty:boolean = false): string return pretty ? JSON.stringify(v, null, 2) : JSON.stringify(v); } -export abstract class BaseComponent implements OnInit, OnDestroy -{ - constructor(public coreService: CoreService) - { +export function RGBAToHex(rgba) { + console.log('RGBAToHex', rgba); + const toh = v => ('0' + v.toString(16)).substr(-2); + return '#' + toh(rgba[0]) + toh(rgba[1]) + toh(rgba[2]) + toh(typeof rgba[3] !== undefined ? (rgba[3] * 255) : 255); +} + +export class BaseComponent { + constructor() { } - ngOnInit(): void - { + ngOnInit() { console.log('BaseComponent::OnInit', this.constructor.name); } - ngOnDestroy(): void - { + ngOnDestroy() { console.log('BaseComponent::OnDestroy'); } - sendCommand(cmd: string, params: any = null): void - { + sendCommand(cmd, params = null) { this.coreService.sendCommand(cmd, params); } - runConsoleRaw(data: string): void - { + runConsoleRaw(data) { let cmd; let params = {}; let args = data.split(' '); cmd = args[0]; - for (let i = 1; i < args.length; ++i) - { + for (let i = 1; i < args.length; ++i) { params['arg' + (i - 1)] = args[i]; } this.runConsole(cmd, params); } - runConsole(cmd: string, params: any = null): void - { + runConsole(cmd, params = null) { let tmp = params || {}; tmp.command = cmd; this.sendCommand('console', tmp); } - runConsoleScript(commands: any): void - { - for (let cmd of commands) - { + runConsoleScript(commands) { + for (let cmd of commands) { this.runConsole(cmd[0], cmd[1] ? cmd[1] : null); } } - formatValue(v, pretty:boolean = false): string - { + formatValue(v, pretty = false) { return compToString(v, pretty) } - runCommand(cmd: string): void - { + runCommand(cmd) { this.sendCommand('runCommand', { command: cmd }); } - buildAndSendCommand(command) - { + buildAndSendCommand(command) { this.coreService.buildAndSendCommand(command); } - trackById(index, item) - { + trackById(index, item) { return item.id; } - trackByEid(index, item) - { + trackByEid(index, item) { return item.eid; } - trackByName(index, item) - { + trackByName(index, item) { return item.name; } - trackByValue(index, item) - { + trackByValue(index, item) { return item; } - open(content, opts?) - { + open(content, opts = undefined) { this.coreService.modalService.open(content, opts).result.then(result => { }, reason => { }); } get isConnected() { return this.coreService.isConnected; }; } -export interface IMessageListener -{ - onOpen(): void; - onMessage(data): void; -} +// export interface IMessageListener { +// onOpen(): void; +// onMessage(data): void; +// } -export function valueToBLK(type: string, value: any, key: string, options: any): string -{ +export function valueToBLK(type, value, key, options) { if (key && key[0] === '_' && !key.endsWith(":object") && !key.endsWith(":array")) return ''; - const wrap = v => '"'+ v + '"'; + const wrap = v => '"' + v + '"'; - if (type === 'string') - { + if (type === 'string') { return wrap(key) + ':t="' + value + '"'; } - if (type === 'number') - { + if (type === 'number') { return wrap(key) + ':r=' + value; } - if (type === 'boolean') - { + if (type === 'boolean') { return wrap(key) + ':b=' + (value ? 'yes' : 'no'); } - if (type === 'object') - { + if (type === 'object') { if (typeof value.toBlk == 'function') return valueToBLK('object', value.toBlk(), key, options); @@ -156,44 +125,35 @@ export function valueToBLK(type: string, value: any, key: string, options: any): if (isSet(value.x) && isSet(value.y) && isSet(value.z)) return `${wrap(key)}:p3=${value.x},${value.y},${value.z}`; if (isSet(value.x) && isSet(value.y)) return `${wrap(key)}:p2=${value.x},${value.y}`; - let subtype: string = Object.keys(value)[0]; + let subtype = Object.keys(value)[0]; let subvalue = value[subtype]; - if (subtype === 'r') - { + if (subtype === 'r') { return wrap(key) + ':' + subtype + '=' + subvalue; } - if (subtype === 'i') - { + if (subtype === 'i') { return wrap(key) + ':' + subtype + '=' + subvalue; } - if (subtype === 'eid') - { + if (subtype === 'eid') { return `"${key}:eid"{value:i=${subvalue};}`; } - if (subtype === 'p2' || subtype === 'p3' || subtype === 'p4' || subtype === 'c') - { + if (subtype === 'p2' || subtype === 'p3' || subtype === 'p4' || subtype === 'c') { return wrap(key) + ':' + subtype + '=' + subvalue.join(','); } - if (subtype === 'm') - { + if (subtype === 'm') { return wrap(key) + ':' + subtype + '=[[' + subvalue[0].join(',') + '] [' + subvalue[1].join(',') + '] [' + subvalue[2].join(',') + '] [' + subvalue[3].join(',') + ']]'; } - if (subtype === 'array') - { + if (subtype === 'array') { let tmp = ''; - for (let item of subvalue) - { + for (let item of subvalue) { tmp += wrap(key) + '{' + jsonToBLK(item) + '}'; tmp += "\n"; } return tmp; } - if (Array.isArray(value)) - { + if (Array.isArray(value)) { let res = ''; - for (let itm of value) - { + for (let itm of value) { res += valueToBLK(typeof itm, itm, key, options) + "\n"; } if (options.markBlockWithTypes && !key.endsWith(":object") && !key.endsWith(":array")) @@ -207,22 +167,17 @@ export function valueToBLK(type: string, value: any, key: string, options: any): return ''; } -export function jsonToBLK(json: any, options = { markBlockWithTypes: false }): string -{ +export function jsonToBLK(json, options = { markBlockWithTypes: false }) { let blk = ""; - if (Array.isArray(json)) - { - for (let itm of json) - { + if (Array.isArray(json)) { + for (let itm of json) { blk += valueToBLK(typeof itm, itm, "array", options) + "\n"; } } - else - { - for (let key in json) - { + else { + for (let key in json) { let value = json[key]; - let type: string = null; + let type = null; blk += valueToBLK(typeof value, value, key, options); blk += "\n"; @@ -232,56 +187,47 @@ export function jsonToBLK(json: any, options = { markBlockWithTypes: false }): s return blk; } -export class Point2 -{ - x: number = 0.0; - y: number = 0.0; +export class Point2 { + x = 0.0; + y = 0.0; - toBlk(): any - { + toBlk() { return { p2: [this.x, this.y] }; } } -export class Point3 -{ - constructor(public x: number = 0, public y: number = 0, public z: number = 0) - { - } +export class Point3 { + x = 0.0; + y = 0.0; + z = 0.0; - toBlk(): any - { + toBlk() { return { p3: [this.x, this.y, this.z] }; } } -export class Point4 -{ - x: number = 0.0; - y: number = 0.0; - z: number = 0.0; - w: number = 0.0; +export class Point4 { + x = 0.0; + y = 0.0; + z = 0.0; + w = 0.0; - toBlk(): any - { + toBlk() { return { p4: [this.x, this.y, this.z, this.w] }; } } -export class TMatrix -{ - col0: Point3 = new Point3; - col1: Point3 = new Point3; - col2: Point3 = new Point3; - col3: Point3 = new Point3; +export class TMatrix { + col0 = new Point3; + col1 = new Point3; + col2 = new Point3; + col3 = new Point3; - toBlk(): any - { + toBlk() { return { tm: [this.col0.toBlk().p3, this.col1.toBlk().p3, this.col2.toBlk().p3, this.col3.toBlk().p3] }; } - static fromArray(data: any): TMatrix - { + static fromArray(data) { let mat = new TMatrix; mat.col0 = new Point3(data[0], data[1], data[2]); mat.col1 = new Point3(data[3], data[4], data[5]); @@ -292,26 +238,25 @@ export class TMatrix } } -export class BLKArray -{ - constructor(public data: any) - { +export class BLKArray { + constructor(data) { + this.data = data; } - toBlk(): any - { + toBlk() { let tmp = []; - for (let d of this.data) - { - if (typeof d.toBlk === 'function') - { + for (let d of this.data) { + if (typeof d.toBlk === 'function') { tmp.push(d.toBlk()); } - else - { + else { tmp.push(d); } } return { array: tmp }; } +} + +export function deserializeBSON(buffer) { + return bson().BSON.deserialize(buffer); } \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/core/core.service.js b/prog/gameLibs/webui/plugins/webView/vue/core/core.service.js new file mode 100644 index 000000000..9e76d9ad3 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/core/core.service.js @@ -0,0 +1,278 @@ +import { deserializeBSON } from './common.js'; + +const { ref, reactive, computed, triggerRef } = Vue; +const { Observable } = rxjs; +const { map, debounceTime, distinctUntilChanged } = rxjs.operators; + +const UPDATE_INTERVAL_MS = 500; + +export class CoreService { + _listeners = []; + + _observable = null; + + _messagesObservable = null; + + _updateCount = 0; + + _updateTimeout = null; + + commandDomains = reactive([]); + commands = reactive({}); + + _consoleCommands = []; + _consoleCommandNames = []; + + _lastCommandName = ''; + _lastCommand = null; + + constructor(streamService, cookieService) { + console.log('CoreService::CoreService'); + + this.streamService = streamService; + this.cookieService = cookieService; + + this._lastCommandName = this.cookieService.get("_lastCommandName"); + if (!this._lastCommandName) + this._lastCommandName = ''; + + this.streamService.onOpen(() => { this.processOpen(); }); + + this._observable = Observable.create(observer => { + this.streamService.onMessage((message) => { this.processMessage(observer, message); }); + }); + + this._observable.subscribe(value => { this.processValue(value); }); + + if (this.streamService.isConnected()) + this.onOpen(); + } + + addListener(listener) { + this._listeners.push(listener); + + if (this.streamService.isConnected()) + listener.onOpen(); + } + + onOpen() { + console.log('CoreService::onOpen'); + + this.sendCommand('onOpen'); + this.sendCommand('getConsoleCommandsList'); + + if (!this.commandDomains.length) + this.sendCommand('getCommandsList'); + + for (let listener of this._listeners) { + listener.onOpen(); + } + } + + onMessage(data) { + if (data._update) { + ++this._updateCount; + } + + if (data.commandsJson && !this.commandDomains.length) { + const _commands = JSON.parse(data.commandsJson); + + if (_commands.common) { + _commands.common = _commands.common.filter(v => v.cmd !== '__sample'); + if (!_commands.common.length) + delete _commands.common; + } + + for (let c in _commands) { + this.commands[c] = _commands[c]; + } + + this.commandDomains.push(...Object.keys(_commands)); + + if (this._lastCommandName !== '') { + for (let domain of this.commandDomains) { + for (let command of _commands[domain]) { + let cmd = command.console ? command.console : command.cmd; + if (this._lastCommandName === cmd) { + this._lastCommandName; + this._lastCommand = command; + break; + } + } + } + } + } + + if (data.consoleCommands) { + this._consoleCommands = data.consoleCommands; + this._consoleCommandNames = this._consoleCommands.map(v => v.name + ' x'.repeat(v.minArgs - 1) + ' [x]'.repeat(v.maxArgs - v.minArgs)); + } + + for (let listener of this._listeners) { + listener.onMessage(data); + } + } + + continueUpdate(force = false) { + if (force) { + if (this._updateTimeout != null) + clearTimeout(this._updateTimeout); + this._updateTimeout = null; + } + + if (this._updateTimeout === null) + this._updateTimeout = setTimeout(() => { this.sendCommand('update'); }, UPDATE_INTERVAL_MS); + } + + processOpen() { + this.onOpen(); + this.continueUpdate(true); + } + + processMessage(observer, message) { + if (typeof message === 'object' && message.constructor && message.constructor.name === 'Blob') { + let reader = new FileReader(); + reader.addEventListener("loadend", () => { + observer.next(deserializeBSON(new Uint8Array(reader.result))); + this.continueUpdate(); + }); + reader.readAsArrayBuffer(message); + } + else { + let json = {}; + try { + json = JSON.parse(message); + } + catch (err) { + json = { log: message }; + } + observer.next(json); + } + } + + processValue(data) { + this.onMessage(data); + + if (data._update) { + if (this._updateTimeout !== null) + clearTimeout(this._updateTimeout); + this._updateTimeout = null; + } + } + + sendCommand(cmd, params = null) { + let tmp = params || {}; + tmp.cmd = cmd; + this.streamService.send(tmp); + } + + pollData(dataGetter, cmd, params = null) { + return new Promise((resolve, reject) => { + let isDataValid = d => { return (typeof (d.length) !== undefined && d.length > 0) || (typeof (d.length) === undefined && d); } + + let data = dataGetter(); + if (isDataValid(data)) { + resolve(data); + return; + } + + this.sendCommand(cmd, params); + let pollId = global.setInterval(() => { + let data = dataGetter(); + if (isDataValid(data)) { + global.clearInterval(pollId); + resolve(data); + } + }, 100); + }); + } + + runConsoleRaw(data) { + let cmd; + let params = {}; + let args = data.split(' '); + cmd = args[0]; + for (let i = 1; i < args.length; ++i) { + params['arg' + (i - 1)] = args[i]; + } + this.runConsole(cmd, params); + } + + runConsole(cmd, params = null) { + let tmp = params || {}; + tmp.command = cmd; + this.sendCommand('console', tmp); + } + + runConsoleScript(commands) { + for (let cmd of commands) { + this.runConsole(cmd[0], cmd[1] ? cmd[1] : null); + } + } + + buildAndSendCommand(command) { + this._lastCommandName = command.console ? command.console : command.cmd; + this._lastCommand = command; + this.cookieService.put("_lastCommandName", this._lastCommandName); + + if (command.console) { + let consoleStr = command.console; + + for (let p of command.params) { + if (p.value === undefined) + continue; + + if (Array.isArray(p.value)) + consoleStr += ' ' + p.value.concat(' '); + else if (typeof (p.value) === 'boolean') + consoleStr += ' ' + (p.value ? 'on' : 'off'); + else + consoleStr += ' ' + p.value; + } + + console.log(command, consoleStr); + + this.runConsoleRaw(consoleStr); + + return; + } + + let params = {}; + + for (let p of command.params) { + if (p.value === undefined) + continue; + + let type = p.type; + if (['dmPart', 'enum', 'b'].indexOf(p.type) >= 0) { + params[p.name] = p.value; + } + else { + params[p.name] = {}; + params[p.name][type] = p.value; + } + } + + console.log(command, params); + + this.sendCommand(command.cmd, params); + } + + searchConsoleCommand(query) { + return query.length < 2 ? [] : this._consoleCommandNames.filter(v => v.toLowerCase().indexOf(query.toLowerCase()) > -1).slice(0, 10); + } + + get isConnected() { return this.streamService.isConnected(); }; + + get updateCount() { return +this._updateCount; } + + set messagesObservable(value) { this._messagesObservable = value; } + get messagesObservable() { return this._messagesObservable; } + + get observable() { return this._observable; } + + get consoleCommands() { return this._consoleCommands; } + get consoleCommandNames() { return this._consoleCommandNames; } + + get lastCommand() { return this._lastCommand; } +} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/core/dm.service.js b/prog/gameLibs/webui/plugins/webView/vue/core/dm.service.js new file mode 100644 index 000000000..e0e9c1a55 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/core/dm.service.js @@ -0,0 +1,270 @@ +import { BLKArray } from './common.js'; + +const { ref, reactive } = Vue; + +export class DMService { + _allParts = []; + _nodes = []; + parts = reactive([]); + _parts = []; + metaParts = reactive([]); + _metaParts = []; + effects = reactive([]); + _effects = []; + _collNodes = []; + _dmgNodes = []; + _wreckedParts = []; + + _debugDrawModes = {}; + + _weaponList = []; + + _curWeaponName = ''; + _ammoSpeed = 200; + _fuseDelay = 2; + + _drawDamagedParts = false; + _drawKilledParts = false; + + eids = reactive([]); + _eids = []; + + _shouldShowAllEvents = false; + + events = reactive([]); + _events = []; + eventRendererElementsNames = []; + eventRendererElementsMask = []; + + constructor(coreService) { + console.log('DMService::DMService'); + + this.coreService = coreService; + + this.coreService.addListener(this); + + let v = this.coreService.cookieService.get('_currentWeapon'); + if (v) + this._curWeaponName = v; + v = this.coreService.cookieService.get('_currentSpeed'); + if (v) + this._ammoSpeed = +v; + v = this.coreService.cookieService.get('_currentFuse'); + if (v) + this._fuseDelay = +v; + } + + onOpen() { + console.log('DMService::onOpen'); + + this._allParts = []; + this._nodes = []; + this._parts = []; + this._collNodes = []; + this._dmgNodes = []; + this._wreckedParts = []; + this._debugDrawModes = {}; + + this.parts.splice(0, this.parts.length); + this.metaParts.splice(0, this.metaParts.length); + this.effects.splice(0, this.effects.length); + this.events.splice(0, this.events.length); + + this.coreService.sendCommand('getWeapons'); + this.coreService.sendCommand('getEntities', { withComponent: 'dm_debug' }); + } + + onMessage(data) { + if (data.allParts) + this._allParts = data.allParts; + if (data.nodes) + this._nodes = data.nodes; + if (data.parts) { + this._parts = data.parts.filter(v => v.enabled); + this._drawKilledParts = false; + this._drawDamagedParts = false; + + this.parts.splice(0, this.parts.length, ...this._parts); + } + if (data.metaParts) { + this._metaParts = data.metaParts; + this.metaParts.splice(0, this.metaParts.length, ...this._metaParts); + } + if (data.dmEffects) { + this._effects = data.dmEffects; + this.effects.splice(0, this.effects.length, ...this._effects); + } + if (data.collNodes) + this._collNodes = data.collNodes; + if (data.dmgNodes) + this._dmgNodes = data.dmgNodes; + if (data.wreckedParts) + this._wreckedParts = data.wreckedParts; + if (data.debugDrawModes) + this._debugDrawModes = data.debugDrawModes; + if (data.weaponList) { + this._weaponList = data.weaponList; + if (!this._curWeaponName && this._weaponList[0]) { + this._curWeaponName = this._weaponList[0]; + this.coreService.cookieService.put('_currentWeapon', this._curWeaponName); + this.coreService.cookieService.put('_currentSpeed', this._ammoSpeed.toString()); + this.coreService.cookieService.put('_currentFuse', this._fuseDelay.toString()); + } + } + + if (data.entities_dm_debug) { + this._eids = data.entities_dm_debug; + console.log('DMService::onMessage', this._eids); + this.eids.splice(0, this.eids.length, ...this._eids); + } + + if (data.exec) { + if (data.exec.shot) { + this.sendShot(); + } + } + + if (data.applyDamageEffect) { + let part = this._parts.find(v => v.id == data.applyDamageEffect.partId); + if (part) { + if (!part.effects) + part.effects = {}; + + for (let eff in data.applyDamageEffect.effects) { + part.effects[eff] = true; + part.effectNames = Object.keys(part.effects); + } + } + } + if (data.onPartHit) { + let part = this._parts.find(v => v.id == data.onPartHit.partId); + if (part) { + part.hp = data.onPartHit.hp; + part.hpRel = data.onPartHit.hpRel; + + if (this._drawKilledParts && part.hpRel == 0.0) { + part.draw = true; + this.coreService.sendCommand('drawPart', { part: part.name, draw: part.draw }); + } + else if (this._drawDamagedParts && part.hpRel != 1.0) { + part.draw = true; + this.coreService.sendCommand('drawPart', { part: part.name, draw: part.draw }); + } + } + } + if (typeof data.shouldShowAllEvents !== 'undefined') { + this._shouldShowAllEvents = data.shouldShowAllEvents; + } + if (data.dmEvents && data.dmEvents.events) { + console.log('DMService::onMessage', data.dmEvents.events); + this._events = data.dmEvents.events; + this.events.splice(0, this.events.length, ...this._events); + } + if (data.eventRendererElementsNames) { + this.eventRendererElementsNames = data.eventRendererElementsNames; + } + if (data.eventRendererElementsMask) { + this.eventRendererElementsMask = data.eventRendererElementsMask; + } + } + + filterPartsByName(n) { + return n ? this._parts.filter(v => v.name.indexOf(n) >= 0) : this._parts; + } + + sendShot() { + this.coreService.cookieService.put('_currentSpeed', this._ammoSpeed.toString()); + this.coreService.cookieService.put('_currentFuse', this._fuseDelay.toString()); + this.coreService.sendCommand('shot', { weapon: this._curWeaponName, speed: +this._ammoSpeed, fuseDelay: +this._fuseDelay }); + } + + getPartNamesForMetaPart(metaPart) { + if (!this._parts.length || !this._metaParts.length) + return []; + + if (!metaPart._parts) + metaPart._parts = this._parts.filter(v => v.metapartId == metaPart.id); + + return metaPart._parts.map(v => v.name); + } + + getPartNamesForEffect(eff) { + if (!this._parts.length || !this._effects.length) + return []; + + if (!eff._parts) + eff._parts = this._parts.filter(v => v.effectPresetId == eff.id); + + return eff._parts.map(v => v.name); + } + + getDamageTypesForEffect(eff) { + if (!this._parts.length || !this._effects.length) + return []; + + if (!eff._types) + eff._types = Object.keys(eff); + + return eff._types; + } + + isExpanded(v) { + if (!v._expanded) + v._expanded = false; + return v._expanded; + } + + toggleExpanded(v) { + v._expanded = !v._expanded; + } + + onEidSelect($event) { + if ($event) { + this.coreService.sendCommand('setCurrentEid', { eid: { i: $event.eid } }); + } + } + + onChangeEventRendererElementsMask() { + this.coreService.sendCommand('setEventRendererElementsMask', new BLKArray(this.eventRendererElementsMask)); + } + + get allParts() { return this._allParts; } + get nodes() { return this._nodes; } + get parts() { return this._parts; } + // get metaParts() { return this._metaParts; } + // get effects() { return this._effects; } + get collNodes() { return this._collNodes; } + get dmgNodes() { return this._dmgNodes; } + get wreckedParts() { return this._wreckedParts; } + get debugDrawModes() { return this._debugDrawModes; } + + get weaponList() { return this._weaponList; } + + get curWeaponName() { return this._curWeaponName; } + set curWeaponName(value) { this._curWeaponName = value; } + get ammoSpeed() { return +this._ammoSpeed; } + set ammoSpeed(value) { this._ammoSpeed = +value; } + get fuseDelay() { return +this._fuseDelay; } + set fuseDelay(value) { this._fuseDelay = +value; } + + get drawDamagedParts() { return this._drawDamagedParts; } + set drawDamagedParts(value) { this._drawDamagedParts = value; } + get drawKilledParts() { return this._drawKilledParts; } + set drawKilledParts(value) { this._drawKilledParts = value; } + + get allPartsPromse() { + return new Promise((resolve, reject) => { + resolve(this._allParts); + }); + } + + get weaponListPromise() { + return this.coreService.pollData(() => this._weaponList, 'getWeapons'); + } + + get shouldShowAllEvents() { return this._shouldShowAllEvents; } + set shouldShowAllEvents(value) { + this._shouldShowAllEvents = value; + this.coreService.sendCommand('shouldShowAllEvents', { value: value }); + } +} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.service.ts b/prog/gameLibs/webui/plugins/webView/vue/core/ecs.service.js similarity index 66% rename from prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.service.ts rename to prog/gameLibs/webui/plugins/webView/vue/core/ecs.service.js index af9f39b65..3a4ff5d5e 100644 --- a/prog/gameLibs/webui/plugins/webView/src/app/modules/ecs/ecs.service.ts +++ b/prog/gameLibs/webui/plugins/webView/vue/core/ecs.service.js @@ -1,94 +1,79 @@ -import { Injectable } from '@angular/core'; +import { jsonToBLK, compToString } from './common.js'; -import { Observable } from 'rxjs/Observable'; -import { Subscription } from 'rxjs/Subscription'; +const { ref, reactive } = Vue; -import { StreamService } from '../../core/stream.service'; -import { CoreService } from '../../core/core.service'; - -import * as common from '../../core/common'; -import { THIS_EXPR } from '@angular/compiler/src/output/output_ast'; -import { JSONP_ERR_NO_CALLBACK } from '@angular/common/http/src/jsonp'; -import { retry } from 'rxjs/operator/retry'; - -const UPDATE_INTERVAL_MS: number = 500; - -interface IECSPromise -{ - resolve: Array; - reject: Array; -} - -function fixBool(v) -{ - if (typeof v !== 'object') - { +function fixBool(v) { + if (typeof v !== 'object') { if (v === 'true') return true; if (v === 'false') return false; return v; } - for (let k in v) - { + for (let k in v) { v[k] = fixBool(v[k]); } return v; } -@Injectable() -export class ECSService implements common.IMessageListener -{ - private _templates: any = []; - private _templatesByName: any = {}; - private _systems: any = []; - private _queries: any = []; - private _components: any = []; - private _entities: any = []; - private _entitiesByEid: any = {}; - private _dynamicQueryEntities: any = []; - private _events: any = []; - private _filter: string = ''; - private _filterEid: string = ''; - private _filteredEntities: any = null; - private _filterComponent: string = ''; - private _filteredComponents: any = null; - private _filterTemplate: string = ''; - private _filteredTemplates: any = null; - private _filterSystem: string = ''; - private _filterQuery: string = ''; - private _filterEvent: string = ''; - private _filteredSystems: any = null; - private _filteredQueries: any = null; - private _filteredEvents: any = null; - private _resolveEid: common.Dictionary = {}; - private _dynamicQuery: any = { comps_ro:[], comps_rq:[], comps_no:[] }; - private _dynamicQueryFilter: string = ''; - private _dynamicQueryColumns: any = []; - - private _fullDataCounter = 0; - - constructor(protected coreService: CoreService) - { +export class ECSService { + templates = reactive([]); + _templates = []; + _templatesByName = {}; + systems = reactive([]); + _systems = []; + queries = reactive([]); + _queries = []; + components = reactive([]); + _components = []; + entities = reactive([]); + _entities = []; + _entitiesByEid = {}; + dynamicQueryEntities = reactive([]); + _dynamicQueryEntities = []; + events = reactive([]); + _events = []; + _filter = ''; + _filterEid = ''; + _filteredEntities = null; + _filterComponent = ''; + _filteredComponents = null; + _filterTemplate = ''; + _filteredTemplates = null; + _filterSystem = ''; + _filterQuery = ''; + _filterEvent = ''; + _filteredSystems = null; + _filteredQueries = null; + _filteredEvents = null; + _resolveEid = {}; + _dynamicQuery = { comps_ro: [], comps_rq: [], comps_no: [] }; + dynamicQueryFilter = ref(''); + dynamicQueryColumns = reactive([]); + _dynamicQueryColumns = []; + + _fullDataCounter = 0; + + constructor(coreService) { console.log('ECSService::ECSService'); + + this.coreService = coreService; + this.coreService.addListener(this); - const query = this.coreService.cookieService.getObject('_dynamicQuery'); - if (query) - { + const query = this.coreService.cookieService.get('_dynamicQuery'); + if (query) { this._dynamicQuery = query; } const queryFilter = this.coreService.cookieService.get('_dynamicQueryFilter'); - if (queryFilter) - { - this._dynamicQueryFilter = queryFilter; + if (queryFilter) { + this.dynamicQueryFilter.value = queryFilter; } } - fetchData() - { + fetchData() { this._fullDataCounter += 5; this.coreService.sendCommand('getTemplates'); this.coreService.sendCommand('getSystems'); @@ -97,57 +82,47 @@ export class ECSService implements common.IMessageListener this.coreService.sendCommand('getEvents'); } - onOpen(): void - { + onOpen() { console.log('ECSService::onOpen'); this.fetchData(); - { - ++this._fullDataCounter; - this.coreService.sendCommand('getEntities'); - } + ++this._fullDataCounter; + this.coreService.sendCommand('getEntities'); } - findTemplate(name: string): any - { - for (let n of name.split('+')) - { + findTemplate(name) { + for (let n of name.split('+')) { const res = this._templatesByName[n]; - if (!!res) - { + if (!!res) { return res; } } } - findTemplateIndex(name: string): any - { - for (let n of name.split('+')) - { + findTemplateIndex(name) { + for (let n of name.split('+')) { const res = this._templates.findIndex(t => t.name === n); - if (res >= 0) - { + if (res >= 0) { return res; } } } - onMessage(data): void - { - if (data.selectEid) - { + onMessage(data) { + if (data.selectEid) { this.filterEntitiesByEid = data.selectEid; this.fetchEntities(); } - if (data.templates) - { + if (data.templates) { console.time('data.templates'); --this._fullDataCounter; this._templatesByName = {}; this._templates = data.templates; + var curId = 0; + this._templates.forEach(t => t.id = curId++); this._templates.forEach(t => t.components.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)); this._templates.forEach(t => { t._systems = []; t._queries = []; this._templatesByName[t.name] = t; }); this._templates.forEach(t => t.parents.forEach(p => p._template = this.findTemplate(p.name))); @@ -159,8 +134,7 @@ export class ECSService implements common.IMessageListener t.parents.forEach(p => countComponents(p._template, level + 1, acc)); - if (level === 0) - { + if (level === 0) { t._componentsCount = acc.componentsCount; t._trackedCount = acc.trackedCount; t._replicatedCount = acc.replicatedCount; @@ -169,29 +143,24 @@ export class ECSService implements common.IMessageListener this._templates.forEach(t => countComponents(t)); console.timeEnd('data.templates'); } - if (data.systems) - { + if (data.systems) { --this._fullDataCounter; this._systems = data.systems; this._systems.forEach(s => s.events.sort()) } - if (data.queries) - { + if (data.queries) { --this._fullDataCounter; this._queries = data.queries; } - if (data.components) - { + if (data.components) { --this._fullDataCounter; this._components = data.components; } - if (data.events) - { + if (data.events) { --this._fullDataCounter; this._events = data.events; } - if (data.dynamicQueryEntities) - { + if (data.dynamicQueryEntities) { console.time('data.dynamicQueryEntities'); console.log(data.dynamicQueryEntities); this._dynamicQueryEntities = data.dynamicQueryEntities @@ -200,7 +169,7 @@ export class ECSService implements common.IMessageListener this._dynamicQueryColumns = e.components.map(c => c.name) this._dynamicQueryEntities.forEach(function (e) { for (let c of e.components) { - e[`_${c.name}`] = common.compToString(c.value) + e[`_${c.name}`] = compToString(c.value) } }) this._dynamicQueryEntities.forEach(e => e.components.forEach(fixBool)) @@ -208,65 +177,62 @@ export class ECSService implements common.IMessageListener else { this._dynamicQueryColumns = [] } + this.dynamicQueryColumns.splice(0, this.dynamicQueryColumns.length, ...this._dynamicQueryColumns); + this.dynamicQueryEntities.splice(0, this.dynamicQueryEntities.length, ...this._dynamicQueryEntities); console.timeEnd('data.dynamicQueryEntities'); } - if (data.entities) - { + if (data.entities) { console.time('data.entities'); --this._fullDataCounter; this._entitiesByEid = {}; this._entities = data.entities.map(v => { v.id = v.eid; this._entitiesByEid[v.eid] = v; v._systemsFn = () => []; v._queriesFn = () => []; return v; }); - if (this._filterEid !== null && this._filterEid !== '') - { + if (this._filterEid !== null && this._filterEid !== '') { this.filterEntitiesByEid = this._filterEid; } - else - { + else { this.filterEntities = this._filter; } console.timeEnd('data.entities'); } - if (data.components) - { + if (data.components) { console.time('data.components'); - let entity = this._entities.find(v => v.eid == data.eid); - if (entity) - { + let entity = this.entities.find(v => v.eid == data.eid); + if (entity) { entity.components = data.components.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); const toh = v => ('0' + v.toString(16)).substr(-2); entity.components.filter(v => v.type === 'E3DCOLOR').forEach(v => v._color = '#' + toh(v.value.r) + toh(v.value.g) + toh(v.value.b) + toh(typeof v.value.a !== undefined ? v.value.a : 255)); entity.components.forEach(fixBool); } let promise = this._resolveEid[data.eid]; - if (promise) - { + if (promise) { promise.resolve.forEach(cb => cb(entity)); delete this._resolveEid[data.eid]; } console.timeEnd('data.components'); } - if (this._fullDataCounter === 0 && this._components.length > 0 && this._systems.length > 0 && this._templates.length > 0) - { + if (this._fullDataCounter === 0 && this._components.length > 0 && this._systems.length > 0 && this._templates.length > 0) { this._fullDataCounter = -1; console.time('dataProcess:systems'); this._queries = this._queries.filter(q => this._systems.findIndex(s => s.name === q.name) < 0) - this._systems.forEach(s => { s.componentsRO.forEach(c => c._mode = 'RO'); s.componentsRW.forEach(c => c._mode = 'RW'); s.componentsRQ.forEach(c => c._mode = 'RQ'); s.componentsNO.forEach(c => c._mode = 'NO')}) - this._queries.forEach(s => { s.componentsRO.forEach(c => c._mode = 'RO'); s.componentsRW.forEach(c => c._mode = 'RW'); s.componentsRQ.forEach(c => c._mode = 'RQ'); s.componentsNO.forEach(c => c._mode = 'NO')}) + this._systems.forEach(s => { s.componentsRO.forEach(c => c._mode = 'RO'); s.componentsRW.forEach(c => c._mode = 'RW'); s.componentsRQ.forEach(c => c._mode = 'RQ'); s.componentsNO.forEach(c => c._mode = 'NO') }) + this._queries.forEach(s => { s.componentsRO.forEach(c => c._mode = 'RO'); s.componentsRW.forEach(c => c._mode = 'RW'); s.componentsRQ.forEach(c => c._mode = 'RQ'); s.componentsNO.forEach(c => c._mode = 'NO') }) this._systems.forEach(s => s._allComponents = [].concat(s.componentsRO, s.componentsRW, s.componentsRQ, s.componentsNO)) this._queries.forEach(s => s._allComponents = [].concat(s.componentsRO, s.componentsRW, s.componentsRQ, s.componentsNO)) console.timeEnd('dataProcess:systems'); console.time('dataProcess:components'); + var compId = 0; for (let c of this._components) { c._systems = []; c._queries = []; + c.id = compId++; for (let sys of this._systems) { let compInSys = sys._allComponents.find(v => c.name === v.name) if (compInSys) { - c._systems.push({system: sys, mode: compInSys._mode}) + c._systems.push({ system: sys, mode: compInSys._mode }) } } c._systems.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0) @@ -274,7 +240,7 @@ export class ECSService implements common.IMessageListener for (let q of this._queries) { let compInQuery = q._allComponents.find(v => c.name === v.name) if (compInQuery) { - c._queries.push({query: q, mode: compInQuery._mode}) + c._queries.push({ query: q, mode: compInQuery._mode }) } } c._queries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0) @@ -288,16 +254,14 @@ export class ECSService implements common.IMessageListener self._templates = []; const searchTempate = (id, template) => { - for (let parent of template.parents) - { + for (let parent of template.parents) { let parentId = this.findTemplateIndex(parent.name); let parentData = this._templates[parentId]; const idx = parentData.components.findIndex(v => v.name === self.name); - if (idx >= 0) - { + if (idx >= 0) { self._templates.push({ templateId: id, sourceTemplateId: parentId }); - break; + // break; } searchTempate(id, parentData); @@ -308,20 +272,20 @@ export class ECSService implements common.IMessageListener const idx = this._templates[templateId].components.findIndex(v => v.name == self.name); if (idx >= 0) { self._templates.push({ templateId: templateId, sourceTemplateId: templateId }); - break; + // break; } searchTempate(templateId, this._templates[templateId]); } + return self._templates; }; } console.timeEnd('dataProcess:components'); console.time('dataProcess:entities'); - if (this._entities.length > 0) - { - const addSystemToTemplate = (sys: any, template_name: string) => { + if (this._entities.length > 0) { + const addSystemToTemplate = (sys, template_name) => { for (let n of template_name.split('+')) { let res = this._templatesByName[n]; if (!!res) { @@ -356,7 +320,7 @@ export class ECSService implements common.IMessageListener s._templateNames = Object.keys(s._templates); }); - const addQueryToTemplate = (sys: any, template_name: string) => { + const addQueryToTemplate = (sys, template_name) => { for (let n of template_name.split('+')) { let res = this._templatesByName[n]; if (!!res) { @@ -392,8 +356,8 @@ export class ECSService implements common.IMessageListener }); this._templates.forEach(t => { - t._systems = t._systems.reduce((res, s) => res.findIndex(r => r.name === s.name) >=0 ? res : [].concat(s, res), []); - t._queries = t._queries.reduce((res, s) => res.findIndex(r => r.name === s.name) >=0 ? res : [].concat(s, res), []); + t._systems = t._systems.reduce((res, s) => res.findIndex(r => r.name === s.name) >= 0 ? res : [].concat(s, res), []); + t._queries = t._queries.reduce((res, s) => res.findIndex(r => r.name === s.name) >= 0 ? res : [].concat(s, res), []); }); } console.timeEnd('dataProcess:entities'); @@ -410,6 +374,13 @@ export class ECSService implements common.IMessageListener } console.timeEnd('dataProcess:events'); + this.entities.splice(0, this.entities.length, ...this._entities); + this.components.splice(0, this.components.length, ...this._components); + this.systems.splice(0, this.systems.length, ...this._systems); + this.queries.splice(0, this.queries.length, ...this._queries); + this.events.splice(0, this.events.length, ...this._events); + this.templates.splice(0, this.templates.length, ...this._templates); + console.log('Templates', this._templates); console.log('Components', this._components); console.log('Systems', this._systems); @@ -418,28 +389,23 @@ export class ECSService implements common.IMessageListener } } - fetchEntities(withComponent: string = null): void - { - if (withComponent !== null) - { + fetchEntities(withComponent = null) { + console.log('fetchEntities', withComponent); + if (withComponent !== null) { ++this._fullDataCounter; this.coreService.sendCommand('getEntities', { withComponent: withComponent }); this.fetchData(); } - else - { + else { ++this._fullDataCounter; this.coreService.sendCommand('getEntities'); this.fetchData(); } } - fetchEntityAttributes(eid): Promise - { - return new Promise((resolve, reject) => - { - if (!this._resolveEid[eid]) - { + fetchEntityAttributes(eid) { + return new Promise((resolve, reject) => { + if (!this._resolveEid[eid]) { this._resolveEid[eid] = { resolve: [], @@ -457,26 +423,22 @@ export class ECSService implements common.IMessageListener }); } - setEntityAttribute(eid, attr, value): void - { - const toBlk = v => - { + setEntityAttribute(eid, attr, value) { + const toBlk = v => { const isSet = v => typeof v !== 'undefined'; - if (typeof v !== 'object') - { + if (typeof v !== 'object') { if (v === 'true') return true; if (v === 'false') return false; return v; } - if (isSet(v.r) && isSet(v.g) && isSet(v.b) && isSet(v.a)) return { c : [v.r, v.g, v.b, v.a] }; - if (isSet(v.x) && isSet(v.y) && isSet(v.z) && isSet(v.w)) return { p4 : [v.x, v.y, v.z, v.w] }; - if (isSet(v.x) && isSet(v.y) && isSet(v.z)) return { p3 : [v.x, v.y, v.z] }; - if (isSet(v.x) && isSet(v.y)) return { p2 : [v.x, v.y] }; + if (isSet(v.r) && isSet(v.g) && isSet(v.b) && isSet(v.a)) return { c: [v.r, v.g, v.b, v.a] }; + if (isSet(v.x) && isSet(v.y) && isSet(v.z) && isSet(v.w)) return { p4: [v.x, v.y, v.z, v.w] }; + if (isSet(v.x) && isSet(v.y) && isSet(v.z)) return { p3: [v.x, v.y, v.z] }; + if (isSet(v.x) && isSet(v.y)) return { p2: [v.x, v.y] }; - for (let k in v) - { + for (let k in v) { v[k] = toBlk(v[k]); } @@ -489,34 +451,30 @@ export class ECSService implements common.IMessageListener Point3: v => { return { p3: [v.x, v.y, v.z] } }, Point4: v => { return { p4: [v.x, v.y, v.z, v.w] } }, E3DCOLOR: v => { return { c: [v.r, v.g, v.b, v.a] } }, - TMatrix: v => { return { tm: [[v[0], v[1], v[2]], [v[3], v[4], v[5]], [v[6], v[7], v[8]], [v[9], v[10], v[11]]] } }, - 'ecs::Object': v => - { + TMatrix: v => { return { m: [[v[0], v[1], v[2]], [v[3], v[4], v[5]], [v[6], v[7], v[8]], [v[9], v[10], v[11]]] } }, + 'ecs::Object': v => { let arr = attr.name.split('.'); let obj = {}; - if (arr.length === 1) - { + if (arr.length === 1) { obj[`${attr.name}:object`] = v; } - else - { - obj[arr[0]] = { [`${ arr[1]}:object`]: v }; + else { + obj[arr[0]] = { [`${arr[1]}:object`]: v }; } return obj; }, - 'ecs::Array': v => - { + 'ecs::Array': v => { const tmpVal = v.map(vv => toBlk(vv)); const typeKey = typeof tmpVal[0] === 'object' ? Object.keys(tmpVal[0])[0] : null; const k2 = typeof tmpVal[0] === 'object' && ['c', 'p2', 'p3', 'p4', 'i', 'r', 'eid'].indexOf(typeKey) < 0 ? `${attr.name}:object` : attr.name; - return { [`${attr.name}:array`]: {[k2]: tmpVal} }; + return { [`${attr.name}:array`]: { [k2]: tmpVal } }; }, - 'ecs::EntityId': v => { return {i: v} } + 'ecs::EntityId': v => { return { i: v } } }; const valueToSend = convert[attr.type] ? convert[attr.type](value) : value; - const message = common.jsonToBLK({ cmd: "setEntityAttribute", eid: { i: eid }, comp: attr.name, type: attr.type, value: valueToSend }, { markBlockWithTypes: true }); + const message = jsonToBLK({ cmd: "setEntityAttribute", eid: { i: eid }, comp: attr.name, type: attr.type, value: valueToSend }, { markBlockWithTypes: true }); console.log('setEntityAttribute', attr, value, valueToSend); console.log(message); @@ -525,137 +483,141 @@ export class ECSService implements common.IMessageListener this.coreService.streamService.sendString(message); } - performDynamicQuery() - { - this.coreService.cookieService.putObject('_dynamicQuery', this._dynamicQuery); - this.coreService.cookieService.put('_dynamicQueryFilter', this._dynamicQueryFilter); + saveDynamicQuery() { + this.coreService.cookieService.put('_dynamicQuery', this._dynamicQuery); + this.coreService.cookieService.put('_dynamicQueryFilter', this.dynamicQueryFilter.value); + + console.log(this._dynamicQuery); + } + + performDynamicQuery() { + this.saveDynamicQuery(); let query = JSON.parse(JSON.stringify(this._dynamicQuery)) - query.filter = this._dynamicQueryFilter - console.log(common.jsonToBLK(query)) + query.filter = this.dynamicQueryFilter.value; + console.log(jsonToBLK(query)) this.coreService.sendCommand('performDynamicQuery', query) } - set filterEntities(template: string) - { - if (this._filterEid !== null && this._filterEid === '') - { + set filterEntities(template) { + if (this._filterEid !== null && this._filterEid === '') { this.filterEntitiesByEid = null; } this._filter = template; - if (template === null || template === '') - { + if (template === null || template === '') { this._filteredEntities = null; + this.entities.splice(0, this.entities.length, ...this._entities); return; } let re = new RegExp(template, 'i'); this._filteredEntities = this._entities.filter(e => re.test(e.template)); + + this.entities.splice(0, this.entities.length, ...this._filteredEntities); } - set filterEntitiesByEid(eid: string) - { - if (this._filter !== null && this._filter !== '') - { + set filterEntitiesByEid(eid) { + if (this._filter !== null && this._filter !== '') { this.filterEntities = null; } this._filterEid = eid; - if (eid === null || eid === '') - { + if (eid === null || eid === '') { this._filteredEntities = null; + this.entities.splice(0, this.entities.length, ...this._entities); return; } this._filteredEntities = this._entities.filter(v => v.eid == eid); + this.entities.splice(0, this.entities.length, ...this._filteredEntities); } - set filterComponents(name: string) - { + set filterComponents(name) { this._filterComponent = name; - if (name === null || name === '') - { + if (name === null || name === '') { this._filteredComponents = null; + this.components.splice(0, this.components.length, ...this._components); return; } let re = new RegExp(name, 'i'); this._filteredComponents = this._components.filter(c => re.test(c.name)); + this.components.splice(0, this.components.length, ...this._filteredComponents); } - set filterTemplates(name: string) - { + set filterTemplates(name) { this._filterTemplate = name; - if (name === null || name === '') - { + if (name === null || name === '') { this._filteredTemplates = null; + this.templates.splice(0, this.templates.length, ...this._templates); return; } let re = new RegExp(name, 'i'); this._filteredTemplates = this._templates.filter(t => re.test(t.name)); + this.templates.splice(0, this.templates.length, ...this._filteredTemplates); } - set filterSystems(name: string) - { + set filterSystems(name) { this._filterSystem = name; - if (name === null || name === '') - { + if (name === null || name === '') { this._filteredSystems = null; + this.systems.splice(0, this.systems.length, ...this._systems); return; } let re = new RegExp(name, 'i'); this._filteredSystems = this._systems.filter(s => re.test(s.name)); + this.systems.splice(0, this.systems.length, ...this._filteredSystems); } - set filterQueries(name: string) - { + set filterQueries(name) { this._filterQuery = name; - if (name === null || name === '') - { + if (name === null || name === '') { this._filteredQueries = null; + this.queries.splice(0, this.queries.length, ...this._queries); return; } let re = new RegExp(name, 'i'); this._filteredQueries = this._queries.filter(q => re.test(q.name)); + this.queries.splice(0, this.queries.length, ...this._filteredQueries); } - set filterEvents(name: string) - { + set filterEvents(name) { this._filterEvent = name; - if (name === null || name === '') - { + if (name === null || name === '') { this._filteredEvents = null; + this.events.splice(0, this.events.length, ...this._events); return; } let re = new RegExp(name, 'i'); this._filteredEvents = this._events.filter(e => re.test(e.name)); + this.events.splice(0, this.events.length, ...this._filteredEvents); } - get templates() { return this._filteredTemplates === null ? this._templates : this._filteredTemplates; } + // get templates() { return this._filteredTemplates === null ? this._templates : this._filteredTemplates; } get allTemplates() { return this._templates; } - get systems() { return this._filteredSystems === null ? this._systems : this._filteredSystems; } + // get systems() { return this._filteredSystems === null ? this._systems : this._filteredSystems; } get allSystems() { return this._systems; } - get queries() { return this._filteredQueries === null ? this._queries : this._filteredQueries; } + // get queries() { return this._filteredQueries === null ? this._queries : this._filteredQueries; } get allQueries() { return this._queries; } - get events() { return this._filteredEvents === null ? this._events : this._filteredEvents; } + // get events() { return this._filteredEvents === null ? this._events : this._filteredEvents; } get allEvents() { return this._events; } - get components() { return this._filteredComponents === null ? this._components : this._filteredComponents; } + // get components() { return this._filteredComponents === null ? this._components : this._filteredComponents; } get allComponents() { return this._components; } - get entities() { return this._filteredEntities === null ? this._entities : this._filteredEntities; } + // get entities() { return this._filteredEntities === null ? this._entities : this._filteredEntities; } get allEntities() { return this._entities; } - get dynamicQueryEntities() { return this._dynamicQueryEntities; } + // get dynamicQueryEntities() { return this._dynamicQueryEntities; } get filterEntities() { return this._filter; } get filterEntitiesByEid() { return this._filterEid; } @@ -668,8 +630,5 @@ export class ECSService implements common.IMessageListener set dynamicQuery(value) { this._dynamicQuery = value; } get dynamicQuery() { return this._dynamicQuery; } - set dynamicQueryFilter(value) { this._dynamicQueryFilter = value; } - get dynamicQueryFilter() { return this._dynamicQueryFilter; } - - get dynamicQueryColumns() { return this._dynamicQueryColumns; } + // get dynamicQueryColumns() { return this._dynamicQueryColumns; } } \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/core/helpers.js b/prog/gameLibs/webui/plugins/webView/vue/core/helpers.js new file mode 100644 index 000000000..56f9d2f4c --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/core/helpers.js @@ -0,0 +1,244 @@ +import { compToString, RGBAToHex } from './common.js'; + +const options = { + moduleCache: { + vue: Vue + }, + async getFile(url) { + const res = await fetch(url); + if (!res.ok) + throw Object.assign(new Error(res.statusText + ' ' + url), { res }); + return { + getContentData: asBinary => asBinary ? res.arrayBuffer() : res.text(), + } + }, + addStyle(textContent) { + const style = Object.assign(document.createElement('style'), { textContent }); + const ref = document.head.getElementsByTagName('style')[0] || null; + document.head.insertBefore(style, ref); + }, +} + +const { loadModule } = window['vue3-sfc-loader']; + +function now() { + return (Date.now || function () { return new Date().getTime(); })(); +} + +function restArguments(func, startIndex) { + startIndex = startIndex == null ? func.length - 1 : +startIndex; + return function () { + var length = Math.max(arguments.length - startIndex, 0), + rest = Array(length), + index = 0; + for (; index < length; index++) { + rest[index] = arguments[index + startIndex]; + } + switch (startIndex) { + case 0: return func.call(this, rest); + case 1: return func.call(this, arguments[0], rest); + case 2: return func.call(this, arguments[0], arguments[1], rest); + } + var args = Array(startIndex + 1); + for (index = 0; index < startIndex; index++) { + args[index] = arguments[index]; + } + args[startIndex] = rest; + return func.apply(this, args); + }; +} + +function shouldOpenEditor(comp) { + return [ + 'ecs::Object', + 'ecs::Array', + 'ecs::IntList', + 'ecs::UInt8List', + 'ecs::UInt16List', + 'ecs::UInt32List', + 'ecs::UInt64List', + 'ecs::StringList', + 'ecs::EidList', + 'ecs::FloatList', + 'ecs::Point2List', + 'ecs::Point3List', + 'ecs::Point4List', + 'ecs::IPoint2List', + 'ecs::IPoint3List', + 'ecs::IPoint4List', + 'ecs::BoolList', + 'ecs::ColorList', + 'ecs::TMatrixList', + 'ecs::Int64List', + ].indexOf(comp.type) >= 0; +} + +function getAttrValue(attr) { + if (attr.type === 'E3DCOLOR') { + const toh = v => ('0' + v.toString(16)).substr(-2); + return '#' + toh(attr.value.r) + toh(attr.value.g) + toh(attr.value.b); + } + return attr.value; +} + +function startEdit(attr) { + console.log('startEdit', attr); + + attr._edit = true; + attr._new_value = null; +} + +function cancelEdit(attr) { + attr._edit = false; + attr._new_value = null; +} + +function saveEdit(row, attr) { + if (row.eid === undefined) { + return; + } + + console.log('saveEdit', attr, attr._new_value); + + attr._edit = false; + if (attr._new_value !== null && attr._new_value !== undefined) { + const nv = attr.type === 'TMatrix' ? Array.from(attr._new_value) : attr._new_value; + this.ecsService.setEntityAttribute(row.eid, attr, nv); + } +} + +function updateValue(ev, row, val, attr, key = null) { + console.log('updateValue', ev, row, val, attr, key); + + const setByKey = v => { + let res = attr.type === 'TMatrix' ? [] : {}; + let curVal = attr._new_value === null ? attr.value : attr._new_value; + for (let k in curVal) { + res[k] = curVal[k]; + } + res[key] = +val; + return res; + }; + + const convert = + { + E3DCOLOR: v => { + const toi = (v, s) => parseInt(v.substring(1 + s * 2, 3 + s * 2), 16); + return { + r: toi(attr._color, 0), g: toi(attr._color, 1), b: toi(attr._color, 2), a: toi(attr._color, 3) + } + }, + int: v => setByKey(v), + float: v => setByKey(v), + Point2: v => setByKey(v), + Point3: v => setByKey(v), + Point4: v => setByKey(v), + TMatrix: v => setByKey(v), + }; + + if (attr.type === 'E3DCOLOR' && Array.isArray(val)) { + attr._color = RGBAToHex(val); + } + + const valueToSet = convert[attr.type] ? convert[attr.type](val) : val; + + console.log('updateValue', attr, val, valueToSet); + + attr._new_value = valueToSet; + + console.log(ev); + if (ev.code === "Enter" || ev.type === "change") { + this.saveEdit(row, attr); + } + else if (ev.code === "Escape") { + this.cancelEdit(attr); + } +} + +function sortValues(values, key, getter = null) { + if (values._sortedKey === undefined) { + values._sortedKey = {}; + } + + if (values._sortedKey[key] === undefined) { + values._sortedKey[key] = {up: false, down: false}; + } + + const getValue = getter ? getter : v => v[key]; + + if (values._sortedKey[key].up) { + values._sortedKey[key].up = false; + values._sortedKey[key].down = true; + values.sort((a, b) => { + if (getValue(a) < getValue(b)) return 1; + if (getValue(a) > getValue(b)) return -1; + return 0; + }); + } + else if (values._sortedKey[key].down) { + values._sortedKey[key].up = false; + values._sortedKey[key].down = false; + values.sort((a, b) => { + if (a.id < b.id) return -1; + if (a.id > b.id) return 1; + return 0; + }); + } + else { + values._sortedKey[key].up = true; + values._sortedKey[key].down = false; + values.sort((a, b) => { + if (getValue(a) < getValue(b)) return -1; + if (getValue(a) > getValue(b)) return 1; + return 0; + }); + } +} + +export default { + loadModule(path) { + return loadModule(path, options) + }, + debounce(func, wait, immediate) { + var timeout, previous, args, result, context; + + var later = function () { + var passed = now() - previous; + if (wait > passed) { + timeout = setTimeout(later, wait - passed); + } else { + timeout = null; + if (!immediate) result = func.apply(context, args); + if (!timeout) args = context = null; + } + }; + + var debounced = restArguments(function (_args) { + context = this; + args = _args; + previous = now(); + if (!timeout) { + timeout = setTimeout(later, wait); + if (immediate) result = func.apply(context, args); + } + return result; + }); + + debounced.cancel = function () { + clearTimeout(timeout); + timeout = args = context = null; + }; + + return debounced; + }, + formatValue: compToString, + compToString, + RGBAToHex, + shouldOpenEditor, + getAttrValue, + startEdit, + cancelEdit, + saveEdit, + updateValue, + sortValues, +} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/core/services.js b/prog/gameLibs/webui/plugins/webView/vue/core/services.js new file mode 100644 index 000000000..59768c8ee --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/core/services.js @@ -0,0 +1,26 @@ +import { CoreService } from "./core.service.js"; +import { StreamService } from "./stream.service.js"; +import { SettingsService } from "./settings.service.js"; +import { ECSService } from "./ecs.service.js"; +import { DMService } from "./dm.service.js"; +import { useCookies } from "../vendor/vue-cookies.js"; + +const { cookies } = useCookies(); + +cookies.put = cookies.set; + +export const cookieService = cookies; +export const settingsService = new SettingsService(); +export const streamService = new StreamService(settingsService); +export const coreService = new CoreService(streamService, cookies); +export const ecsService = new ECSService(coreService); +export const dmService = new DMService(coreService); + +export default { + settingsService, + streamService, + coreService, + ecsService, + dmService, + cookieService, +} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/core/settings.service.js b/prog/gameLibs/webui/plugins/webView/vue/core/settings.service.js new file mode 100644 index 000000000..7dc7bab00 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/core/settings.service.js @@ -0,0 +1,52 @@ +const { ajax } = rxjs.ajax; +const { map, of, catchError } = rxjs; + +export class Settings { + constructor(port) { + this.port = port; + } +} + +export class SettingsService { + _defaultSettings = new Settings(9113); + _settings = null; + + _settingsPromise = null; + + getSettings() { + if (this._settingsPromise !== null) { + return this._settingsPromise; + } + + this._settingsPromise = new Promise((resolve, reject) => { + let onDone = (data) => { + console.log('Settings', data); + + this._settingsPromise = null; + this._settings = data; + resolve(this._settings); + }; + + if (this._settings !== null) { + resolve(this._settings); + } + else { + const obs$ = ajax(`${location.href}/settings.json`).pipe( + // const obs$ = ajax(`http://127.0.0.1:23456/webview/settings.json`).pipe( + map(data => data.response), + catchError(error => { + console.log('error: ', error); + return of(error); + }) + ); + + obs$.subscribe({ + next: value => onDone(value), + error: err => console.log(err) + }); + } + }); + + return this._settingsPromise; + } +} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/core/stream.service.js b/prog/gameLibs/webui/plugins/webView/vue/core/stream.service.js new file mode 100644 index 000000000..1a06cc8b4 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/core/stream.service.js @@ -0,0 +1,61 @@ +import * as common from './common.js'; +import { $WebSocket } from './websocket.js'; + +export class StreamService { + socket; + + _socketPromise = null; + + constructor(settingsService) { + this.settingsService = settingsService; + } + + connect() { + if (this._socketPromise === null) { + this._socketPromise = new Promise((resolve, reject) => { + if (this.socket) { + this._socketPromise = null; + resolve(this.socket); + return; + } + + this.settingsService.getSettings().then(settings => { + this.socket = new $WebSocket(`ws://localhost:${settings.port}/stream`, null, { initialTimeout: 500, maxTimeout: 5000, reconnectIfNotNormalClose: true }); + + this._socketPromise = null; + resolve(this.socket); + }); + }); + } + return this._socketPromise; + } + + onOpen(callback) { + this.connect().then(socket => socket.onOpen(() => callback())); + } + + onMessage(callback) { + this.connect().then(socket => socket.onMessage((event) => callback(event.data), null)); + } + + isConnected() { + this.connect(); + return this.socket && this.socket.getReadyState() == 1; + } + + send(json) { + if (this.socket === null || this.socket.getReadyState() !== 1) { + return; + } + + this.socket.send(common.jsonToBLK(json)).subscribe(); + } + + sendString(jsonString) { + if (this.socket === null || this.socket.getReadyState() !== 1) { + return; + } + + this.socket.send(jsonString).subscribe(); + } +} \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/core/websocket.js b/prog/gameLibs/webui/plugins/webView/vue/core/websocket.js new file mode 100644 index 000000000..c6bbb6059 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/core/websocket.js @@ -0,0 +1,334 @@ +const Observable = rxjs.Observable; +const Subject = rxjs.Subject; + +export class $WebSocket { + static Helpers = class { + static isPresent(obj) { + return obj !== undefined && obj !== null; + } + + static isString(obj) { + return typeof obj === 'string'; + } + + static isArray(obj) { + return Array.isArray(obj); + } + + static isFunction(obj) { + return typeof obj === 'function'; + } + }; + + reconnectAttempts = 0; + sendQueue = []; + onOpenCallbacks = []; + onMessageCallbacks = []; + onErrorCallbacks = []; + onCloseCallbacks = []; + readyStateConstants = { + 'CONNECTING': 0, + 'OPEN': 1, + 'CLOSING': 2, + 'CLOSED': 3, + 'RECONNECT_ABORTED': 4 + }; + normalCloseCode = 1000; + reconnectableStatusCodes = [4000]; + socket; + dataStream; + internalConnectionState; + + constructor(url, protocols = undefined, config = undefined, binaryType = undefined) { + this.url = url; + this.protocols = protocols; + this.config = config; + this.binaryType = binaryType; + + let match = new RegExp('wss?:\/\/').test(url); + if (!match) { + throw new Error('Invalid url provided'); + } + this.config = config || { initialTimeout: 500, maxTimeout: 300000, reconnectIfNotNormalClose: false }; + this.binaryType = binaryType || "blob"; + this.dataStream = new Subject(); + this.connect(true); + } + + connect(force = false) { + // console.log("WebSocket connecting..."); + let self = this; + if (force || !this.socket || this.socket.readyState !== this.readyStateConstants.OPEN) { + self.socket = this.protocols ? new WebSocket(this.url, this.protocols) : new WebSocket(this.url); + self.socket.binaryType = self.binaryType.toString(); + + self.socket.onopen = (ev) => { + // console.log('onOpen: ', ev); + this.onOpenHandler(ev); + }; + self.socket.onmessage = (ev) => { + // console.log('onNext: ', ev.data); + self.onMessageHandler(ev); + this.dataStream.next(ev); + }; + this.socket.onclose = (ev) => { + // console.log('onClose ', ev); + self.onCloseHandler(ev); + }; + + this.socket.onerror = (ev) => { + // console.log('onError ', ev); + self.onErrorHandler(ev); + this.dataStream.error(ev); + }; + + } + } + + /** + * Run in Block Mode + * Return true when can send and false in socket closed + * @param data + * @returns {boolean} + */ + send4Direct(data, binary = undefined) { + let self = this; + if (this.getReadyState() !== this.readyStateConstants.OPEN + && this.getReadyState() !== this.readyStateConstants.CONNECTING) { + this.connect(); + } + self.sendQueue.push({ message: data, binary: binary }); + if (self.socket.readyState === self.readyStateConstants.OPEN) { + self.fireQueue(); + return true; + } else { + return false; + } + } + + /** + * Return Promise + * When can Send will resolve Promise + * When Socket closed will reject Promise + * @param data + * @returns {Promise} + */ + send4Promise(data, binary = undefined) { + return new Promise( + (resolve, reject) => { + if (this.send4Direct(data, binary)) { + return resolve(); + } else { + return reject(Error('Socket connection has been closed')); + } + } + ) + } + + /** + * Return cold Observable + * When can Send will complete observer + * When Socket closed will error observer + * @param data + * @returns {Observable} + */ + send4Observable(data, binary = undefined) { + return Observable.create((observer) => { + if (this.send4Direct(data, binary)) { + return observer.complete(); + } else { + return observer.error('Socket connection has been closed'); + } + }); + } + + send4Mode = WebSocketSendMode.Observable; + + /** + * Set send(data) function return mode + * @param mode + */ + setSend4Mode(mode) { + this.send4Mode = mode; + } + + /** + * Use {mode} mode to send {data} data + * If no specify, Default SendMode is Observable mode + * @param data + * @param mode + * @param binary + * @returns {any} + */ + send(data, mode = undefined, binary = undefined) { + switch (typeof mode !== "undefined" ? mode : this.send4Mode) { + case WebSocketSendMode.Direct: + return this.send4Direct(data, binary); + case WebSocketSendMode.Promise: + return this.send4Promise(data, binary); + case WebSocketSendMode.Observable: + return this.send4Observable(data, binary); + default: + throw Error("WebSocketSendMode Error."); + } + } + + getDataStream() { + return this.dataStream; + } + + onOpenHandler(event) { + this.reconnectAttempts = 0; + this.notifyOpenCallbacks(event); + this.fireQueue(); + } + + notifyOpenCallbacks(event) { + for (let i = 0; i < this.onOpenCallbacks.length; i++) { + this.onOpenCallbacks[i].call(this, event); + } + } + + fireQueue() { + // console.log("fireQueue()"); + while (this.sendQueue.length && this.socket.readyState === this.readyStateConstants.OPEN) { + let data = this.sendQueue.shift(); + + // console.log("fireQueue: ", data); + if (data.binary) { + this.socket.send(data.message); + } else { + this.socket.send( + $WebSocket.Helpers.isString(data.message) ? data.message : JSON.stringify(data.message) + ); + } + // data.deferred.resolve(); + } + } + + notifyCloseCallbacks(event) { + for (let i = 0; i < this.onCloseCallbacks.length; i++) { + this.onCloseCallbacks[i].call(this, event); + } + } + + notifyErrorCallbacks(event) { + for (let i = 0; i < this.onErrorCallbacks.length; i++) { + this.onErrorCallbacks[i].call(this, event); + } + } + + onOpen(cb) { + this.onOpenCallbacks.push(cb); + return this; + }; + + onClose(cb) { + this.onCloseCallbacks.push(cb); + return this; + } + + onError(cb) { + this.onErrorCallbacks.push(cb); + return this; + }; + + onMessage(callback, options = undefined) { + if (!$WebSocket.Helpers.isFunction(callback)) { + throw new Error('Callback must be a function'); + } + + this.onMessageCallbacks.push({ + fn: callback, + pattern: options ? options.filter : undefined, + autoApply: options ? options.autoApply : true + }); + return this; + } + + onMessageHandler(message) { + let self = this; + let currentCallback; + for (let i = 0; i < self.onMessageCallbacks.length; i++) { + currentCallback = self.onMessageCallbacks[i]; + currentCallback.fn.apply(self, [message]); + } + }; + + onCloseHandler(event) { + this.notifyCloseCallbacks(event); + if ((this.config.reconnectIfNotNormalClose && event.code !== this.normalCloseCode) + || this.reconnectableStatusCodes.indexOf(event.code) > -1) { + this.reconnect(); + } else { + this.sendQueue = []; + this.dataStream.complete(); + } + }; + + onErrorHandler(event) { + this.notifyErrorCallbacks(event); + }; + + reconnect() { + this.close(true); + let backoffDelay = this.getBackoffDelay(++this.reconnectAttempts); + // let backoffDelaySeconds = backoffDelay / 1000; + // console.log('Reconnecting in ' + backoffDelaySeconds + ' seconds'); + setTimeout(() => this.connect(), backoffDelay); + return this; + } + + close(force = false) { + if (force || !this.socket.bufferedAmount) { + this.socket.close(this.normalCloseCode); + } + return this; + }; + + // Exponential Backoff Formula by Prof. Douglas Thain + // http://dthain.blogspot.co.uk/2009/02/exponential-backoff-in-distributed.html + getBackoffDelay(attempt) { + let R = Math.random() + 1; + let T = this.config.initialTimeout; + let F = 2; + let N = attempt; + let M = this.config.maxTimeout; + + return Math.floor(Math.min(R * T * Math.pow(F, N), M)); + }; + + setInternalState(state) { + if (Math.floor(state) !== state || state < 0 || state > 4) { + throw new Error('state must be an integer between 0 and 4, got: ' + state); + } + + this.internalConnectionState = state; + + } + + /** + * Could be -1 if not initzialized yet + * @returns {number} + */ + getReadyState() { + if (this.socket == null) { + return -1; + } + return this.internalConnectionState || this.socket.readyState; + } +} + +// export interface WebSocketConfig { +// initialTimeout: number; +// maxTimeout: number; +// reconnectIfNotNormalClose; +// } + +export const WebSocketSendMode = { + Direct: 0, + Promise: 1, + Observable: 2 +} + +// export type BinaryType = "blob" | "arraybuffer"; \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/index.html b/prog/gameLibs/webui/plugins/webView/vue/index.html new file mode 100644 index 000000000..e3f324d69 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/index.html @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ Connection status: + {{ status }} +
+ + + + To enable this feature add enableWebSocketStream:b = yes to debug section in + config.blk + + + +
+ + +
+ + + \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/main.js b/prog/gameLibs/webui/plugins/webView/vue/main.js new file mode 100644 index 000000000..84a9b6e9a --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/main.js @@ -0,0 +1,24 @@ +import { streamService } from './core/services.js'; +import { createMyApp, app, status, SortableColumn } from './app.js'; + +export function main() { + Vue.component('vue-bootstrap-typeahead', VueBootstrapTypeahead); + Vue.component('RecycleScroller', VueVirtualScroller.RecycleScroller); + Vue.component('color-picker', VColor); + Vue.component('vue-multiselect', VueMultiselect.Multiselect); + Vue.component('SortableColumn', SortableColumn); + + createMyApp(); + + console.log('App', app); + console.log('App', app.$bvModal); + console.log('Vue', Vue.$bvModal); + + setInterval(() => { + let prevStatus = status; + let curStatus = streamService.isConnected() ? "Online" : "Offline"; + if (prevStatus !== curStatus) { + status.value = curStatus; + } + }, 500); +} diff --git a/prog/gameLibs/webui/plugins/webView/web/assets/styles.css b/prog/gameLibs/webui/plugins/webView/vue/styles.css similarity index 97% rename from prog/gameLibs/webui/plugins/webView/web/assets/styles.css rename to prog/gameLibs/webui/plugins/webView/vue/styles.css index 220134592..bacd910eb 100644 --- a/prog/gameLibs/webui/plugins/webView/web/assets/styles.css +++ b/prog/gameLibs/webui/plugins/webView/vue/styles.css @@ -178,4 +178,13 @@ .table-bordered td { border: 1px solid #ddd !important; } -} \ No newline at end of file +} + +.online { + color: green; + font-weight: bold; +} + +.offline { + color: red; +} diff --git a/prog/gameLibs/webui/plugins/webView/src/vendor/bootstrap/css/bootstrap-4.0.0.min.css b/prog/gameLibs/webui/plugins/webView/vue/vendor/bootstrap-4.0.0.css similarity index 100% rename from prog/gameLibs/webui/plugins/webView/src/vendor/bootstrap/css/bootstrap-4.0.0.min.css rename to prog/gameLibs/webui/plugins/webView/vue/vendor/bootstrap-4.0.0.css diff --git a/prog/gameLibs/webui/plugins/webView/src/vendor/bson.js b/prog/gameLibs/webui/plugins/webView/vue/vendor/bson.js similarity index 100% rename from prog/gameLibs/webui/plugins/webView/src/vendor/bson.js rename to prog/gameLibs/webui/plugins/webView/vue/vendor/bson.js diff --git a/prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/css/font-awesome.min.css b/prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/css/font-awesome.min.css similarity index 100% rename from prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/css/font-awesome.min.css rename to prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/css/font-awesome.min.css diff --git a/prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/fonts/fontawesome-webfont.eot b/prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/fonts/fontawesome-webfont.eot similarity index 100% rename from prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/fonts/fontawesome-webfont.eot rename to prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/fonts/fontawesome-webfont.eot diff --git a/prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/fonts/fontawesome-webfont.svg b/prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/fonts/fontawesome-webfont.svg similarity index 100% rename from prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/fonts/fontawesome-webfont.svg rename to prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/fonts/fontawesome-webfont.svg diff --git a/prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/fonts/fontawesome-webfont.ttf b/prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/fonts/fontawesome-webfont.ttf similarity index 100% rename from prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/fonts/fontawesome-webfont.ttf rename to prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/fonts/fontawesome-webfont.ttf diff --git a/prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/fonts/fontawesome-webfont.woff b/prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/fonts/fontawesome-webfont.woff similarity index 100% rename from prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/fonts/fontawesome-webfont.woff rename to prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/fonts/fontawesome-webfont.woff diff --git a/prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/fonts/fontawesome-webfont.woff2 b/prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/fonts/fontawesome-webfont.woff2 similarity index 100% rename from prog/gameLibs/webui/plugins/webView/src/vendor/font-awesome/fonts/fontawesome-webfont.woff2 rename to prog/gameLibs/webui/plugins/webView/vue/vendor/font-awesome/fonts/fontawesome-webfont.woff2 diff --git a/prog/gameLibs/webui/plugins/webView/vue/vendor/rxjs.js b/prog/gameLibs/webui/plugins/webView/vue/vendor/rxjs.js new file mode 100644 index 000000000..c211d716e --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/vendor/rxjs.js @@ -0,0 +1,195 @@ +/** + @license + Apache License 2.0 https://github.com/ReactiveX/RxJS/blob/master/LICENSE.txt + **/ +/** + @license + Apache License 2.0 https://github.com/ReactiveX/RxJS/blob/master/LICENSE.txt + **/ +/* + ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. +*****************************************************************************/ +(function(g,y){"object"===typeof exports&&"undefined"!==typeof module?y(exports):"function"===typeof define&&define.amd?define("rxjs",["exports"],y):y(g.rxjs={})})(this,function(g){function y(b,a){function c(){this.constructor=b}if("function"!==typeof a&&null!==a)throw new TypeError("Class extends value "+String(a)+" is not a constructor or null");Ta(b,a);b.prototype=null===a?Object.create(a):(c.prototype=a.prototype,new c)}function Zd(b,a){var c={},d;for(d in b)Object.prototype.hasOwnProperty.call(b, +d)&&0>a.indexOf(d)&&(c[d]=b[d]);if(null!=b&&"function"===typeof Object.getOwnPropertySymbols){var e=0;for(d=Object.getOwnPropertySymbols(b);ea.indexOf(d[e])&&Object.prototype.propertyIsEnumerable.call(b,d[e])&&(c[d[e]]=b[d[e]])}return c}function $d(b,a,c,d){function e(a){return a instanceof c?a:new c(function(b){b(a)})}return new (c||(c=Promise))(function(c,h){function f(a){try{z(d.next(a))}catch(v){h(v)}}function k(a){try{z(d["throw"](a))}catch(v){h(v)}}function z(a){a.done?c(a.value): +e(a.value).then(f,k)}z((d=d.apply(b,a||[])).next())})}function Ua(b,a){function c(a){return function(b){return d([a,b])}}function d(c){if(f)throw new TypeError("Generator is already executing.");for(;e;)try{if(f=1,h&&(l=c[0]&2?h["return"]:c[0]?h["throw"]||((l=h["return"])&&l.call(h),0):h.next)&&!(l=l.call(h,c[1])).done)return l;if(h=0,l)c=[c[0]&2,l.value];switch(c[0]){case 0:case 1:l=c;break;case 4:return e.label++,{value:c[1],done:!1};case 5:e.label++;h=c[1];c=[0];continue;case 7:c=e.ops.pop();e.trys.pop(); +continue;default:if(!(l=e.trys,l=0l[0]&&c[1]=b.length&&(b=void 0);return{value:b&&b[d++],done:!b}}};throw new TypeError(a?"Object is not iterable.":"Symbol.iterator is not defined.");}function w(b,a){var c="function"===typeof Symbol&&b[Symbol.iterator];if(!c)return b;b= +c.call(b);var d,e=[],f;try{for(;(void 0===a||0=b._refCount||0<--b._refCount)c=null;else{var d=b._connection,f=c;c=null;!d||f&&d!==f||d.unsubscribe();a.unsubscribe()}});b.subscribe(d);d.closed||(c=b.connect())})}function Mb(b){return new r(function(a){var c=b||Da,d=c.now(),e=0,f=function(){a.closed||(e=N.requestAnimationFrame(function(h){e=0;var l=c.now();a.next({timestamp:b?l:h,elapsed:l-d});f()}))};f();return function(){e&&N.cancelAnimationFrame(e)}})}function Nb(b){return b in +$a?(delete $a[b],!0):!1}function de(b){return new r(function(a){return b.schedule(function(){return a.complete()})})}function Ea(b){return b&&t(b.schedule)}function oa(b){return t(b[b.length-1])?b.pop():void 0}function O(b){return Ea(b[b.length-1])?b.pop():void 0}function Ob(b){return Symbol.asyncIterator&&t(null===b||void 0===b?void 0:b[Symbol.asyncIterator])}function Pb(b){return new TypeError("You provided "+(null!==b&&"object"===typeof b?"an invalid object":"'"+b+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")} +function Qb(b){return t(null===b||void 0===b?void 0:b[ab])}function Rb(b){return ae(this,arguments,function(){var a,c,d,e;return Ua(this,function(f){switch(f.label){case 0:a=b.getReader(),f.label=1;case 1:f.trys.push([1,,9,10]),f.label=2;case 2:return[4,ca(a.read())];case 3:return c=f.sent(),d=c.value,(e=c.done)?[4,ca(void 0)]:[3,5];case 4:return[2,f.sent()];case 5:return[4,ca(d)];case 6:return[4,f.sent()];case 7:return f.sent(),[3,2];case 8:return[3,10];case 9:return a.releaseLock(),[7];case 10:return[2]}})})} +function q(b){if(b instanceof r)return b;if(null!=b){if(t(b[pa]))return ee(b);if(bb(b))return fe(b);if(t(null===b||void 0===b?void 0:b.then))return ge(b);if(Ob(b))return Sb(b);if(Qb(b))return he(b);if(t(null===b||void 0===b?void 0:b.getReader))return Sb(Rb(b))}throw Pb(b);}function ee(b){return new r(function(a){var c=b[pa]();if(t(c.subscribe))return c.subscribe(a);throw new TypeError("Provided object does not correctly implement Symbol.observable");})}function fe(b){return new r(function(a){for(var c= +0;ce&&(e=0);var h=0;return c.schedule(function(){a.closed||(a.next(h++),0<=d?this.schedule(void 0,d):a.complete())},e)})}function ec(b,a){void 0===b&&(b=0);void 0===a&&(a=I);0>b&&(b=0);return Y(b,b,a)}function Z(b){return 1===b.length&&we(b[0])?b[0]:b}function fc(){for(var b=[],a=0;a=b?function(){return L}:n(function(a,c){var d=0;a.subscribe(m(c,function(a){++d<=b&&(c.next(a),b<=d&&c.complete())}))})} +function ob(){return n(function(b,a){b.subscribe(m(a,C))})}function pb(b){return Q(function(){return b})}function Ma(b,a){return a?function(c){return ta(a.pipe(ga(1),ob()),c.pipe(Ma(b)))}:H(function(a,d){return q(b(a,d)).pipe(ga(1),pb(a))})}function xc(b,a){void 0===a&&(a=I);var c=Y(b,a);return Ma(function(){return c})}function yc(){return n(function(b,a){b.subscribe(m(a,function(c){return Fa(c,a)}))})}function zc(b,a){return n(function(c,d){var e=new Set;c.subscribe(m(d,function(a){var c=b?b(a): +a;e.has(c)||(e.add(c),d.next(a))}));a&&q(a).subscribe(m(d,function(){return e.clear()},C))})}function qb(b,a){void 0===a&&(a=E);b=null!==b&&void 0!==b?b:De;return n(function(c,d){var e,f=!0;c.subscribe(m(d,function(c){var h=a(c);if(f||!b(e,h))f=!1,e=h,d.next(c)}))})}function De(b,a){return b===a}function Ac(b,a){return qb(function(c,d){return a?a(c[b],d[b]):c[b]===d[b]})}function va(b){void 0===b&&(b=Ee);return n(function(a,c){var d=!1;a.subscribe(m(c,function(a){d=!0;c.next(a)},function(){return d? +c.complete():c.error(b())}))})}function Ee(){return new aa}function Bc(b,a){if(0>b)throw new rb;var c=2<=arguments.length;return function(d){return d.pipe(K(function(a,c){return c===b}),ga(1),c?ua(a):va(function(){return new rb}))}}function Cc(){for(var b=[],a=0;a(a||0)?Infinity:a;return n(function(d,e){return gb(d,e,b,a,void 0,!0,c)})}function Fc(b){return n(function(a, +c){try{a.subscribe(c)}finally{c.add(b)}})}function Gc(b,a){return n(Hc(b,a,"value"))}function Hc(b,a,c){var d="index"===c;return function(c,f){var e=0;c.subscribe(m(f,function(h){var l=e++;b.call(a,h,l,c)&&(f.next(d?l:h),f.complete())},function(){f.next(d?-1:void 0);f.complete()}))}}function Ic(b,a){return n(Hc(b,a,"index"))}function Jc(b,a){var c=2<=arguments.length;return function(d){return d.pipe(b?K(function(a,c){return b(a,c,d)}):E,ga(1),c?ua(a):va(function(){return new aa}))}}function Kc(b, +a,c,d){return n(function(e,f){function h(a,c){var b=new r(function(a){v++;var b=c.subscribe(a);return function(){b.unsubscribe();0===--v&&n&&Va.unsubscribe()}});b.key=a;return b}var l;a&&"function"!==typeof a?(c=a.duration,l=a.element,d=a.connector):l=a;var k=new Map,g=function(a){k.forEach(a);a(f)},p=function(a){return g(function(c){return c.error(a)})},v=0,n=!1,Va=new Ya(f,function(a){try{var e=b(a),g=k.get(e);if(!g){k.set(e,g=d?d():new A);var z=h(e,g);f.next(z);if(c){var v=m(g,function(){g.complete(); +null===v||void 0===v?void 0:v.unsubscribe()},void 0,void 0,function(){return k.delete(e)});Va.add(q(c(z)).subscribe(v))}}g.next(l?l(a):a)}catch(xe){p(xe)}},function(){return g(function(a){return a.complete()})},p,function(){return k.clear()},function(){n=!0;return 0===v});e.subscribe(Va)})}function Lc(){return n(function(b,a){b.subscribe(m(a,function(){a.next(!1);a.complete()},function(){a.next(!0);a.complete()}))})}function sb(b){return 0>=b?function(){return L}:n(function(a,c){var d=[];a.subscribe(m(c, +function(a){d.push(a);bc?a:c})}function Pc(b,a,c){void 0===c&&(c=Infinity);if(t(a))return H(function(){return b},a,c);"number"===typeof a&&(c=a);return H(function(){return b},c)}function Qc(b,a,c){void 0===c&&(c=Infinity);return n(function(d,e){var f=a;return gb(d,e,function(a,c){return b(f,a,c)},c,function(a){f=a},!1,void 0, +function(){return f=null})})}function Rc(){for(var b=[],a=0;ab(a,c)?a:c}:function(a,c){return a=c?function(){return L}:n(function(a,b){var e=0,f,k=function(){null===f||void 0===f?void 0:f.unsubscribe();f=null;if(null!=d){var a="number"===typeof d?Y(d):q(d(e)),c=m(b,function(){c.unsubscribe();g()});a.subscribe(c)}else g()},g=function(){var d=!1;f=a.subscribe(m(b,void 0,function(){++e= +c?E:n(function(a,b){var f=0,h,g=function(){var l=!1;h=a.subscribe(m(b,function(a){e&&(f=0);b.next(a)},void 0,function(a){if(f++=b?E:n(function(a,c){var d= +Array(b),e=0;a.subscribe(m(c,function(a){var f=e++;if(fe){null===(b=null===r||void 0===r?void 0:r.complete)||void 0===b?void 0:b.call(r);b=void 0;try{b=new yb(c,u,q,Od+"_"+c.type)}catch(ye){a.error(ye);return}a.next(b);a.complete()}else null===(d=null===r||void 0===r?void 0:r.error)||void 0===d?void 0:d.call(r,c),x(e)});e=q.user;d=q.method;h=q.async; +e?u.open(d,k,h,e,q.password):u.open(d,k,h);h&&(u.timeout=q.timeout,u.responseType=q.responseType);"withCredentials"in u&&(u.withCredentials=q.withCredentials);for(p in f)f.hasOwnProperty(p)&&u.setRequestHeader(p,f[p]);c?u.send(c):u.send();return function(){u&&4!==u.readyState&&u.abort()}})}function Oe(b,a){var c;if(!b||"string"===typeof b||"undefined"!==typeof FormData&&b instanceof FormData||"undefined"!==typeof URLSearchParams&&b instanceof URLSearchParams||Bb(b,"ArrayBuffer")||Bb(b,"File")||Bb(b, +"Blob")||"undefined"!==typeof ReadableStream&&b instanceof ReadableStream)return b;if("undefined"!==typeof ArrayBuffer&&ArrayBuffer.isView(b))return b.buffer;if("object"===typeof b)return a["content-type"]=null!==(c=a["content-type"])&&void 0!==c?c:"application/json;charset\x3dutf-8",JSON.stringify(b);throw new TypeError("Unknown body type");}function Bb(b,a){return Qe.call(b)==="[object "+a+"]"}var Ta=function(b,a){Ta=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(a,b){a.__proto__= +b}||function(a,b){for(var c in b)Object.prototype.hasOwnProperty.call(b,c)&&(a[c]=b[c])};return Ta(b,a)},T=function(){T=Object.assign||function(b){for(var a,c=1,d=arguments.length;ca&&hb.index?1:-1:a.delay>b.delay?1:-1};return a}(ya),L=new r(function(b){return b.complete()}), +bb=function(b){return b&&"number"===typeof b.length&&"function"!==typeof b},ab;ab="function"===typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator";(function(b){b.NEXT="N";b.ERROR="E";b.COMPLETE="C"})(g.NotificationKind||(g.NotificationKind={}));var Pa=function(){function b(a,b,d){this.kind=a;this.value=b;this.error=d;this.hasValue="N"===a}b.prototype.observe=function(a){return Fa(this,a)};b.prototype.do=function(a,b,d){var c=this.kind,f=this.value,h=this.error;return"N"===c?null===a||void 0=== +a?void 0:a(f):"E"===c?null===b||void 0===b?void 0:b(h):null===d||void 0===d?void 0:d()};b.prototype.accept=function(a,b,d){return t(null===a||void 0===a?void 0:a.next)?this.observe(a):this.do(a,b,d)};b.prototype.toObservable=function(){var a=this.kind,b=this.value,d=this.error,b="N"===a?cb(b):"E"===a?Wb(function(){return d}):"C"===a?L:0;if(!b)throw new TypeError("Unexpected notification kind "+a);return b};b.createNext=function(a){return new b("N",a)};b.createError=function(a){return new b("E",void 0, +a)};b.createComplete=function(){return b.completeNotification};b.completeNotification=new b("C");return b}(),aa=R(function(b){return function(){b(this);this.name="EmptyError";this.message="no elements in sequence"}}),rb=R(function(b){return function(){b(this);this.name="ArgumentOutOfRangeError";this.message="argument out of range"}}),ld=R(function(b){return function(a){b(this);this.name="NotFoundError";this.message=a}}),kd=R(function(b){return function(a){b(this);this.name="SequenceError";this.message= +a}}),Xb=R(function(b){return function(a){void 0===a&&(a=null);b(this);this.message="Timeout has occurred";this.name="TimeoutError";this.info=a}}),le=Array.isArray,me=Array.isArray,ne=Object.getPrototypeOf,oe=Object.prototype,pe=Object.keys,$e={connector:function(){return new A},resetOnDisconnect:!0},te=["addListener","removeListener"],re=["addEventListener","removeEventListener"],ve=["on","off"],Vd=new r(C),we=Array.isArray,Ae=function(b,a){return b.push(a),b},Ce={connector:function(){return new A}}, +Fe=function(){return function(b,a){this.value=b;this.interval=a}}(),af=Object.freeze({audit:kb,auditTime:ic,buffer:jc,bufferCount:kc,bufferTime:lc,bufferToggle:mc,bufferWhen:nc,catchError:lb,combineAll:Ja,combineLatestAll:Ja,combineLatest:nb,combineLatestWith:qc,concat:sc,concatAll:Ha,concatMap:Ka,concatMapTo:rc,concatWith:tc,connect:La,count:uc,debounce:vc,debounceTime:wc,defaultIfEmpty:ua,delay:xc,delayWhen:Ma,dematerialize:yc,distinct:zc,distinctUntilChanged:qb,distinctUntilKeyChanged:Ac,elementAt:Bc, +endWith:Cc,every:Dc,exhaust:Oa,exhaustAll:Oa,exhaustMap:Na,expand:Ec,filter:K,finalize:Fc,find:Gc,findIndex:Ic,first:Jc,groupBy:Kc,ignoreElements:ob,isEmpty:Lc,last:Mc,map:Q,mapTo:pb,materialize:Nc,max:Oc,merge:Rc,mergeAll:sa,flatMap:H,mergeMap:H,mergeMapTo:Pc,mergeScan:Qc,mergeWith:Sc,min:Tc,multicast:Qa,observeOn:qa,onErrorResumeNext:Uc,pairwise:Vc,partition:function(b,a){return function(c){return[K(b,a)(c),K(gc(b,a))(c)]}},pluck:Wc,publish:Xc,publishBehavior:Yc,publishLast:$c,publishReplay:ad, +race:function(){for(var b=[],a=0;ak?new Aa(l):new Aa(l,k)};a.parseMarbles=function(a, +b,e,f,g){var c=this;void 0===f&&(f=!1);void 0===g&&(g=!1);if(-1!==a.indexOf("!"))throw Error('conventional marble diagrams cannot have the unsubscription marker "!"');var d=x([],w(a)),h=d.length,p=[];a=g?a.replace(/^[ ]+/,"").indexOf("^"):a.indexOf("^");var m=-1===a?0:a*-this.frameTimeFactor,n="object"!==typeof b?function(a){return a}:function(a){return f&&b[a]instanceof Hb?b[a].messages:b[a]},q=-1;a=function(a){var b=m,f=function(a){b+=a*c.frameTimeFactor},h=void 0,k=d[a];switch(k){case " ":g||f(1); +break;case "-":f(1);break;case "(":q=m;f(1);break;case ")":q=-1;f(1);break;case "|":h=xa;f(1);break;case "^":f(1);break;case "#":h=J("E",void 0,e||"error");f(1);break;default:if(g&&k.match(/^[0-9]$/)&&(0===a||" "===d[a-1])){var l=d.slice(a).join("").match(/^([0-9]+(?:\.[0-9]+)?)(ms|s|m) /);if(l){a+=l[0].length-1;var k=parseFloat(l[1]),v=void 0;switch(l[2]){case "ms":v=k;break;case "s":v=1E3*k;break;case "m":v=6E4*k}f(v/r.frameTimeFactor);break}}h=J("N",n(k),void 0);f(1)}h&&p.push({frame:-1=a)return L;var d=a+b;return new r(c?function(a){var e=b;return c.schedule(function(){e< +d?(a.next(e++),this.schedule()):a.complete()})}:function(a){for(var c=b;cc)r.f(t,n=a[c++],e[n]);return t}},"1eb2":function(t,e,n){var r;"undefined"!==typeof window&&((r=window.document.currentScript)&&(r=r.src.match(/(.+\/)[^/]+\.js$/))&&(n.p=r[1]))},"214f":function(t,e,n){"use strict";var r=n("32e9"),i=n("2aba"),o=n("79e5"),a=n("be13"),u=n("2b4c");t.exports=function(t,e,n){var c=u(t),s=n(a,c,""[t]),f=s[0],p=s[1];o(function(){var e={};return e[c]=function(){return 7},7!=""[t](e)})&&(i(String.prototype,t,f),r(RegExp.prototype,c,2==e?function(t,e){return p.call(t,this,e)}:function(t){return p.call(t,this)}))}},"230e":function(t,e,n){var r=n("d3f4"),i=n("7726").document,o=r(i)&&r(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},"2aba":function(t,e,n){var r=n("7726"),i=n("32e9"),o=n("69a8"),a=n("ca5a")("src"),u="toString",c=Function[u],s=(""+c).split(u);n("8378").inspectSource=function(t){return c.call(t)},(t.exports=function(t,e,n,u){var c="function"==typeof n;c&&(o(n,"name")||i(n,"name",e)),t[e]!==n&&(c&&(o(n,a)||i(n,a,t[e]?""+t[e]:s.join(String(e)))),t===r?t[e]=n:u?t[e]?t[e]=n:i(t,e,n):(delete t[e],i(t,e,n)))})(Function.prototype,u,function(){return"function"==typeof this&&this[a]||c.call(this)})},"2aeb":function(t,e,n){var r=n("cb7c"),i=n("1495"),o=n("e11e"),a=n("613b")("IE_PROTO"),u=function(){},c="prototype",s=function(){var t,e=n("230e")("iframe"),r=o.length,i="<",a=">";e.style.display="none",n("fab2").appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(i+"script"+a+"document.F=Object"+i+"/script"+a),t.close(),s=t.F;while(r--)delete s[c][o[r]];return s()};t.exports=Object.create||function(t,e){var n;return null!==t?(u[c]=r(t),n=new u,u[c]=null,n[a]=t):n=s(),void 0===e?n:i(n,e)}},"2b4c":function(t,e,n){var r=n("5537")("wks"),i=n("ca5a"),o=n("7726").Symbol,a="function"==typeof o,u=t.exports=function(t){return r[t]||(r[t]=a&&o[t]||(a?o:i)("Symbol."+t))};u.store=r},"2d00":function(t,e){t.exports=!1},"2d95":function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},"2f21":function(t,e,n){"use strict";var r=n("79e5");t.exports=function(t,e){return!!t&&r(function(){e?t.call(null,function(){},1):t.call(null)})}},"32e9":function(t,e,n){var r=n("86cc"),i=n("4630");t.exports=n("9e1e")?function(t,e,n){return r.f(t,e,i(1,n))}:function(t,e,n){return t[e]=n,t}},"3b2b":function(t,e,n){var r=n("7726"),i=n("5dbc"),o=n("86cc").f,a=n("9093").f,u=n("aae3"),c=n("0bfb"),s=r.RegExp,f=s,p=s.prototype,l=/a/g,d=/a/g,h=new s(l)!==l;if(n("9e1e")&&(!h||n("79e5")(function(){return d[n("2b4c")("match")]=!1,s(l)!=l||s(d)==d||"/a/i"!=s(l,"i")}))){s=function(t,e){var n=this instanceof s,r=u(t),o=void 0===e;return!n&&r&&t.constructor===s&&o?t:i(h?new f(r&&!o?t.source:t,e):f((r=t instanceof s)?t.source:t,r&&o?c.call(t):e),n?this:p,s)};for(var v=function(t){t in s||o(s,t,{configurable:!0,get:function(){return f[t]},set:function(e){f[t]=e}})},b=a(f),y=0;b.length>y;)v(b[y++]);p.constructor=s,s.prototype=p,n("2aba")(r,"RegExp",s)}n("7a56")("RegExp")},4588:function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},4630:function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},4917:function(t,e,n){n("214f")("match",1,function(t,e,n){return[function(n){"use strict";var r=t(this),i=void 0==n?void 0:n[e];return void 0!==i?i.call(n,r):new RegExp(n)[e](String(r))},n]})},"4bf8":function(t,e,n){var r=n("be13");t.exports=function(t){return Object(r(t))}},"52a7":function(t,e){e.f={}.propertyIsEnumerable},5537:function(t,e,n){var r=n("8378"),i=n("7726"),o="__core-js_shared__",a=i[o]||(i[o]={});(t.exports=function(t,e){return a[t]||(a[t]=void 0!==e?e:{})})("versions",[]).push({version:r.version,mode:n("2d00")?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},"55dd":function(t,e,n){"use strict";var r=n("5ca1"),i=n("d8e8"),o=n("4bf8"),a=n("79e5"),u=[].sort,c=[1,2,3];r(r.P+r.F*(a(function(){c.sort(void 0)})||!a(function(){c.sort(null)})||!n("2f21")(u)),"Array",{sort:function(t){return void 0===t?u.call(o(this)):u.call(o(this),i(t))}})},"5ca1":function(t,e,n){var r=n("7726"),i=n("8378"),o=n("32e9"),a=n("2aba"),u=n("9b43"),c="prototype",s=function(t,e,n){var f,p,l,d,h=t&s.F,v=t&s.G,b=t&s.S,y=t&s.P,_=t&s.B,g=v?r:b?r[e]||(r[e]={}):(r[e]||{})[c],m=v?i:i[e]||(i[e]={}),x=m[c]||(m[c]={});for(f in v&&(n=e),n)p=!h&&g&&void 0!==g[f],l=(p?g:n)[f],d=_&&p?u(l,r):y&&"function"==typeof l?u(Function.call,l):l,g&&a(g,f,l,t&s.U),m[f]!=l&&o(m,f,d),y&&x[f]!=l&&(x[f]=l)};r.core=i,s.F=1,s.G=2,s.S=4,s.P=8,s.B=16,s.W=32,s.U=64,s.R=128,t.exports=s},"5dbc":function(t,e,n){var r=n("d3f4"),i=n("8b97").set;t.exports=function(t,e,n){var o,a=e.constructor;return a!==n&&"function"==typeof a&&(o=a.prototype)!==n.prototype&&r(o)&&i&&i(t,o),t}},"613b":function(t,e,n){var r=n("5537")("keys"),i=n("ca5a");t.exports=function(t){return r[t]||(r[t]=i(t))}},"626a":function(t,e,n){var r=n("2d95");t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},6821:function(t,e,n){var r=n("626a"),i=n("be13");t.exports=function(t){return r(i(t))}},"69a8":function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},"6a99":function(t,e,n){var r=n("d3f4");t.exports=function(t,e){if(!r(t))return t;var n,i;if(e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;if("function"==typeof(n=t.valueOf)&&!r(i=n.call(t)))return i;if(!e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},"6dd8":function(t,e,n){"use strict";(function(t){var n=function(){if("undefined"!==typeof Map)return Map;function t(t,e){var n=-1;return t.some(function(t,r){return t[0]===e&&(n=r,!0)}),n}return function(){function e(){this.__entries__=[]}var n={size:{configurable:!0}};return n.size.get=function(){return this.__entries__.length},e.prototype.get=function(e){var n=t(this.__entries__,e),r=this.__entries__[n];return r&&r[1]},e.prototype.set=function(e,n){var r=t(this.__entries__,e);~r?this.__entries__[r][1]=n:this.__entries__.push([e,n])},e.prototype.delete=function(e){var n=this.__entries__,r=t(n,e);~r&&n.splice(r,1)},e.prototype.has=function(e){return!!~t(this.__entries__,e)},e.prototype.clear=function(){this.__entries__.splice(0)},e.prototype.forEach=function(t,e){var n=this;void 0===e&&(e=null);for(var r=0,i=n.__entries__;r0},p.prototype.connect_=function(){r&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),f?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},p.prototype.disconnect_=function(){r&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},p.prototype.onTransitionEnd_=function(t){var e=t.propertyName;void 0===e&&(e="");var n=s.some(function(t){return!!~e.indexOf(t)});n&&this.refresh()},p.getInstance=function(){return this.instance_||(this.instance_=new p),this.instance_},p.instance_=null;var l=function(t,e){for(var n=0,r=Object.keys(e);n0)e[n]=arguments[n+1];return e.reduce(function(e,n){var r=t["border-"+n+"-width"];return e+v(r)},0)}function y(t){for(var e=["top","right","bottom","left"],n={},r=0,i=e;r0};var j="undefined"!==typeof WeakMap?new WeakMap:new n,C=function(t){if(!(this instanceof C))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var e=p.getInstance(),n=new M(t,e,this);j.set(this,n)};["observe","unobserve","disconnect"].forEach(function(t){C.prototype[t]=function(){return(e=j.get(this))[t].apply(e,arguments);var e}});var V=function(){return"undefined"!==typeof i.ResizeObserver?i.ResizeObserver:C}();e["a"]=V}).call(this,n("c8ba"))},7726:function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},"77f1":function(t,e,n){var r=n("4588"),i=Math.max,o=Math.min;t.exports=function(t,e){return t=r(t),t<0?i(t+e,0):o(t,e)}},"79e5":function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},"7a56":function(t,e,n){"use strict";var r=n("7726"),i=n("86cc"),o=n("9e1e"),a=n("2b4c")("species");t.exports=function(t){var e=r[t];o&&e&&!e[a]&&i.f(e,a,{configurable:!0,get:function(){return this}})}},8378:function(t,e){var n=t.exports={version:"2.5.7"};"number"==typeof __e&&(__e=n)},"86cc":function(t,e,n){var r=n("cb7c"),i=n("c69a"),o=n("6a99"),a=Object.defineProperty;e.f=n("9e1e")?Object.defineProperty:function(t,e,n){if(r(t),e=o(e,!0),r(n),i)try{return a(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},"892a":function(t,e,n){"use strict";var r=n("9bf9"),i=n.n(r);i.a},"8b97":function(t,e,n){var r=n("d3f4"),i=n("cb7c"),o=function(t,e){if(i(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,e,r){try{r=n("9b43")(Function.call,n("11e9").f(Object.prototype,"__proto__").set,2),r(t,[]),e=!(t instanceof Array)}catch(t){e=!0}return function(t,n){return o(t,n),e?t.__proto__=n:r(t,n),t}}({},!1):void 0),check:o}},9093:function(t,e,n){var r=n("ce10"),i=n("e11e").concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return r(t,i)}},"9b43":function(t,e,n){var r=n("d8e8");t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,i){return t.call(e,n,r,i)}}return function(){return t.apply(e,arguments)}}},"9bf9":function(t,e,n){},"9def":function(t,e,n){var r=n("4588"),i=Math.min;t.exports=function(t){return t>0?i(r(t),9007199254740991):0}},"9e1e":function(t,e,n){t.exports=!n("79e5")(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},a481:function(t,e,n){n("214f")("replace",2,function(t,e,n){return[function(r,i){"use strict";var o=t(this),a=void 0==r?void 0:r[e];return void 0!==a?a.call(r,o,i):n.call(String(o),r,i)},n]})},aa77:function(t,e,n){var r=n("5ca1"),i=n("be13"),o=n("79e5"),a=n("fdef"),u="["+a+"]",c="​…",s=RegExp("^"+u+u+"*"),f=RegExp(u+u+"*$"),p=function(t,e,n){var i={},u=o(function(){return!!a[t]()||c[t]()!=c}),s=i[t]=u?e(l):a[t];n&&(i[n]=s),r(r.P+r.F*u,"String",i)},l=p.trim=function(t,e){return t=String(i(t)),1&e&&(t=t.replace(s,"")),2&e&&(t=t.replace(f,"")),t};t.exports=p},aae3:function(t,e,n){var r=n("d3f4"),i=n("2d95"),o=n("2b4c")("match");t.exports=function(t){var e;return r(t)&&(void 0!==(e=t[o])?!!e:"RegExp"==i(t))}},be13:function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},c366:function(t,e,n){var r=n("6821"),i=n("9def"),o=n("77f1");t.exports=function(t){return function(e,n,a){var u,c=r(e),s=i(c.length),f=o(a,s);if(t&&n!=n){while(s>f)if(u=c[f++],u!=u)return!0}else for(;s>f;f++)if((t||f in c)&&c[f]===n)return t||f||0;return!t&&-1}}},c5f6:function(t,e,n){"use strict";var r=n("7726"),i=n("69a8"),o=n("2d95"),a=n("5dbc"),u=n("6a99"),c=n("79e5"),s=n("9093").f,f=n("11e9").f,p=n("86cc").f,l=n("aa77").trim,d="Number",h=r[d],v=h,b=h.prototype,y=o(n("2aeb")(b))==d,_="trim"in String.prototype,g=function(t){var e=u(t,!1);if("string"==typeof e&&e.length>2){e=_?e.trim():l(e,3);var n,r,i,o=e.charCodeAt(0);if(43===o||45===o){if(n=e.charCodeAt(2),88===n||120===n)return NaN}else if(48===o){switch(e.charCodeAt(1)){case 66:case 98:r=2,i=49;break;case 79:case 111:r=8,i=55;break;default:return+e}for(var a,c=e.slice(2),s=0,f=c.length;si)return NaN;return parseInt(c,r)}}return+e};if(!h(" 0o1")||!h("0b1")||h("+0x1")){h=function(t){var e=arguments.length<1?0:t,n=this;return n instanceof h&&(y?c(function(){b.valueOf.call(n)}):o(n)!=d)?a(new v(g(e)),n,h):g(e)};for(var m,x=n("9e1e")?s(v):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),w=0;x.length>w;w++)i(v,m=x[w])&&!i(h,m)&&p(h,m,f(v,m));h.prototype=b,b.constructor=h,n("2aba")(r,d,h)}},c69a:function(t,e,n){t.exports=!n("9e1e")&&!n("79e5")(function(){return 7!=Object.defineProperty(n("230e")("div"),"a",{get:function(){return 7}}).a})},c8ba:function(t,e){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(t){"object"===typeof window&&(n=window)}t.exports=n},ca5a:function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},cb7c:function(t,e,n){var r=n("d3f4");t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},ce10:function(t,e,n){var r=n("69a8"),i=n("6821"),o=n("c366")(!1),a=n("613b")("IE_PROTO");t.exports=function(t,e){var n,u=i(t),c=0,s=[];for(n in u)n!=a&&r(u,n)&&s.push(n);while(e.length>c)r(u,n=e[c++])&&(~o(s,n)||s.push(n));return s}},d3f4:function(t,e){t.exports=function(t){return"object"===typeof t?null!==t:"function"===typeof t}},d8e8:function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},e11e:function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},fab2:function(t,e,n){var r=n("7726").document;t.exports=r&&r.documentElement},fb15:function(t,e,n){"use strict";n.r(e);n("1eb2");var r=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("div",{class:t.sizeClasses},[t.$slots.prepend||t.prepend?n("div",{ref:"prependDiv",staticClass:"input-group-prepend"},[t._t("prepend",[n("span",{staticClass:"input-group-text"},[t._v(t._s(t.prepend))])])],2):t._e(),n("input",{ref:"input",class:"form-control "+t.inputClass,attrs:{type:"search",placeholder:t.placeholder,"aria-label":t.placeholder,autocomplete:"off"},domProps:{value:t.inputValue},on:{focus:function(e){t.isFocused=!0},blur:t.handleBlur,input:function(e){t.handleInput(e.target.value)}}}),t.$slots.append||t.append?n("div",{staticClass:"input-group-append"},[t._t("append",[n("span",{staticClass:"input-group-text"},[t._v(t._s(t.append))])])],2):t._e()]),n("vue-bootstrap-typeahead-list",{directives:[{name:"show",rawName:"v-show",value:t.isFocused&&t.data.length>0,expression:"isFocused && data.length > 0"}],ref:"list",staticClass:"vbt-autcomplete-list",attrs:{query:t.inputValue,data:t.formattedData,"background-variant":t.backgroundVariant,"text-variant":t.textVariant,maxMatches:t.maxMatches,minMatchingChars:t.minMatchingChars},on:{hit:t.handleHit},scopedSlots:t._u([t._l(t.$scopedSlots,function(e,n){return{key:n,fn:function(e){var r=e.data,i=e.htmlText;return[t._t(n,null,null,{data:r,htmlText:i})]}}})])})],1)},i=[],o=(n("c5f6"),function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"list-group shadow"},t._l(t.matchedItems,function(e,r){return n("vue-bootstrap-typeahead-list-item",{key:r,attrs:{data:e.data,"html-text":t.highlight(e.text),"background-variant":t.backgroundVariant,"text-variant":t.textVariant},nativeOn:{click:function(n){t.handleHit(e,n)}},scopedSlots:t._u([{key:"suggestion",fn:function(e){var n=e.data,r=e.htmlText;return t.$scopedSlots.suggestion?[t._t("suggestion",null,null,{data:n,htmlText:r})]:void 0}}])})}))}),a=[],u=(n("4917"),n("55dd"),n("3b2b"),n("a481"),function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("a",{class:t.textClasses,attrs:{tabindex:"0",href:"#"},on:{mouseover:function(e){t.active=!0},mouseout:function(e){t.active=!1}}},[t._t("suggestion",[n("span",{domProps:{innerHTML:t._s(t.htmlText)}})],null,{data:t.data,htmlText:t.htmlText})],2)}),c=[],s={name:"VueBootstrapTypeaheadListItem",props:{data:{},htmlText:{type:String},backgroundVariant:{type:String},textVariant:{type:String}},data:function(){return{active:!1}},computed:{textClasses:function(){var t="";return t+=this.active?"active":"",t+=this.backgroundVariant?" bg-".concat(this.backgroundVariant):"",t+=this.textVariant?" text-".concat(this.textVariant):"","vbst-item list-group-item list-group-item-action ".concat(t)}}},f=s;function p(t,e,n,r,i,o,a,u){var c,s="function"===typeof t?t.options:t;if(e&&(s.render=e,s.staticRenderFns=n,s._compiled=!0),r&&(s.functional=!0),o&&(s._scopeId="data-v-"+o),a?(c=function(t){t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,t||"undefined"===typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),i&&i.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(a)},s._ssrRegister=c):i&&(c=u?function(){i.call(this,this.$root.$options.shadowRoot)}:i),c)if(s.functional){s._injectStyles=c;var f=s.render;s.render=function(t,e){return c.call(e),f(t,e)}}else{var p=s.beforeCreate;s.beforeCreate=p?[].concat(p,c):[c]}return{exports:t,options:s}}var l=p(f,u,c,!1,null,null,null);l.options.__file="VueBootstrapTypeaheadListItem.vue";var d=l.exports;function h(t){return t.replace(//g,">")}function v(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var b={name:"VueBootstrapTypeaheadList",components:{VueBootstrapTypeaheadListItem:d},props:{data:{type:Array,required:!0,validator:function(t){return t instanceof Array}},query:{type:String,default:""},backgroundVariant:{type:String},textVariant:{type:String},maxMatches:{type:Number,default:10},minMatchingChars:{type:Number,default:2}},computed:{highlight:function(){var t=this;return function(e){if(e=h(e),0===t.query.length)return e;var n=new RegExp(t.escapedQuery,"gi");return e.replace(n,"$&")}},escapedQuery:function(){return v(h(this.query))},matchedItems:function(){if(0===this.query.length||this.query.lengthi?1:0}).slice(0,this.maxMatches)}},methods:{handleHit:function(t,e){this.$emit("hit",t),e.preventDefault()}}},y=b,_=p(y,o,a,!1,null,null,null);_.options.__file="VueBootstrapTypeaheadList.vue";var g=_.exports,m=n("6dd8"),x={name:"VueBootstrapTypehead",components:{VueBootstrapTypeaheadList:g},props:{size:{type:String,default:null,validator:function(t){return["lg","sm"].indexOf(t)>-1}},value:{type:String},data:{type:Array,required:!0,validator:function(t){return t instanceof Array}},serializer:{type:Function,default:function(t){return t},validator:function(t){return t instanceof Function}},backgroundVariant:String,textVariant:String,inputClass:{type:String,default:""},maxMatches:{type:Number,default:10},minMatchingChars:{type:Number,default:2},placeholder:String,prepend:String,append:String},computed:{sizeClasses:function(){return this.size?"input-group input-group-".concat(this.size):"input-group"},formattedData:function(){var t=this;return this.data instanceof Array?this.data.map(function(e,n){return{id:n,data:e,text:t.serializer(e)}}):[]}},methods:{resizeList:function(t){var e=t.getBoundingClientRect(),n=this.$refs.list.$el.style;if(n.width=e.width+"px",this.$refs.prependDiv){var r=this.$refs.prependDiv.getBoundingClientRect();n.marginLeft=r.width+"px"}},handleHit:function(t){"undefined"!==typeof this.value&&this.$emit("input",t.text),this.inputValue=t.text,this.$emit("hit",t.data),this.$refs.input.blur(),this.isFocused=!1},handleBlur:function(t){var e=t.relatedTarget;e&&e.classList.contains("vbst-item")||(this.isFocused=!1)},handleInput:function(t){this.inputValue=t,"undefined"!==typeof this.value&&this.$emit("input",t)}},data:function(){return{isFocused:!1,inputValue:""}},mounted:function(){var t=this;this.$_ro=new m["a"](function(e){t.resizeList(t.$refs.input)}),this.$_ro.observe(this.$refs.input),this.$_ro.observe(this.$refs.list.$el)},beforeDestroy:function(){this.$_ro.disconnect()}},w=x,O=(n("892a"),p(w,r,i,!1,null,"48792d67",null));O.options.__file="VueBootstrapTypeahead.vue";var E=O.exports;e["default"]=E},fdef:function(t,e){t.exports="\t\n\v\f\r   ᠎              \u2028\u2029\ufeff"}})["default"]}); +//# sourceMappingURL=VueBootstrapTypeahead.umd.min.js.map \ No newline at end of file diff --git a/prog/gameLibs/webui/plugins/webView/vue/vendor/vue-bootstrap.js b/prog/gameLibs/webui/plugins/webView/vue/vendor/vue-bootstrap.js new file mode 100644 index 000000000..e45ccf940 --- /dev/null +++ b/prog/gameLibs/webui/plugins/webView/vue/vendor/vue-bootstrap.js @@ -0,0 +1,30803 @@ +/*! + * BootstrapVue 2.23.1 + * + * @link https://bootstrap-vue.org + * @source https://github.com/bootstrap-vue/bootstrap-vue + * @copyright (c) 2016-2022 BootstrapVue + * @license MIT + * https://github.com/bootstrap-vue/bootstrap-vue/blob/master/LICENSE + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue')) : + typeof define === 'function' && define.amd ? define(['vue'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrapVue = factory(global.Vue)); +}(this, (function (Vue) { 'use strict'; + + function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + + var Vue__default = /*#__PURE__*/_interopDefaultLegacy(Vue); + + function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + enumerableOnly && (symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + })), keys.push.apply(keys, symbols); + } + + return keys; + } + + function _objectSpread2$3(target) { + for (var i = 1; i < arguments.length; i++) { + var source = null != arguments[i] ? arguments[i] : {}; + i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { + _defineProperty(target, key, source[key]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + + return target; + } + + function _typeof$1(obj) { + "@babel/helpers - typeof"; + + return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }, _typeof$1(obj); + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + Object.defineProperty(Constructor, "prototype", { + writable: false + }); + return Constructor; + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function"); + } + + Object.defineProperty(subClass, "prototype", { + value: Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + writable: true, + configurable: true + } + }), + writable: false + }); + if (superClass) _setPrototypeOf(subClass, superClass); + } + + function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + + return _setPrototypeOf(o, p); + } + + function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) return false; + if (Reflect.construct.sham) return false; + if (typeof Proxy === "function") return true; + + try { + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); + return true; + } catch (e) { + return false; + } + } + + function _construct(Parent, args, Class) { + if (_isNativeReflectConstruct()) { + _construct = Reflect.construct; + } else { + _construct = function _construct(Parent, args, Class) { + var a = [null]; + a.push.apply(a, args); + var Constructor = Function.bind.apply(Parent, a); + var instance = new Constructor(); + if (Class) _setPrototypeOf(instance, Class.prototype); + return instance; + }; + } + + return _construct.apply(null, arguments); + } + + function _isNativeFunction(fn) { + return Function.toString.call(fn).indexOf("[native code]") !== -1; + } + + function _wrapNativeSuper(Class) { + var _cache = typeof Map === "function" ? new Map() : undefined; + + _wrapNativeSuper = function _wrapNativeSuper(Class) { + if (Class === null || !_isNativeFunction(Class)) return Class; + + if (typeof Class !== "function") { + throw new TypeError("Super expression must either be null or a function"); + } + + if (typeof _cache !== "undefined") { + if (_cache.has(Class)) return _cache.get(Class); + + _cache.set(Class, Wrapper); + } + + function Wrapper() { + return _construct(Class, arguments, _getPrototypeOf(this).constructor); + } + + Wrapper.prototype = Object.create(Class.prototype, { + constructor: { + value: Wrapper, + enumerable: false, + writable: true, + configurable: true + } + }); + return _setPrototypeOf(Wrapper, Class); + }; + + return _wrapNativeSuper(Class); + } + + function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; + } + + function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } + } + + return target; + } + + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return self; + } + + function _possibleConstructorReturn(self, call) { + if (call && (typeof call === "object" || typeof call === "function")) { + return call; + } else if (call !== void 0) { + throw new TypeError("Derived constructors may only return object or undefined"); + } + + return _assertThisInitialized(self); + } + + function _createSuper(Derived) { + var hasNativeReflectConstruct = _isNativeReflectConstruct(); + + return function _createSuperInternal() { + var Super = _getPrototypeOf(Derived), + result; + + if (hasNativeReflectConstruct) { + var NewTarget = _getPrototypeOf(this).constructor; + + result = Reflect.construct(Super, arguments, NewTarget); + } else { + result = Super.apply(this, arguments); + } + + return _possibleConstructorReturn(this, result); + }; + } + + function _superPropBase(object, property) { + while (!Object.prototype.hasOwnProperty.call(object, property)) { + object = _getPrototypeOf(object); + if (object === null) break; + } + + return object; + } + + function _get() { + if (typeof Reflect !== "undefined" && Reflect.get) { + _get = Reflect.get; + } else { + _get = function _get(target, property, receiver) { + var base = _superPropBase(target, property); + + if (!base) return; + var desc = Object.getOwnPropertyDescriptor(base, property); + + if (desc.get) { + return desc.get.call(arguments.length < 3 ? target : receiver); + } + + return desc.value; + }; + } + + return _get.apply(this, arguments); + } + + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); + } + + function _toConsumableArray$1(arr) { + return _arrayWithoutHoles$1(arr) || _iterableToArray$1(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread$1(); + } + + function _arrayWithoutHoles$1(arr) { + if (Array.isArray(arr)) return _arrayLikeToArray(arr); + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArray$1(iter) { + if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); + } + + function _iterableToArrayLimit(arr, i) { + var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; + + if (_i == null) return; + var _arr = []; + var _n = true; + var _d = false; + + var _s, _e; + + try { + for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; + } + + function _nonIterableSpread$1() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + var e=function(){return (e=Object.assign||function(e){for(var t,r=1,s=arguments.length;r 0; + /msie|trident/.test(USER_AGENT); // Determine if the browser supports the option passive for events + + var HAS_PASSIVE_EVENT_SUPPORT = function () { + var passiveEventSupported = false; + + if (IS_BROWSER) { + try { + var options = { + // This function will be called when the browser + // attempts to access the passive property + get passive() { + /* istanbul ignore next: will never be called in JSDOM */ + passiveEventSupported = true; + } + + }; + WINDOW.addEventListener('test', options, options); + WINDOW.removeEventListener('test', options, options); + } catch (_unused) { + /* istanbul ignore next: will never be called in JSDOM */ + passiveEventSupported = false; + } + } + + return passiveEventSupported; + }(); + var HAS_TOUCH_SUPPORT = IS_BROWSER && ('ontouchstart' in DOCUMENT.documentElement || NAVIGATOR.maxTouchPoints > 0); + var HAS_POINTER_EVENT_SUPPORT = IS_BROWSER && Boolean(WINDOW.PointerEvent || WINDOW.MSPointerEvent); + /* istanbul ignore next: JSDOM only checks for 'IntersectionObserver' */ + + var HAS_INTERACTION_OBSERVER_SUPPORT = IS_BROWSER && 'IntersectionObserver' in WINDOW && 'IntersectionObserverEntry' in WINDOW && // Edge 15 and UC Browser lack support for `isIntersecting` + // but we an use `intersectionRatio > 0` instead + // 'isIntersecting' in window.IntersectionObserverEntry.prototype && + 'intersectionRatio' in WINDOW.IntersectionObserverEntry.prototype; + + var NAME$2 = 'BvConfig'; + var PROP_NAME$2 = '$bvConfig'; + var DEFAULT_BREAKPOINT = ['xs', 'sm', 'md', 'lg', 'xl']; + + // --- General --- + var RX_ARRAY_NOTATION = /\[(\d+)]/g; + var RX_BV_PREFIX = /^(BV?)/; + var RX_DIGITS = /^\d+$/; + var RX_EXTENSION = /^\..+/; + var RX_HASH = /^#/; + var RX_HASH_ID = /^#[A-Za-z]+[\w\-:.]*$/; + var RX_HTML_TAGS = /(<([^>]+)>)/gi; + var RX_HYPHENATE = /\B([A-Z])/g; + var RX_LOWER_UPPER = /([a-z])([A-Z])/g; + var RX_NUMBER = /^[0-9]*\.?[0-9]+$/; + var RX_PLUS = /\+/g; + var RX_REGEXP_REPLACE = /[-/\\^$*+?.()|[\]{}]/g; + var RX_SPACES = /[\s\uFEFF\xA0]+/g; + var RX_SPACE_SPLIT = /\s+/; + var RX_STAR = /\/\*$/; + var RX_START_SPACE_WORD = /(\s|^)(\w)/g; + var RX_TRIM_LEFT = /^\s+/; + var RX_UNDERSCORE = /_/g; + var RX_UN_KEBAB = /-(\w)/g; // --- Date --- + // Loose YYYY-MM-DD matching, ignores any appended time inforation + // Matches '1999-12-20', '1999-1-1', '1999-01-20T22:51:49.118Z', '1999-01-02 13:00:00' + + var RX_DATE = /^\d+-\d\d?-\d\d?(?:\s|T|$)/; // Used to split off the date parts of the YYYY-MM-DD string + + var RX_DATE_SPLIT = /-|\s|T/; // Time string RegEx (optional seconds) + + var RX_TIME = /^([0-1]?[0-9]|2[0-3]):[0-5]?[0-9](:[0-5]?[0-9])?$/; // --- URL --- + // HREFs must end with a hash followed by at least one non-hash character + + var RX_HREF = /^.*(#[^#]+)$/; + var RX_ENCODED_COMMA = /%2C/g; + var RX_ENCODE_REVERSE = /[!'()*]/g; + var RX_QUERY_START = /^(\?|#|&)/; // --- Aspect --- + + var RX_ASPECT = /^\d+(\.\d*)?[/:]\d+(\.\d*)?$/; + var RX_ASPECT_SEPARATOR = /[/:]/; // --- Grid --- + + var RX_COL_CLASS = /^col-/; // --- Icon --- + + var RX_ICON_PREFIX = /^BIcon/; // --- Locale --- + + var RX_STRIP_LOCALE_MODS = /-u-.+/; + + /* istanbul ignore next */ + + var Element = HAS_WINDOW_SUPPORT ? WINDOW.Element : /*#__PURE__*/function (_Object) { + _inherits(Element, _Object); + + var _super = _createSuper(Element); + + function Element() { + _classCallCheck(this, Element); + + return _super.apply(this, arguments); + } + + return Element; + }( /*#__PURE__*/_wrapNativeSuper(Object)); + /* istanbul ignore next */ + + var HTMLElement = HAS_WINDOW_SUPPORT ? WINDOW.HTMLElement : /*#__PURE__*/function (_Element) { + _inherits(HTMLElement, _Element); + + var _super2 = _createSuper(HTMLElement); + + function HTMLElement() { + _classCallCheck(this, HTMLElement); + + return _super2.apply(this, arguments); + } + + return HTMLElement; + }(Element); + /* istanbul ignore next */ + + var SVGElement = HAS_WINDOW_SUPPORT ? WINDOW.SVGElement : /*#__PURE__*/function (_Element2) { + _inherits(SVGElement, _Element2); + + var _super3 = _createSuper(SVGElement); + + function SVGElement() { + _classCallCheck(this, SVGElement); + + return _super3.apply(this, arguments); + } + + return SVGElement; + }(Element); + /* istanbul ignore next */ + + var File = HAS_WINDOW_SUPPORT ? WINDOW.File : /*#__PURE__*/function (_Object2) { + _inherits(File, _Object2); + + var _super4 = _createSuper(File); + + function File() { + _classCallCheck(this, File); + + return _super4.apply(this, arguments); + } + + return File; + }( /*#__PURE__*/_wrapNativeSuper(Object)); + + var toType$1 = function toType(value) { + return _typeof$1(value); + }; + var toRawType = function toRawType(value) { + return Object.prototype.toString.call(value).slice(8, -1); + }; + var isUndefined = function isUndefined(value) { + return value === undefined; + }; + var isNull = function isNull(value) { + return value === null; + }; + var isUndefinedOrNull = function isUndefinedOrNull(value) { + return isUndefined(value) || isNull(value); + }; + var isFunction$1 = function isFunction(value) { + return toType$1(value) === 'function'; + }; + var isBoolean = function isBoolean(value) { + return toType$1(value) === 'boolean'; + }; + var isString = function isString(value) { + return toType$1(value) === 'string'; + }; + var isNumber = function isNumber(value) { + return toType$1(value) === 'number'; + }; + var isNumeric$1 = function isNumeric(value) { + return RX_NUMBER.test(String(value)); + }; + var isArray = function isArray(value) { + return Array.isArray(value); + }; // Quick object check + // This is primarily used to tell Objects from primitive values + // when we know the value is a JSON-compliant type + // Note object could be a complex type like array, Date, etc. + + var isObject = function isObject(obj) { + return obj !== null && _typeof$1(obj) === 'object'; + }; // Strict object type check + // Only returns true for plain JavaScript objects + + var isPlainObject = function isPlainObject(obj) { + return Object.prototype.toString.call(obj) === '[object Object]'; + }; + var isDate = function isDate(value) { + return value instanceof Date; + }; + var isEvent = function isEvent(value) { + return value instanceof Event; + }; + var isFile = function isFile(value) { + return value instanceof File; + }; + var isRegExp = function isRegExp(value) { + return toRawType(value) === 'RegExp'; + }; + var isPromise = function isPromise(value) { + return !isUndefinedOrNull(value) && isFunction$1(value.then) && isFunction$1(value.catch); + }; + + var assign = function assign() { + return Object.assign.apply(Object, arguments); + }; + var create = function create(proto, optionalProps) { + return Object.create(proto, optionalProps); + }; + var defineProperties = function defineProperties(obj, props) { + return Object.defineProperties(obj, props); + }; + var defineProperty$1 = function defineProperty(obj, prop, descriptor) { + return Object.defineProperty(obj, prop, descriptor); + }; + var getOwnPropertyNames = function getOwnPropertyNames(obj) { + return Object.getOwnPropertyNames(obj); + }; + var keys = function keys(obj) { + return Object.keys(obj); + }; // --- "Instance" --- + + var hasOwnProperty = function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); + }; + var toString$1 = function toString(obj) { + return Object.prototype.toString.call(obj); + }; // --- Utilities --- + // Shallow copy an object + + var clone = function clone(obj) { + return _objectSpread2$3({}, obj); + }; // Return a shallow copy of object with the specified properties only + // See: https://gist.github.com/bisubus/2da8af7e801ffd813fab7ac221aa7afc + + var pick$1 = function pick(obj, props) { + return keys(obj).filter(function (key) { + return props.indexOf(key) !== -1; + }).reduce(function (result, key) { + return _objectSpread2$3(_objectSpread2$3({}, result), {}, _defineProperty({}, key, obj[key])); + }, {}); + }; // Return a shallow copy of object with the specified properties omitted + // See: https://gist.github.com/bisubus/2da8af7e801ffd813fab7ac221aa7afc + + var omit = function omit(obj, props) { + return keys(obj).filter(function (key) { + return props.indexOf(key) === -1; + }).reduce(function (result, key) { + return _objectSpread2$3(_objectSpread2$3({}, result), {}, _defineProperty({}, key, obj[key])); + }, {}); + }; // Merges two object deeply together + // See: https://gist.github.com/Salakar/1d7137de9cb8b704e48a + + var mergeDeep = function mergeDeep(target, source) { + if (isObject(target) && isObject(source)) { + keys(source).forEach(function (key) { + if (isObject(source[key])) { + if (!target[key] || !isObject(target[key])) { + target[key] = source[key]; + } + + mergeDeep(target[key], source[key]); + } else { + assign(target, _defineProperty({}, key, source[key])); + } + }); + } + + return target; + }; // Returns a shallow copy of the object with keys in sorted order + + var sortKeys = function sortKeys(obj) { + return keys(obj).sort().reduce(function (result, key) { + return _objectSpread2$3(_objectSpread2$3({}, result), {}, _defineProperty({}, key, obj[key])); + }, {}); + }; // Convenience method to create a read-only descriptor + + var readonlyDescriptor = function readonlyDescriptor() { + return { + enumerable: true, + configurable: false, + writable: false + }; + }; + + var cloneDeep = function cloneDeep(obj) { + var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : obj; + + if (isArray(obj)) { + return obj.reduce(function (result, val) { + return [].concat(_toConsumableArray$1(result), [cloneDeep(val, val)]); + }, []); + } + + if (isPlainObject(obj)) { + return keys(obj).reduce(function (result, key) { + return _objectSpread2$3(_objectSpread2$3({}, result), {}, _defineProperty({}, key, cloneDeep(obj[key], obj[key]))); + }, {}); + } + + return defaultValue; + }; + + var identity = function identity(x) { + return x; + }; + + /** + * Get property defined by dot/array notation in string, returns undefined if not found + * + * @link https://gist.github.com/jeneg/9767afdcca45601ea44930ea03e0febf#gistcomment-1935901 + * + * @param {Object} obj + * @param {string|Array} path + * @return {*} + */ + + var getRaw = function getRaw(obj, path) { + var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; + // Handle array of path values + path = isArray(path) ? path.join('.') : path; // If no path or no object passed + + if (!path || !isObject(obj)) { + return defaultValue; + } // Handle edge case where user has dot(s) in top-level item field key + // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2762 + // Switched to `in` operator vs `hasOwnProperty` to handle obj.prototype getters + // https://github.com/bootstrap-vue/bootstrap-vue/issues/3463 + + + if (path in obj) { + return obj[path]; + } // Handle string array notation (numeric indices only) + + + path = String(path).replace(RX_ARRAY_NOTATION, '.$1'); + var steps = path.split('.').filter(identity); // Handle case where someone passes a string of only dots + + if (steps.length === 0) { + return defaultValue; + } // Traverse path in object to find result + // Switched to `in` operator vs `hasOwnProperty` to handle obj.prototype getters + // https://github.com/bootstrap-vue/bootstrap-vue/issues/3463 + + + return steps.every(function (step) { + return isObject(obj) && step in obj && !isUndefinedOrNull(obj = obj[step]); + }) ? obj : isNull(obj) ? null : defaultValue; + }; + /** + * Get property defined by dot/array notation in string. + * + * @link https://gist.github.com/jeneg/9767afdcca45601ea44930ea03e0febf#gistcomment-1935901 + * + * @param {Object} obj + * @param {string|Array} path + * @param {*} defaultValue (optional) + * @return {*} + */ + + var get = function get(obj, path) { + var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var value = getRaw(obj, path); + return isUndefinedOrNull(value) ? defaultValue : value; + }; + + /** + * Utilities to get information about the current environment + */ + var getEnv = function getEnv(key) { + var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var env = typeof process !== 'undefined' && process ? process.env || {} : {}; + + if (!key) { + /* istanbul ignore next */ + return env; + } + + return env[key] || fallback; + }; + var getNoWarn = function getNoWarn() { + return getEnv('BOOTSTRAP_VUE_NO_WARN') || getEnv('NODE_ENV') === 'production'; + }; + + /** + * Log a warning message to the console with BootstrapVue formatting + * @param {string} message + */ + + var warn = function warn(message) + /* istanbul ignore next */ + { + var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + if (!getNoWarn()) { + console.warn("[BootstrapVue warn]: ".concat(source ? "".concat(source, " - ") : '').concat(message)); + } + }; + /** + * Warn when no Promise support is given + * @param {string} source + * @returns {boolean} warned + */ + + var warnNotClient = function warnNotClient(source) { + /* istanbul ignore else */ + if (IS_BROWSER) { + return false; + } else { + warn("".concat(source, ": Can not be called during SSR.")); + return true; + } + }; + /** + * Warn when no Promise support is given + * @param {string} source + * @returns {boolean} warned + */ + + var warnNoPromiseSupport = function warnNoPromiseSupport(source) { + /* istanbul ignore else */ + if (HAS_PROMISE_SUPPORT) { + return false; + } else { + warn("".concat(source, ": Requires Promise support.")); + return true; + } + }; + /** + * Warn when no MutationObserver support is given + * @param {string} source + * @returns {boolean} warned + */ + + var warnNoMutationObserverSupport = function warnNoMutationObserverSupport(source) { + /* istanbul ignore else */ + if (HAS_MUTATION_OBSERVER_SUPPORT) { + return false; + } else { + warn("".concat(source, ": Requires MutationObserver support.")); + return true; + } + }; + + var BvConfig = /*#__PURE__*/function () { + function BvConfig() { + _classCallCheck(this, BvConfig); + + this.$_config = {}; + } // Method to merge in user config parameters + + + _createClass(BvConfig, [{ + key: "setConfig", + value: function setConfig() { + var _this = this; + + var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + /* istanbul ignore next */ + if (!isPlainObject(config)) { + return; + } + + var configKeys = getOwnPropertyNames(config); + configKeys.forEach(function (key) { + /* istanbul ignore next */ + var subConfig = config[key]; + + if (key === 'breakpoints') { + /* istanbul ignore if */ + if (!isArray(subConfig) || subConfig.length < 2 || subConfig.some(function (b) { + return !isString(b) || b.length === 0; + })) { + warn('"breakpoints" must be an array of at least 2 breakpoint names', NAME$2); + } else { + _this.$_config[key] = cloneDeep(subConfig); + } + } else if (isPlainObject(subConfig)) { + // Component prop defaults + _this.$_config[key] = getOwnPropertyNames(subConfig).reduce(function (config, prop) { + if (!isUndefined(subConfig[prop])) { + config[prop] = cloneDeep(subConfig[prop]); + } + + return config; + }, _this.$_config[key] || {}); + } + }); + } // Clear the config + + }, { + key: "resetConfig", + value: function resetConfig() { + this.$_config = {}; + } // Returns a deep copy of the user config + + }, { + key: "getConfig", + value: function getConfig() { + return cloneDeep(this.$_config); + } // Returns a deep copy of the config value + + }, { + key: "getConfigValue", + value: function getConfigValue(key) { + var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + return cloneDeep(getRaw(this.$_config, key, defaultValue)); + } + }]); + + return BvConfig; + }(); // Method for applying a global config + + + var setConfig = function setConfig() { + var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var Vue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Vue__default['default']; + // Ensure we have a `$bvConfig` Object on the Vue prototype + // We set on Vue and OurVue just in case consumer has not set an alias of `vue` + Vue.prototype[PROP_NAME$2] = Vue__default['default'].prototype[PROP_NAME$2] = Vue.prototype[PROP_NAME$2] || Vue__default['default'].prototype[PROP_NAME$2] || new BvConfig(); // Apply the config values + + Vue.prototype[PROP_NAME$2].setConfig(config); + }; // Method for resetting the user config + + /** + * Checks if there are multiple instances of Vue, and warns (once) about possible issues. + * @param {object} Vue + */ + + var checkMultipleVue = function () { + var checkMultipleVueWarned = false; + var MULTIPLE_VUE_WARNING = ['Multiple instances of Vue detected!', 'You may need to set up an alias for Vue in your bundler config.', 'See: https://bootstrap-vue.org/docs#using-module-bundlers'].join('\n'); + return function (Vue) { + /* istanbul ignore next */ + if (!checkMultipleVueWarned && Vue__default['default'] !== Vue && !IS_JSDOM) { + warn(MULTIPLE_VUE_WARNING); + } + + checkMultipleVueWarned = true; + }; + }(); + /** + * Plugin install factory function. + * @param {object} { components, directives } + * @returns {function} plugin install function + */ + + var installFactory = function installFactory() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + components = _ref.components, + directives = _ref.directives, + plugins = _ref.plugins; + + var install = function install(Vue) { + var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (install.installed) { + /* istanbul ignore next */ + return; + } + + install.installed = true; + checkMultipleVue(Vue); + setConfig(config, Vue); + registerComponents(Vue, components); + registerDirectives(Vue, directives); + registerPlugins(Vue, plugins); + }; + + install.installed = false; + return install; + }; + /** + * Plugin object factory function. + * @param {object} { components, directives, plugins } + * @returns {object} plugin install object + */ + + var pluginFactory = function pluginFactory() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var extend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return _objectSpread2$3(_objectSpread2$3({}, extend), {}, { + install: installFactory(options) + }); + }; + /** + * Load a group of plugins. + * @param {object} Vue + * @param {object} Plugin definitions + */ + + var registerPlugins = function registerPlugins(Vue) { + var plugins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + for (var plugin in plugins) { + if (plugin && plugins[plugin]) { + Vue.use(plugins[plugin]); + } + } + }; + /** + * Load a component. + * @param {object} Vue + * @param {string} Component name + * @param {object} Component definition + */ + + var registerComponent = function registerComponent(Vue, name, def) { + if (Vue && name && def) { + Vue.component(name, def); + } + }; + /** + * Load a group of components. + * @param {object} Vue + * @param {object} Object of component definitions + */ + + var registerComponents = function registerComponents(Vue) { + var components = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + for (var component in components) { + registerComponent(Vue, component, components[component]); + } + }; + /** + * Load a directive. + * @param {object} Vue + * @param {string} Directive name + * @param {object} Directive definition + */ + + var registerDirective = function registerDirective(Vue, name, def) { + if (Vue && name && def) { + // Ensure that any leading V is removed from the + // name, as Vue adds it automatically + Vue.directive(name.replace(/^VB/, 'B'), def); + } + }; + /** + * Load a group of directives. + * @param {object} Vue + * @param {object} Object of directive definitions + */ + + var registerDirectives = function registerDirectives(Vue) { + var directives = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + for (var directive in directives) { + registerDirective(Vue, directive, directives[directive]); + } + }; + /** + * Install plugin if window.Vue available + * @param {object} Plugin definition + */ + + var vueUse = function vueUse(VuePlugin) { + /* istanbul ignore next */ + if (HAS_WINDOW_SUPPORT && window.Vue) { + window.Vue.use(VuePlugin); + } + /* istanbul ignore next */ + + + if (HAS_WINDOW_SUPPORT && VuePlugin.NAME) { + window[VuePlugin.NAME] = VuePlugin; + } + }; + + // Component names + var NAME_ALERT = 'BAlert'; + var NAME_ASPECT = 'BAspect'; + var NAME_AVATAR = 'BAvatar'; + var NAME_AVATAR_GROUP = 'BAvatarGroup'; + var NAME_BADGE = 'BBadge'; + var NAME_BREADCRUMB = 'BBreadcrumb'; + var NAME_BREADCRUMB_ITEM = 'BBreadcrumbItem'; + var NAME_BREADCRUMB_LINK = 'BBreadcrumbLink'; + var NAME_BUTTON = 'BButton'; + var NAME_BUTTON_CLOSE = 'BButtonClose'; + var NAME_BUTTON_GROUP = 'BButtonGroup'; + var NAME_BUTTON_TOOLBAR = 'BButtonToolbar'; + var NAME_CALENDAR = 'BCalendar'; + var NAME_CARD = 'BCard'; + var NAME_CARD_BODY = 'BCardBody'; + var NAME_CARD_FOOTER = 'BCardFooter'; + var NAME_CARD_GROUP = 'BCardGroup'; + var NAME_CARD_HEADER = 'BCardHeader'; + var NAME_CARD_IMG = 'BCardImg'; + var NAME_CARD_IMG_LAZY = 'BCardImgLazy'; + var NAME_CARD_SUB_TITLE = 'BCardSubTitle'; + var NAME_CARD_TEXT = 'BCardText'; + var NAME_CARD_TITLE = 'BCardTitle'; + var NAME_CAROUSEL = 'BCarousel'; + var NAME_CAROUSEL_SLIDE = 'BCarouselSlide'; + var NAME_COL = 'BCol'; + var NAME_COLLAPSE = 'BCollapse'; + var NAME_CONTAINER = 'BContainer'; + var NAME_DROPDOWN = 'BDropdown'; + var NAME_DROPDOWN_DIVIDER = 'BDropdownDivider'; + var NAME_DROPDOWN_FORM = 'BDropdownForm'; + var NAME_DROPDOWN_GROUP = 'BDropdownGroup'; + var NAME_DROPDOWN_HEADER = 'BDropdownHeader'; + var NAME_DROPDOWN_ITEM = 'BDropdownItem'; + var NAME_DROPDOWN_ITEM_BUTTON = 'BDropdownItemButton'; + var NAME_DROPDOWN_TEXT = 'BDropdownText'; + var NAME_EMBED = 'BEmbed'; + var NAME_FORM = 'BForm'; + var NAME_FORM_CHECKBOX = 'BFormCheckbox'; + var NAME_FORM_CHECKBOX_GROUP = 'BFormCheckboxGroup'; + var NAME_FORM_DATALIST = 'BFormDatalist'; + var NAME_FORM_DATEPICKER = 'BFormDatepicker'; + var NAME_FORM_FILE = 'BFormFile'; + var NAME_FORM_GROUP = 'BFormGroup'; + var NAME_FORM_INPUT = 'BFormInput'; + var NAME_FORM_INVALID_FEEDBACK = 'BFormInvalidFeedback'; + var NAME_FORM_RADIO = 'BFormRadio'; + var NAME_FORM_RADIO_GROUP = 'BFormRadioGroup'; + var NAME_FORM_RATING = 'BFormRating'; + var NAME_FORM_ROW = 'BFormRow'; + var NAME_FORM_SELECT = 'BFormSelect'; + var NAME_FORM_SELECT_OPTION = 'BFormSelectOption'; + var NAME_FORM_SELECT_OPTION_GROUP = 'BFormSelectOptionGroup'; + var NAME_FORM_SPINBUTTON = 'BFormSpinbutton'; + var NAME_FORM_TAG = 'BFormTag'; + var NAME_FORM_TAGS = 'BFormTags'; + var NAME_FORM_TEXT = 'BFormText'; + var NAME_FORM_TEXTAREA = 'BFormTextarea'; + var NAME_FORM_TIMEPICKER = 'BFormTimepicker'; + var NAME_FORM_VALID_FEEDBACK = 'BFormValidFeedback'; + var NAME_ICON = 'BIcon'; + var NAME_ICONSTACK = 'BIconstack'; + var NAME_ICON_BASE = 'BIconBase'; + var NAME_IMG = 'BImg'; + var NAME_IMG_LAZY = 'BImgLazy'; + var NAME_INPUT_GROUP = 'BInputGroup'; + var NAME_INPUT_GROUP_ADDON = 'BInputGroupAddon'; + var NAME_INPUT_GROUP_APPEND = 'BInputGroupAppend'; + var NAME_INPUT_GROUP_PREPEND = 'BInputGroupPrepend'; + var NAME_INPUT_GROUP_TEXT = 'BInputGroupText'; + var NAME_JUMBOTRON = 'BJumbotron'; + var NAME_LINK = 'BLink'; + var NAME_LIST_GROUP = 'BListGroup'; + var NAME_LIST_GROUP_ITEM = 'BListGroupItem'; + var NAME_MEDIA = 'BMedia'; + var NAME_MEDIA_ASIDE = 'BMediaAside'; + var NAME_MEDIA_BODY = 'BMediaBody'; + var NAME_MODAL = 'BModal'; + var NAME_MSG_BOX = 'BMsgBox'; + var NAME_NAV = 'BNav'; + var NAME_NAVBAR = 'BNavbar'; + var NAME_NAVBAR_BRAND = 'BNavbarBrand'; + var NAME_NAVBAR_NAV = 'BNavbarNav'; + var NAME_NAVBAR_TOGGLE = 'BNavbarToggle'; + var NAME_NAV_FORM = 'BNavForm'; + var NAME_NAV_ITEM = 'BNavItem'; + var NAME_NAV_ITEM_DROPDOWN = 'BNavItemDropdown'; + var NAME_NAV_TEXT = 'BNavText'; + var NAME_OVERLAY = 'BOverlay'; + var NAME_PAGINATION = 'BPagination'; + var NAME_PAGINATION_NAV = 'BPaginationNav'; + var NAME_POPOVER = 'BPopover'; + var NAME_PROGRESS = 'BProgress'; + var NAME_PROGRESS_BAR = 'BProgressBar'; + var NAME_ROW = 'BRow'; + var NAME_SIDEBAR = 'BSidebar'; + var NAME_SKELETON = 'BSkeleton'; + var NAME_SKELETON_ICON = 'BSkeletonIcon'; + var NAME_SKELETON_IMG = 'BSkeletonImg'; + var NAME_SKELETON_TABLE = 'BSkeletonTable'; + var NAME_SKELETON_WRAPPER = 'BSkeletonWrapper'; + var NAME_SPINNER = 'BSpinner'; + var NAME_TAB = 'BTab'; + var NAME_TABLE = 'BTable'; + var NAME_TABLE_CELL = 'BTableCell'; + var NAME_TABLE_LITE = 'BTableLite'; + var NAME_TABLE_SIMPLE = 'BTableSimple'; + var NAME_TABS = 'BTabs'; + var NAME_TBODY = 'BTbody'; + var NAME_TFOOT = 'BTfoot'; + var NAME_TH = 'BTh'; + var NAME_THEAD = 'BThead'; + var NAME_TIME = 'BTime'; + var NAME_TOAST = 'BToast'; + var NAME_TOASTER = 'BToaster'; + var NAME_TOOLTIP = 'BTooltip'; + var NAME_TR = 'BTr'; // Helper component names + + var NAME_COLLAPSE_HELPER = 'BVCollapse'; + var NAME_FORM_BUTTON_LABEL_CONTROL = 'BVFormBtnLabelControl'; + var NAME_FORM_RATING_STAR = 'BVFormRatingStar'; + var NAME_POPOVER_HELPER = 'BVPopover'; + var NAME_POPOVER_TEMPLATE = 'BVPopoverTemplate'; + var NAME_POPPER = 'BVPopper'; + var NAME_TAB_BUTTON_HELPER = 'BVTabButton'; + var NAME_TOAST_POP = 'BVToastPop'; + var NAME_TOOLTIP_HELPER = 'BVTooltip'; + var NAME_TOOLTIP_TEMPLATE = 'BVTooltipTemplate'; + var NAME_TRANSITION = 'BVTransition'; + var NAME_TRANSPORTER = 'BVTransporter'; + var NAME_TRANSPORTER_TARGET = 'BVTransporterTarget'; + + var EVENT_NAME_ACTIVATE_TAB = 'activate-tab'; + var EVENT_NAME_BLUR = 'blur'; + var EVENT_NAME_CANCEL = 'cancel'; + var EVENT_NAME_CHANGE = 'change'; + var EVENT_NAME_CHANGED = 'changed'; + var EVENT_NAME_CLICK = 'click'; + var EVENT_NAME_CLOSE = 'close'; + var EVENT_NAME_CONTEXT = 'context'; + var EVENT_NAME_CONTEXT_CHANGED = 'context-changed'; + var EVENT_NAME_DESTROYED = 'destroyed'; + var EVENT_NAME_DISABLE = 'disable'; + var EVENT_NAME_DISABLED = 'disabled'; + var EVENT_NAME_DISMISSED = 'dismissed'; + var EVENT_NAME_DISMISS_COUNT_DOWN = 'dismiss-count-down'; + var EVENT_NAME_ENABLE = 'enable'; + var EVENT_NAME_ENABLED = 'enabled'; + var EVENT_NAME_FILTERED = 'filtered'; + var EVENT_NAME_FIRST = 'first'; + var EVENT_NAME_FOCUS = 'focus'; + var EVENT_NAME_FOCUSIN = 'focusin'; + var EVENT_NAME_FOCUSOUT = 'focusout'; + var EVENT_NAME_HEAD_CLICKED = 'head-clicked'; + var EVENT_NAME_HIDDEN = 'hidden'; + var EVENT_NAME_HIDE = 'hide'; + var EVENT_NAME_IMG_ERROR = 'img-error'; + var EVENT_NAME_INPUT = 'input'; + var EVENT_NAME_LAST = 'last'; + var EVENT_NAME_MOUSEENTER = 'mouseenter'; + var EVENT_NAME_MOUSELEAVE = 'mouseleave'; + var EVENT_NAME_NEXT = 'next'; + var EVENT_NAME_OK = 'ok'; + var EVENT_NAME_OPEN = 'open'; + var EVENT_NAME_PAGE_CLICK = 'page-click'; + var EVENT_NAME_PAUSED = 'paused'; + var EVENT_NAME_PREV = 'prev'; + var EVENT_NAME_REFRESH = 'refresh'; + var EVENT_NAME_REFRESHED = 'refreshed'; + var EVENT_NAME_REMOVE = 'remove'; + var EVENT_NAME_ROW_CLICKED = 'row-clicked'; + var EVENT_NAME_ROW_CONTEXTMENU = 'row-contextmenu'; + var EVENT_NAME_ROW_DBLCLICKED = 'row-dblclicked'; + var EVENT_NAME_ROW_HOVERED = 'row-hovered'; + var EVENT_NAME_ROW_MIDDLE_CLICKED = 'row-middle-clicked'; + var EVENT_NAME_ROW_SELECTED = 'row-selected'; + var EVENT_NAME_ROW_UNHOVERED = 'row-unhovered'; + var EVENT_NAME_SELECTED = 'selected'; + var EVENT_NAME_SHOW = 'show'; + var EVENT_NAME_SHOWN = 'shown'; + var EVENT_NAME_SLIDING_END = 'sliding-end'; + var EVENT_NAME_SLIDING_START = 'sliding-start'; + var EVENT_NAME_SORT_CHANGED = 'sort-changed'; + var EVENT_NAME_TAG_STATE = 'tag-state'; + var EVENT_NAME_TOGGLE = 'toggle'; + var EVENT_NAME_UNPAUSED = 'unpaused'; + var EVENT_NAME_UPDATE = 'update'; + var HOOK_EVENT_NAME_BEFORE_DESTROY = isVue3 ? 'vnodeBeforeUnmount' : 'hook:beforeDestroy'; + var HOOK_EVENT_NAME_DESTROYED = isVue3 ? 'vNodeUnmounted' : 'hook:destroyed'; + var MODEL_EVENT_NAME_PREFIX = 'update:'; + var ROOT_EVENT_NAME_PREFIX = 'bv'; + var ROOT_EVENT_NAME_SEPARATOR = '::'; + var EVENT_OPTIONS_PASSIVE = { + passive: true + }; + var EVENT_OPTIONS_NO_CAPTURE = { + passive: true, + capture: false + }; + + // General types + var PROP_TYPE_ANY = undefined; + var PROP_TYPE_ARRAY = Array; + var PROP_TYPE_BOOLEAN = Boolean; + var PROP_TYPE_DATE = Date; + var PROP_TYPE_FUNCTION = Function; + var PROP_TYPE_NUMBER = Number; + var PROP_TYPE_OBJECT = Object; + var PROP_TYPE_REG_EXP = RegExp; + var PROP_TYPE_STRING = String; // Multiple types + + var PROP_TYPE_ARRAY_FUNCTION = [PROP_TYPE_ARRAY, PROP_TYPE_FUNCTION]; + var PROP_TYPE_ARRAY_OBJECT = [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT]; + var PROP_TYPE_ARRAY_OBJECT_STRING = [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING]; + var PROP_TYPE_ARRAY_STRING = [PROP_TYPE_ARRAY, PROP_TYPE_STRING]; + var PROP_TYPE_BOOLEAN_NUMBER = [PROP_TYPE_BOOLEAN, PROP_TYPE_NUMBER]; + var PROP_TYPE_BOOLEAN_NUMBER_STRING = [PROP_TYPE_BOOLEAN, PROP_TYPE_NUMBER, PROP_TYPE_STRING]; + var PROP_TYPE_BOOLEAN_STRING = [PROP_TYPE_BOOLEAN, PROP_TYPE_STRING]; + var PROP_TYPE_DATE_STRING = [PROP_TYPE_DATE, PROP_TYPE_STRING]; + var PROP_TYPE_FUNCTION_STRING = [PROP_TYPE_FUNCTION, PROP_TYPE_STRING]; + var PROP_TYPE_NUMBER_STRING = [PROP_TYPE_NUMBER, PROP_TYPE_STRING]; + var PROP_TYPE_NUMBER_OBJECT_STRING = [PROP_TYPE_NUMBER, PROP_TYPE_OBJECT, PROP_TYPE_STRING]; + var PROP_TYPE_OBJECT_FUNCTION = [PROP_TYPE_OBJECT, PROP_TYPE_FUNCTION]; + var PROP_TYPE_OBJECT_STRING = [PROP_TYPE_OBJECT, PROP_TYPE_STRING]; + + var SLOT_NAME_ADD_BUTTON_TEXT = 'add-button-text'; + var SLOT_NAME_APPEND = 'append'; + var SLOT_NAME_ASIDE = 'aside'; + var SLOT_NAME_BADGE = 'badge'; + var SLOT_NAME_BOTTOM_ROW = 'bottom-row'; + var SLOT_NAME_BUTTON_CONTENT = 'button-content'; + var SLOT_NAME_CUSTOM_FOOT = 'custom-foot'; + var SLOT_NAME_DECREMENT = 'decrement'; + var SLOT_NAME_DEFAULT = 'default'; + var SLOT_NAME_DESCRIPTION = 'description'; + var SLOT_NAME_DISMISS = 'dismiss'; + var SLOT_NAME_DROP_PLACEHOLDER = 'drop-placeholder'; + var SLOT_NAME_ELLIPSIS_TEXT = 'ellipsis-text'; + var SLOT_NAME_EMPTY = 'empty'; + var SLOT_NAME_EMPTYFILTERED = 'emptyfiltered'; + var SLOT_NAME_FILE_NAME = 'file-name'; + var SLOT_NAME_FIRST = 'first'; + var SLOT_NAME_FIRST_TEXT = 'first-text'; + var SLOT_NAME_FOOTER = 'footer'; + var SLOT_NAME_HEADER = 'header'; + var SLOT_NAME_HEADER_CLOSE = 'header-close'; + var SLOT_NAME_ICON_CLEAR = 'icon-clear'; + var SLOT_NAME_ICON_EMPTY = 'icon-empty'; + var SLOT_NAME_ICON_FULL = 'icon-full'; + var SLOT_NAME_ICON_HALF = 'icon-half'; + var SLOT_NAME_IMG = 'img'; + var SLOT_NAME_INCREMENT = 'increment'; + var SLOT_NAME_INVALID_FEEDBACK = 'invalid-feedback'; + var SLOT_NAME_LABEL = 'label'; + var SLOT_NAME_LAST_TEXT = 'last-text'; + var SLOT_NAME_LEAD = 'lead'; + var SLOT_NAME_LOADING = 'loading'; + var SLOT_NAME_MODAL_BACKDROP = 'modal-backdrop'; + var SLOT_NAME_MODAL_CANCEL = 'modal-cancel'; + var SLOT_NAME_MODAL_FOOTER = 'modal-footer'; + var SLOT_NAME_MODAL_HEADER = 'modal-header'; + var SLOT_NAME_MODAL_HEADER_CLOSE = 'modal-header-close'; + var SLOT_NAME_MODAL_OK = 'modal-ok'; + var SLOT_NAME_MODAL_TITLE = 'modal-title'; + var SLOT_NAME_NAV_NEXT_DECADE = 'nav-next-decade'; + var SLOT_NAME_NAV_NEXT_MONTH = 'nav-next-month'; + var SLOT_NAME_NAV_NEXT_YEAR = 'nav-next-year'; + var SLOT_NAME_NAV_PEV_DECADE = 'nav-prev-decade'; + var SLOT_NAME_NAV_PEV_MONTH = 'nav-prev-month'; + var SLOT_NAME_NAV_PEV_YEAR = 'nav-prev-year'; + var SLOT_NAME_NAV_THIS_MONTH = 'nav-this-month'; + var SLOT_NAME_NEXT_TEXT = 'next-text'; + var SLOT_NAME_OVERLAY = 'overlay'; + var SLOT_NAME_PAGE = 'page'; + var SLOT_NAME_PLACEHOLDER = 'placeholder'; + var SLOT_NAME_PREPEND = 'prepend'; + var SLOT_NAME_PREV_TEXT = 'prev-text'; + var SLOT_NAME_ROW_DETAILS = 'row-details'; + var SLOT_NAME_TABLE_BUSY = 'table-busy'; + var SLOT_NAME_TABLE_CAPTION = 'table-caption'; + var SLOT_NAME_TABLE_COLGROUP = 'table-colgroup'; + var SLOT_NAME_TABS_END = 'tabs-end'; + var SLOT_NAME_TABS_START = 'tabs-start'; + var SLOT_NAME_TEXT = 'text'; + var SLOT_NAME_THEAD_TOP = 'thead-top'; + var SLOT_NAME_TITLE = 'title'; + var SLOT_NAME_TOAST_TITLE = 'toast-title'; + var SLOT_NAME_TOP_ROW = 'top-row'; + var SLOT_NAME_VALID_FEEDBACK = 'valid-feedback'; + + var from = function from() { + return Array.from.apply(Array, arguments); + }; // --- Instance --- + + var arrayIncludes = function arrayIncludes(array, value) { + return array.indexOf(value) !== -1; + }; + var concat = function concat() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return Array.prototype.concat.apply([], args); + }; // --- Utilities --- + + var createArray = function createArray(length, fillFn) { + var mapFn = isFunction$1(fillFn) ? fillFn : function () { + return fillFn; + }; + return Array.apply(null, { + length: length + }).map(mapFn); + }; + var flatten = function flatten(array) { + return array.reduce(function (result, item) { + return concat(result, item); + }, []); + }; + var flattenDeep = function flattenDeep(array) { + return array.reduce(function (result, item) { + return concat(result, Array.isArray(item) ? flattenDeep(item) : item); + }, []); + }; + + // In functional components, `slots` is a function so it must be called + // first before passing to the below methods. `scopedSlots` is always an + // object and may be undefined (for Vue < 2.6.x) + + /** + * Returns true if either scoped or unscoped named slot exists + * + * @param {String, Array} name or name[] + * @param {Object} scopedSlots + * @param {Object} slots + * @returns {Array|undefined} VNodes + */ + + var hasNormalizedSlot = function hasNormalizedSlot(names) { + var $scopedSlots = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var $slots = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + // Ensure names is an array + names = concat(names).filter(identity); // Returns true if the either a $scopedSlot or $slot exists with the specified name + + return names.some(function (name) { + return $scopedSlots[name] || $slots[name]; + }); + }; + /** + * Returns VNodes for named slot either scoped or unscoped + * + * @param {String, Array} name or name[] + * @param {String} scope + * @param {Object} scopedSlots + * @param {Object} slots + * @returns {Array|undefined} VNodes + */ + + var normalizeSlot = function normalizeSlot(names) { + var scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var $scopedSlots = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var $slots = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + // Ensure names is an array + names = concat(names).filter(identity); + var slot; + + for (var i = 0; i < names.length && !slot; i++) { + var name = names[i]; + slot = $scopedSlots[name] || $slots[name]; + } // Note: in Vue 2.6.x, all named slots are also scoped slots + + + return isFunction$1(slot) ? slot(scope) : slot; + }; + + var normalizeSlotMixin = extend({ + methods: { + // Returns `true` if the either a `$scopedSlot` or `$slot` exists with the specified name + // `name` can be a string name or an array of names + hasNormalizedSlot: function hasNormalizedSlot$1() { + var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SLOT_NAME_DEFAULT; + var scopedSlots = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.$scopedSlots; + var slots = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.$slots; + return hasNormalizedSlot(name, scopedSlots, slots); + }, + // Returns an array of rendered VNodes if slot found, otherwise `undefined` + // `name` can be a string name or an array of names + normalizeSlot: function normalizeSlot$1() { + var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SLOT_NAME_DEFAULT; + var scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var scopedSlots = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.$scopedSlots; + var slots = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : this.$slots; + + var vNodes = normalizeSlot(name, scope, scopedSlots, slots); + + return vNodes ? concat(vNodes) : vNodes; + } + } + }); + + // Number utilities + // Converts a value (string, number, etc.) to an integer number + // Assumes radix base 10 + var toInteger = function toInteger(value) { + var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : NaN; + var integer = parseInt(value, 10); + return isNaN(integer) ? defaultValue : integer; + }; // Converts a value (string, number, etc.) to a number + + var toFloat = function toFloat(value) { + var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : NaN; + var float = parseFloat(value); + return isNaN(float) ? defaultValue : float; + }; // Converts a value (string, number, etc.) to a string + // representation with `precision` digits after the decimal + // Returns the string 'NaN' if the value cannot be converted + + var toFixed = function toFixed(val, precision) { + return toFloat(val).toFixed(toInteger(precision, 0)); + }; + + // String utilities + // Converts PascalCase or camelCase to kebab-case + + var kebabCase = function kebabCase(str) { + return str.replace(RX_HYPHENATE, '-$1').toLowerCase(); + }; // Converts a kebab-case or camelCase string to PascalCase + + var pascalCase = function pascalCase(str) { + str = kebabCase(str).replace(RX_UN_KEBAB, function (_, c) { + return c ? c.toUpperCase() : ''; + }); + return str.charAt(0).toUpperCase() + str.slice(1); + }; // Converts a string, including strings in camelCase or snake_case, into Start Case + // It keeps original single quote and hyphen in the word + // https://github.com/UrbanCompass/to-start-case + + var startCase = function startCase(str) { + return str.replace(RX_UNDERSCORE, ' ').replace(RX_LOWER_UPPER, function (str, $1, $2) { + return $1 + ' ' + $2; + }).replace(RX_START_SPACE_WORD, function (str, $1, $2) { + return $1 + $2.toUpperCase(); + }); + }; // Lowercases the first letter of a string and returns a new string + + var lowerFirst = function lowerFirst(str) { + str = isString(str) ? str.trim() : String(str); + return str.charAt(0).toLowerCase() + str.slice(1); + }; // Uppercases the first letter of a string and returns a new string + + var upperFirst = function upperFirst(str) { + str = isString(str) ? str.trim() : String(str); + return str.charAt(0).toUpperCase() + str.slice(1); + }; // Escape characters to be used in building a regular expression + + var escapeRegExp = function escapeRegExp(str) { + return str.replace(RX_REGEXP_REPLACE, '\\$&'); + }; // Convert a value to a string that can be rendered + // `undefined`/`null` will be converted to `''` + // Plain objects and arrays will be JSON stringified + + var toString = function toString(val) { + var spaces = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; + return isUndefinedOrNull(val) ? '' : isArray(val) || isPlainObject(val) && val.toString === Object.prototype.toString ? JSON.stringify(val, null, spaces) : String(val); + }; // Remove leading white space from a string + + var trimLeft = function trimLeft(str) { + return toString(str).replace(RX_TRIM_LEFT, ''); + }; // Remove Trailing white space from a string + + var trim = function trim(str) { + return toString(str).trim(); + }; // Lower case a string + + var lowerCase = function lowerCase(str) { + return toString(str).toLowerCase(); + }; // Upper case a string + + var ELEMENT_PROTO = Element.prototype; + var TABABLE_SELECTOR = ['button', '[href]:not(.disabled)', 'input', 'select', 'textarea', '[tabindex]', '[contenteditable]'].map(function (s) { + return "".concat(s, ":not(:disabled):not([disabled])"); + }).join(', '); // --- Normalization utils --- + // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill + + /* istanbul ignore next */ + + var matchesEl = ELEMENT_PROTO.matches || ELEMENT_PROTO.msMatchesSelector || ELEMENT_PROTO.webkitMatchesSelector; // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest + + /* istanbul ignore next */ + + var closestEl = ELEMENT_PROTO.closest || function (sel) { + var el = this; + + do { + // Use our "patched" matches function + if (matches(el, sel)) { + return el; + } + + el = el.parentElement || el.parentNode; + } while (!isNull(el) && el.nodeType === Node.ELEMENT_NODE); + + return null; + }; // `requestAnimationFrame()` convenience method + + /* istanbul ignore next: JSDOM always returns the first option */ + + var requestAF = (WINDOW.requestAnimationFrame || WINDOW.webkitRequestAnimationFrame || WINDOW.mozRequestAnimationFrame || WINDOW.msRequestAnimationFrame || WINDOW.oRequestAnimationFrame || // Fallback, but not a true polyfill + // Only needed for Opera Mini + + /* istanbul ignore next */ + function (cb) { + return setTimeout(cb, 16); + }).bind(WINDOW); + var MutationObs = WINDOW.MutationObserver || WINDOW.WebKitMutationObserver || WINDOW.MozMutationObserver || null; // --- Utils --- + // Remove a node from DOM + + var removeNode = function removeNode(el) { + return el && el.parentNode && el.parentNode.removeChild(el); + }; // Determine if an element is an HTML element + + var isElement = function isElement(el) { + return !!(el && el.nodeType === Node.ELEMENT_NODE); + }; // Get the currently active HTML element + + var getActiveElement = function getActiveElement() { + var excludes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + var activeElement = DOCUMENT.activeElement; + return activeElement && !excludes.some(function (el) { + return el === activeElement; + }) ? activeElement : null; + }; // Returns `true` if a tag's name equals `name` + + var isTag = function isTag(tag, name) { + return toString(tag).toLowerCase() === toString(name).toLowerCase(); + }; // Determine if an HTML element is the currently active element + + var isActiveElement = function isActiveElement(el) { + return isElement(el) && el === getActiveElement(); + }; // Determine if an HTML element is visible - Faster than CSS check + + var isVisible = function isVisible(el) { + if (!isElement(el) || !el.parentNode || !contains(DOCUMENT.body, el)) { + // Note this can fail for shadow dom elements since they + // are not a direct descendant of document.body + return false; + } + + if (getStyle(el, 'display') === 'none') { + // We do this check to help with vue-test-utils when using v-show + + /* istanbul ignore next */ + return false; + } // All browsers support getBoundingClientRect(), except JSDOM as it returns all 0's for values :( + // So any tests that need isVisible will fail in JSDOM + // Except when we override the getBCR prototype in some tests + + + var bcr = getBCR(el); + return !!(bcr && bcr.height > 0 && bcr.width > 0); + }; // Determine if an element is disabled + + var isDisabled = function isDisabled(el) { + return !isElement(el) || el.disabled || hasAttr(el, 'disabled') || hasClass(el, 'disabled'); + }; // Cause/wait-for an element to reflow its content (adjusting its height/width) + + var reflow = function reflow(el) { + // Requesting an elements offsetHight will trigger a reflow of the element content + + /* istanbul ignore next: reflow doesn't happen in JSDOM */ + return isElement(el) && el.offsetHeight; + }; // Select all elements matching selector. Returns `[]` if none found + + var selectAll = function selectAll(selector, root) { + return from((isElement(root) ? root : DOCUMENT).querySelectorAll(selector)); + }; // Select a single element, returns `null` if not found + + var select = function select(selector, root) { + return (isElement(root) ? root : DOCUMENT).querySelector(selector) || null; + }; // Determine if an element matches a selector + + var matches = function matches(el, selector) { + return isElement(el) ? matchesEl.call(el, selector) : false; + }; // Finds closest element matching selector. Returns `null` if not found + + var closest = function closest(selector, root) { + var includeRoot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + if (!isElement(root)) { + return null; + } + + var el = closestEl.call(root, selector); // Native closest behaviour when `includeRoot` is truthy, + // else emulate jQuery closest and return `null` if match is + // the passed in root element when `includeRoot` is falsey + + return includeRoot ? el : el === root ? null : el; + }; // Returns true if the parent element contains the child element + + var contains = function contains(parent, child) { + return parent && isFunction$1(parent.contains) ? parent.contains(child) : false; + }; // Get an element given an ID + + var getById = function getById(id) { + return DOCUMENT.getElementById(/^#/.test(id) ? id.slice(1) : id) || null; + }; // Add a class to an element + + var addClass = function addClass(el, className) { + // We are checking for `el.classList` existence here since IE 11 + // returns `undefined` for some elements (e.g. SVG elements) + // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2713 + if (className && isElement(el) && el.classList) { + el.classList.add(className); + } + }; // Remove a class from an element + + var removeClass = function removeClass(el, className) { + // We are checking for `el.classList` existence here since IE 11 + // returns `undefined` for some elements (e.g. SVG elements) + // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2713 + if (className && isElement(el) && el.classList) { + el.classList.remove(className); + } + }; // Test if an element has a class + + var hasClass = function hasClass(el, className) { + // We are checking for `el.classList` existence here since IE 11 + // returns `undefined` for some elements (e.g. SVG elements) + // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2713 + if (className && isElement(el) && el.classList) { + return el.classList.contains(className); + } + + return false; + }; // Set an attribute on an element + + var setAttr = function setAttr(el, attr, value) { + if (attr && isElement(el)) { + el.setAttribute(attr, value); + } + }; // Remove an attribute from an element + + var removeAttr = function removeAttr(el, attr) { + if (attr && isElement(el)) { + el.removeAttribute(attr); + } + }; // Get an attribute value from an element + // Returns `null` if not found + + var getAttr = function getAttr(el, attr) { + return attr && isElement(el) ? el.getAttribute(attr) : null; + }; // Determine if an attribute exists on an element + // Returns `true` or `false`, or `null` if element not found + + var hasAttr = function hasAttr(el, attr) { + return attr && isElement(el) ? el.hasAttribute(attr) : null; + }; // Set an style property on an element + + var setStyle = function setStyle(el, prop, value) { + if (prop && isElement(el)) { + el.style[prop] = value; + } + }; // Remove an style property from an element + + var removeStyle = function removeStyle(el, prop) { + if (prop && isElement(el)) { + el.style[prop] = ''; + } + }; // Get an style property value from an element + // Returns `null` if not found + + var getStyle = function getStyle(el, prop) { + return prop && isElement(el) ? el.style[prop] || null : null; + }; // Return the Bounding Client Rect of an element + // Returns `null` if not an element + + /* istanbul ignore next: getBoundingClientRect() doesn't work in JSDOM */ + + var getBCR = function getBCR(el) { + return isElement(el) ? el.getBoundingClientRect() : null; + }; // Get computed style object for an element + + /* istanbul ignore next: getComputedStyle() doesn't work in JSDOM */ + + var getCS = function getCS(el) { + var getComputedStyle = WINDOW.getComputedStyle; + return getComputedStyle && isElement(el) ? getComputedStyle(el) : {}; + }; // Returns a `Selection` object representing the range of text selected + // Returns `null` if no window support is given + + /* istanbul ignore next: getSelection() doesn't work in JSDOM */ + + var getSel = function getSel() { + var getSelection = WINDOW.getSelection; + return getSelection ? WINDOW.getSelection() : null; + }; // Return an element's offset with respect to document element + // https://j11y.io/jquery/#v=git&fn=jQuery.fn.offset + + var offset$1 = function offset(el) + /* istanbul ignore next: getBoundingClientRect(), getClientRects() doesn't work in JSDOM */ + { + var _offset = { + top: 0, + left: 0 + }; + + if (!isElement(el) || el.getClientRects().length === 0) { + return _offset; + } + + var bcr = getBCR(el); + + if (bcr) { + var win = el.ownerDocument.defaultView; + _offset.top = bcr.top + win.pageYOffset; + _offset.left = bcr.left + win.pageXOffset; + } + + return _offset; + }; // Return an element's offset with respect to to its offsetParent + // https://j11y.io/jquery/#v=git&fn=jQuery.fn.position + + var position = function position(el) + /* istanbul ignore next: getBoundingClientRect() doesn't work in JSDOM */ + { + var _offset = { + top: 0, + left: 0 + }; + + if (!isElement(el)) { + return _offset; + } + + var parentOffset = { + top: 0, + left: 0 + }; + var elStyles = getCS(el); + + if (elStyles.position === 'fixed') { + _offset = getBCR(el) || _offset; + } else { + _offset = offset$1(el); + var doc = el.ownerDocument; + var offsetParent = el.offsetParent || doc.documentElement; + + while (offsetParent && (offsetParent === doc.body || offsetParent === doc.documentElement) && getCS(offsetParent).position === 'static') { + offsetParent = offsetParent.parentNode; + } + + if (offsetParent && offsetParent !== el && offsetParent.nodeType === Node.ELEMENT_NODE) { + parentOffset = offset$1(offsetParent); + var offsetParentStyles = getCS(offsetParent); + parentOffset.top += toFloat(offsetParentStyles.borderTopWidth, 0); + parentOffset.left += toFloat(offsetParentStyles.borderLeftWidth, 0); + } + } + + return { + top: _offset.top - parentOffset.top - toFloat(elStyles.marginTop, 0), + left: _offset.left - parentOffset.left - toFloat(elStyles.marginLeft, 0) + }; + }; // Find all tabable elements in the given element + // Assumes users have not used `tabindex` > `0` on elements + + var getTabables = function getTabables() { + var rootEl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; + return selectAll(TABABLE_SELECTOR, rootEl).filter(isVisible).filter(function (el) { + return el.tabIndex > -1 && !el.disabled; + }); + }; // Attempt to focus an element, and return `true` if successful + + var attemptFocus = function attemptFocus(el) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + try { + el.focus(options); + } catch (_unused) {} + + return isActiveElement(el); + }; // Attempt to blur an element, and return `true` if successful + + var attemptBlur = function attemptBlur(el) { + try { + el.blur(); + } catch (_unused2) {} + + return !isActiveElement(el); + }; + + var memoize = function memoize(fn) { + var cache = create(null); + return function () { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + var argsKey = JSON.stringify(args); + return cache[argsKey] = cache[argsKey] || fn.apply(null, args); + }; + }; + + var VueProto = Vue__default['default'].prototype; // --- Getter methods --- + + var getConfigValue = function getConfigValue(key) { + var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + var bvConfig = VueProto[PROP_NAME$2]; + return bvConfig ? bvConfig.getConfigValue(key, defaultValue) : cloneDeep(defaultValue); + }; // Method to grab a config value for a particular component + + var getComponentConfig = function getComponentConfig(key) { + var propKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; + // Return the particular config value for key if specified, + // otherwise we return the full config (or an empty object if not found) + return propKey ? getConfigValue("".concat(key, ".").concat(propKey), defaultValue) : getConfigValue(key, {}); + }; // Get all breakpoint names + + var getBreakpoints = function getBreakpoints() { + return getConfigValue('breakpoints', DEFAULT_BREAKPOINT); + }; // Private method for caching breakpoint names + + var _getBreakpointsCached = memoize(function () { + return getBreakpoints(); + }); // Get all breakpoint names (cached) + + + var getBreakpointsCached = function getBreakpointsCached() { + return cloneDeep(_getBreakpointsCached()); + }; // Get breakpoints with the smallest breakpoint set as '' + // Useful for components that create breakpoint specific props + + var getBreakpointsUpCached = memoize(function () { + var breakpoints = getBreakpointsCached(); + breakpoints[0] = ''; + return breakpoints; + }); // Get breakpoints with the largest breakpoint set as '' + + var prefixPropName = function prefixPropName(prefix, value) { + return prefix + upperFirst(value); + }; // Remove a prefix from a property + + var unprefixPropName = function unprefixPropName(prefix, value) { + return lowerFirst(value.replace(prefix, '')); + }; // Suffix can be a falsey value so nothing is appended to string + // (helps when looping over props & some shouldn't change) + // Use data last parameters to allow for currying + + var suffixPropName = function suffixPropName(suffix, value) { + return value + (suffix ? upperFirst(suffix) : ''); + }; // Generates a prop object + + var makeProp = function makeProp() { + var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : PROP_TYPE_ANY; + var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + var requiredOrValidator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; + var validator = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined; + var required = requiredOrValidator === true; + validator = required ? validator : requiredOrValidator; + return _objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, type ? { + type: type + } : {}), required ? { + required: required + } : isUndefined(value) ? {} : { + default: isObject(value) ? function () { + return value; + } : value + }), isUndefined(validator) ? {} : { + validator: validator + }); + }; // Copies props from one array/object to a new array/object + // Prop values are also cloned as new references to prevent possible + // mutation of original prop object values + // Optionally accepts a function to transform the prop name + + var copyProps = function copyProps(props) { + var transformFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : identity; + + if (isArray(props)) { + return props.map(transformFn); + } + + var copied = {}; + + for (var prop in props) { + /* istanbul ignore else */ + if (hasOwnProperty(props, prop)) { + // If the prop value is an object, do a shallow clone + // to prevent potential mutations to the original object + copied[transformFn(prop)] = isObject(props[prop]) ? clone(props[prop]) : props[prop]; + } + } + + return copied; + }; // Given an array of properties or an object of property keys, + // plucks all the values off the target object, returning a new object + // that has props that reference the original prop values + + var pluckProps = function pluckProps(keysToPluck, objToPluck) { + var transformFn = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : identity; + return (isArray(keysToPluck) ? keysToPluck.slice() : keys(keysToPluck)).reduce(function (memo, prop) { + memo[transformFn(prop)] = objToPluck[prop]; + return memo; + }, {}); + }; // Make a prop object configurable by global configuration + // Replaces the current `default` key of each prop with a `getComponentConfig()` + // call that falls back to the current default value of the prop + + var makePropConfigurable = function makePropConfigurable(prop, key, componentKey) { + return _objectSpread2$3(_objectSpread2$3({}, cloneDeep(prop)), {}, { + default: function bvConfigurablePropDefault() { + var value = getComponentConfig(componentKey, key, prop.default); + return isFunction$1(value) ? value() : value; + } + }); + }; // Make a props object configurable by global configuration + // Replaces the current `default` key of each prop with a `getComponentConfig()` + // call that falls back to the current default value of the prop + + var makePropsConfigurable = function makePropsConfigurable(props, componentKey) { + return keys(props).reduce(function (result, key) { + return _objectSpread2$3(_objectSpread2$3({}, result), {}, _defineProperty({}, key, makePropConfigurable(props[key], key, componentKey))); + }, {}); + }; // Get function name we use in `makePropConfigurable()` + // for the prop default value override to compare + // against in `hasPropFunction()` + + var configurablePropDefaultFnName = makePropConfigurable({}, '', '').default.name; // Detect wether the given value is currently a function + // and isn't the props default function + + var hasPropFunction = function hasPropFunction(fn) { + return isFunction$1(fn) && fn.name && fn.name !== configurablePropDefaultFnName; + }; + + var makeModelMixin = function makeModelMixin(prop) { + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$type = _ref.type, + type = _ref$type === void 0 ? PROP_TYPE_ANY : _ref$type, + _ref$defaultValue = _ref.defaultValue, + defaultValue = _ref$defaultValue === void 0 ? undefined : _ref$defaultValue, + _ref$validator = _ref.validator, + validator = _ref$validator === void 0 ? undefined : _ref$validator, + _ref$event = _ref.event, + event = _ref$event === void 0 ? EVENT_NAME_INPUT : _ref$event; + + var props = _defineProperty({}, prop, makeProp(type, defaultValue, validator)); // @vue/component + + + var mixin = extend({ + model: { + prop: prop, + event: event + }, + props: props + }); + return { + mixin: mixin, + props: props, + prop: prop, + event: event + }; + }; + + // Normalize event options based on support of passive option + // Exported only for testing purposes + + var parseEventOptions = function parseEventOptions(options) { + /* istanbul ignore else: can't test in JSDOM, as it supports passive */ + if (HAS_PASSIVE_EVENT_SUPPORT) { + return isObject(options) ? options : { + capture: !!options || false + }; + } else { + // Need to translate to actual Boolean value + return !!(isObject(options) ? options.capture : options); + } + }; // Attach an event listener to an element + + var eventOn = function eventOn(el, eventName, handler, options) { + if (el && el.addEventListener) { + el.addEventListener(eventName, handler, parseEventOptions(options)); + } + }; // Remove an event listener from an element + + var eventOff = function eventOff(el, eventName, handler, options) { + if (el && el.removeEventListener) { + el.removeEventListener(eventName, handler, parseEventOptions(options)); + } + }; // Utility method to add/remove a event listener based on first argument (boolean) + // It passes all other arguments to the `eventOn()` or `eventOff` method + + var eventOnOff = function eventOnOff(on) { + var method = on ? eventOn : eventOff; + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + method.apply(void 0, args); + }; // Utility method to prevent the default event handling and propagation + + var stopEvent = function stopEvent(event) { + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$preventDefault = _ref.preventDefault, + preventDefault = _ref$preventDefault === void 0 ? true : _ref$preventDefault, + _ref$propagation = _ref.propagation, + propagation = _ref$propagation === void 0 ? true : _ref$propagation, + _ref$immediatePropaga = _ref.immediatePropagation, + immediatePropagation = _ref$immediatePropaga === void 0 ? false : _ref$immediatePropaga; + + if (preventDefault) { + event.preventDefault(); + } + + if (propagation) { + event.stopPropagation(); + } + + if (immediatePropagation) { + event.stopImmediatePropagation(); + } + }; // Helper method to convert a component/directive name to a base event name + // `getBaseEventName('BNavigationItem')` => 'navigation-item' + // `getBaseEventName('BVToggle')` => 'toggle' + + var getBaseEventName = function getBaseEventName(value) { + return kebabCase(value.replace(RX_BV_PREFIX, '')); + }; // Get a root event name by component/directive and event name + // `getBaseEventName('BModal', 'show')` => 'bv::modal::show' + + + var getRootEventName = function getRootEventName(name, eventName) { + return [ROOT_EVENT_NAME_PREFIX, getBaseEventName(name), eventName].join(ROOT_EVENT_NAME_SEPARATOR); + }; // Get a root action event name by component/directive and action name + // `getRootActionEventName('BModal', 'show')` => 'bv::show::modal' + + var getRootActionEventName = function getRootActionEventName(name, actionName) { + return [ROOT_EVENT_NAME_PREFIX, actionName, getBaseEventName(name)].join(ROOT_EVENT_NAME_SEPARATOR); + }; + + var props$2l = makePropsConfigurable({ + ariaLabel: makeProp(PROP_TYPE_STRING, 'Close'), + content: makeProp(PROP_TYPE_STRING, '×'), + disabled: makeProp(PROP_TYPE_BOOLEAN, false), + textVariant: makeProp(PROP_TYPE_STRING) + }, NAME_BUTTON_CLOSE); // --- Main component --- + // @vue/component + + var BButtonClose = /*#__PURE__*/extend({ + name: NAME_BUTTON_CLOSE, + functional: true, + props: props$2l, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + slots = _ref.slots, + scopedSlots = _ref.scopedSlots; + var $slots = slots(); + var $scopedSlots = scopedSlots || {}; + var componentData = { + staticClass: 'close', + class: _defineProperty({}, "text-".concat(props.textVariant), props.textVariant), + attrs: { + type: 'button', + disabled: props.disabled, + 'aria-label': props.ariaLabel ? String(props.ariaLabel) : null + }, + on: { + click: function click(event) { + // Ensure click on button HTML content is also disabled + + /* istanbul ignore if: bug in JSDOM still emits click on inner element */ + if (props.disabled && isEvent(event)) { + stopEvent(event); + } + } + } + }; // Careful not to override the default slot with innerHTML + + if (!hasNormalizedSlot(SLOT_NAME_DEFAULT, $scopedSlots, $slots)) { + componentData.domProps = { + innerHTML: props.content + }; + } + + return h('button', a(data, componentData), normalizeSlot(SLOT_NAME_DEFAULT, {}, $scopedSlots, $slots)); + } + }); + + var NO_FADE_PROPS = { + name: '', + enterClass: '', + enterActiveClass: '', + enterToClass: 'show', + leaveClass: 'show', + leaveActiveClass: '', + leaveToClass: '' + }; + + var FADE_PROPS = _objectSpread2$3(_objectSpread2$3({}, NO_FADE_PROPS), {}, { + enterActiveClass: 'fade', + leaveActiveClass: 'fade' + }); // --- Props --- + + + var props$2k = { + // Has no effect if `trans-props` provided + appear: makeProp(PROP_TYPE_BOOLEAN, false), + // Can be overridden by user supplied `trans-props` + mode: makeProp(PROP_TYPE_STRING), + // Only applicable to the built in transition + // Has no effect if `trans-props` provided + noFade: makeProp(PROP_TYPE_BOOLEAN, false), + // For user supplied transitions (if needed) + transProps: makeProp(PROP_TYPE_OBJECT) + }; // --- Main component --- + // @vue/component + + var BVTransition = /*#__PURE__*/extend({ + name: NAME_TRANSITION, + functional: true, + props: props$2k, + render: function render(h, _ref) { + var children = _ref.children, + data = _ref.data, + props = _ref.props; + var transProps = props.transProps; + + if (!isPlainObject(transProps)) { + transProps = props.noFade ? NO_FADE_PROPS : FADE_PROPS; + + if (props.appear) { + // Default the appear classes to equal the enter classes + transProps = _objectSpread2$3(_objectSpread2$3({}, transProps), {}, { + appear: true, + appearClass: transProps.enterClass, + appearActiveClass: transProps.enterActiveClass, + appearToClass: transProps.enterToClass + }); + } + } + + transProps = _objectSpread2$3(_objectSpread2$3({ + mode: props.mode + }, transProps), {}, { + // We always need `css` true + css: true + }); + + var dataCopy = _objectSpread2$3({}, data); + + delete dataCopy.props; + return h('transition', // Any transition event listeners will get merged here + a(dataCopy, { + props: transProps + }), children); + } + }); + + var _watch$k; + + var _makeModelMixin$k = makeModelMixin('show', { + type: PROP_TYPE_BOOLEAN_NUMBER_STRING, + defaultValue: false + }), + modelMixin$j = _makeModelMixin$k.mixin, + modelProps$j = _makeModelMixin$k.props, + MODEL_PROP_NAME$j = _makeModelMixin$k.prop, + MODEL_EVENT_NAME$j = _makeModelMixin$k.event; // --- Helper methods --- + // Convert `show` value to a number + + + var parseCountDown = function parseCountDown(show) { + if (show === '' || isBoolean(show)) { + return 0; + } + + show = toInteger(show, 0); + return show > 0 ? show : 0; + }; // Convert `show` value to a boolean + + + var parseShow = function parseShow(show) { + if (show === '' || show === true) { + return true; + } + + if (toInteger(show, 0) < 1) { + // Boolean will always return false for the above comparison + return false; + } + + return !!show; + }; // --- Props --- + + + var props$2j = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, modelProps$j), {}, { + dismissLabel: makeProp(PROP_TYPE_STRING, 'Close'), + dismissible: makeProp(PROP_TYPE_BOOLEAN, false), + fade: makeProp(PROP_TYPE_BOOLEAN, false), + variant: makeProp(PROP_TYPE_STRING, 'info') + })), NAME_ALERT); // --- Main component --- + // @vue/component + + var BAlert = /*#__PURE__*/extend({ + name: NAME_ALERT, + mixins: [modelMixin$j, normalizeSlotMixin], + props: props$2j, + data: function data() { + return { + countDown: 0, + // If initially shown, we need to set these for SSR + localShow: parseShow(this[MODEL_PROP_NAME$j]) + }; + }, + watch: (_watch$k = {}, _defineProperty(_watch$k, MODEL_PROP_NAME$j, function (newValue) { + this.countDown = parseCountDown(newValue); + this.localShow = parseShow(newValue); + }), _defineProperty(_watch$k, "countDown", function countDown(newValue) { + var _this = this; + + this.clearCountDownInterval(); + var show = this[MODEL_PROP_NAME$j]; // Ignore if `show` transitions to a boolean value + + if (isNumeric$1(show)) { + this.$emit(EVENT_NAME_DISMISS_COUNT_DOWN, newValue); // Update the v-model if needed + + if (show !== newValue) { + this.$emit(MODEL_EVENT_NAME$j, newValue); + } + + if (newValue > 0) { + this.localShow = true; + this.$_countDownTimeout = setTimeout(function () { + _this.countDown--; + }, 1000); + } else { + // Slightly delay the hide to allow any UI updates + this.$nextTick(function () { + requestAF(function () { + _this.localShow = false; + }); + }); + } + } + }), _defineProperty(_watch$k, "localShow", function localShow(newValue) { + var show = this[MODEL_PROP_NAME$j]; // Only emit dismissed events for dismissible or auto-dismissing alerts + + if (!newValue && (this.dismissible || isNumeric$1(show))) { + this.$emit(EVENT_NAME_DISMISSED); + } // Only emit booleans if we weren't passed a number via v-model + + + if (!isNumeric$1(show) && show !== newValue) { + this.$emit(MODEL_EVENT_NAME$j, newValue); + } + }), _watch$k), + created: function created() { + // Create private non-reactive props + this.$_filterTimer = null; + var show = this[MODEL_PROP_NAME$j]; + this.countDown = parseCountDown(show); + this.localShow = parseShow(show); + }, + beforeDestroy: function beforeDestroy() { + this.clearCountDownInterval(); + }, + methods: { + dismiss: function dismiss() { + this.clearCountDownInterval(); + this.countDown = 0; + this.localShow = false; + }, + clearCountDownInterval: function clearCountDownInterval() { + clearTimeout(this.$_countDownTimeout); + this.$_countDownTimeout = null; + } + }, + render: function render(h) { + var $alert = h(); + + if (this.localShow) { + var dismissible = this.dismissible, + variant = this.variant; + var $dismissButton = h(); + + if (dismissible) { + // Add dismiss button + $dismissButton = h(BButtonClose, { + attrs: { + 'aria-label': this.dismissLabel + }, + on: { + click: this.dismiss + } + }, [this.normalizeSlot(SLOT_NAME_DISMISS)]); + } + + $alert = h('div', { + staticClass: 'alert', + class: _defineProperty({ + 'alert-dismissible': dismissible + }, "alert-".concat(variant), variant), + attrs: { + role: 'alert', + 'aria-live': 'polite', + 'aria-atomic': true + }, + key: this[COMPONENT_UID_KEY] + }, [$dismissButton, this.normalizeSlot()]); + } + + return h(BVTransition, { + props: { + noFade: !this.fade + } + }, [$alert]); + } + }); + + var AlertPlugin = /*#__PURE__*/pluginFactory({ + components: { + BAlert: BAlert + } + }); + + // Math utilty functions + var mathMin = Math.min; + var mathMax = Math.max; + var mathAbs = Math.abs; + var mathCeil = Math.ceil; + var mathFloor = Math.floor; + var mathPow = Math.pow; + var mathRound = Math.round; + + var CLASS_NAME$3 = 'b-aspect'; // --- Props --- + + var props$2i = makePropsConfigurable({ + // Accepts a number (i.e. `16 / 9`, `1`, `4 / 3`) + // Or a string (i.e. '16/9', '16:9', '4:3' '1:1') + aspect: makeProp(PROP_TYPE_NUMBER_STRING, '1:1'), + tag: makeProp(PROP_TYPE_STRING, 'div') + }, NAME_ASPECT); // --- Main component --- + // @vue/component + + var BAspect = /*#__PURE__*/extend({ + name: NAME_ASPECT, + mixins: [normalizeSlotMixin], + props: props$2i, + computed: { + padding: function padding() { + var aspect = this.aspect; + var ratio = 1; + + if (RX_ASPECT.test(aspect)) { + // Width and/or Height can be a decimal value below `1`, so + // we only fallback to `1` if the value is `0` or `NaN` + var _aspect$split$map = aspect.split(RX_ASPECT_SEPARATOR).map(function (v) { + return toFloat(v) || 1; + }), + _aspect$split$map2 = _slicedToArray(_aspect$split$map, 2), + width = _aspect$split$map2[0], + height = _aspect$split$map2[1]; + + ratio = width / height; + } else { + ratio = toFloat(aspect) || 1; + } + + return "".concat(100 / mathAbs(ratio), "%"); + } + }, + render: function render(h) { + var $sizer = h('div', { + staticClass: "".concat(CLASS_NAME$3, "-sizer flex-grow-1"), + style: { + paddingBottom: this.padding, + height: 0 + } + }); + var $content = h('div', { + staticClass: "".concat(CLASS_NAME$3, "-content flex-grow-1 w-100 mw-100"), + style: { + marginLeft: '-100%' + } + }, this.normalizeSlot()); + return h(this.tag, { + staticClass: "".concat(CLASS_NAME$3, " d-flex") + }, [$sizer, $content]); + } + }); + + var AspectPlugin = /*#__PURE__*/pluginFactory({ + components: { + BAspect: BAspect + } + }); + + function safeVueInstance(target) { + if (!isVue3) { + return target; + } + + return new Proxy(target, { + get: function get(target, prop) { + return prop in target ? target[prop] : undefined; + } + }); + } + + var ANCHOR_TAG = 'a'; // Method to replace reserved chars + + var encodeReserveReplacer = function encodeReserveReplacer(c) { + return '%' + c.charCodeAt(0).toString(16); + }; // Fixed encodeURIComponent which is more conformant to RFC3986: + // - escapes [!'()*] + // - preserve commas + + + var encode = function encode(str) { + return encodeURIComponent(toString(str)).replace(RX_ENCODE_REVERSE, encodeReserveReplacer).replace(RX_ENCODED_COMMA, ','); + }; + + var decode = decodeURIComponent; // Stringifies an object of query parameters + // See: https://github.com/vuejs/vue-router/blob/dev/src/util/query.js + + var stringifyQueryObj = function stringifyQueryObj(obj) { + if (!isPlainObject(obj)) { + return ''; + } + + var query = keys(obj).map(function (key) { + var value = obj[key]; + + if (isUndefined(value)) { + return ''; + } else if (isNull(value)) { + return encode(key); + } else if (isArray(value)) { + return value.reduce(function (results, value2) { + if (isNull(value2)) { + results.push(encode(key)); + } else if (!isUndefined(value2)) { + // Faster than string interpolation + results.push(encode(key) + '=' + encode(value2)); + } + + return results; + }, []).join('&'); + } // Faster than string interpolation + + + return encode(key) + '=' + encode(value); + }) + /* must check for length, as we only want to filter empty strings, not things that look falsey! */ + .filter(function (x) { + return x.length > 0; + }).join('&'); + return query ? "?".concat(query) : ''; + }; + var parseQuery = function parseQuery(query) { + var parsed = {}; + query = toString(query).trim().replace(RX_QUERY_START, ''); + + if (!query) { + return parsed; + } + + query.split('&').forEach(function (param) { + var parts = param.replace(RX_PLUS, ' ').split('='); + var key = decode(parts.shift()); + var value = parts.length > 0 ? decode(parts.join('=')) : null; + + if (isUndefined(parsed[key])) { + parsed[key] = value; + } else if (isArray(parsed[key])) { + parsed[key].push(value); + } else { + parsed[key] = [parsed[key], value]; + } + }); + return parsed; + }; + var isLink$1 = function isLink(props) { + return !!(props.href || props.to); + }; + var isRouterLink = function isRouterLink(tag) { + return !!(tag && !isTag(tag, 'a')); + }; + var computeTag = function computeTag(_ref, thisOrParent) { + var to = _ref.to, + disabled = _ref.disabled, + routerComponentName = _ref.routerComponentName; + var hasRouter = !!safeVueInstance(thisOrParent).$router; + var hasNuxt = !!safeVueInstance(thisOrParent).$nuxt; + + if (!hasRouter || hasRouter && (disabled || !to)) { + return ANCHOR_TAG; + } // TODO: + // Check registered components for existence of user supplied router link component name + // We would need to check PascalCase, kebab-case, and camelCase versions of name: + // const name = routerComponentName + // const names = [name, PascalCase(name), KebabCase(name), CamelCase(name)] + // exists = names.some(name => !!thisOrParent.$options.components[name]) + // And may want to cache the result for performance or we just let the render fail + // if the component is not registered + + + return routerComponentName || (hasNuxt ? 'nuxt-link' : 'router-link'); + }; + var computeRel = function computeRel() { + var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + target = _ref2.target, + rel = _ref2.rel; + + return target === '_blank' && isNull(rel) ? 'noopener' : rel || null; + }; + var computeHref = function computeHref() { + var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + href = _ref3.href, + to = _ref3.to; + + var tag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ANCHOR_TAG; + var fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '#'; + var toFallback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '/'; + + // Return `href` when explicitly provided + if (href) { + return href; + } // We've checked for `$router` in `computeTag()`, so `isRouterLink()` indicates a live router + // When deferring to Vue Router's ``, don't use the `href` attribute at all + // We return `null`, and then remove `href` from the attributes passed to `` + + + if (isRouterLink(tag)) { + return null; + } // Fallback to `to` prop (if `to` is a string) + + + if (isString(to)) { + return to || toFallback; + } // Fallback to `to.path' + `to.query` + `to.hash` prop (if `to` is an object) + + + if (isPlainObject(to) && (to.path || to.query || to.hash)) { + var path = toString(to.path); + var query = stringifyQueryObj(to.query); + var hash = toString(to.hash); + hash = !hash || hash.charAt(0) === '#' ? hash : "#".concat(hash); + return "".concat(path).concat(query).concat(hash) || toFallback; + } // If nothing is provided return the fallback + + + return fallback; + }; + + // Base attributes needed on all icons + + var BASE_ATTRS = { + viewBox: '0 0 16 16', + width: '1em', + height: '1em', + focusable: 'false', + role: 'img', + 'aria-label': 'icon' + }; // Attributes that are nulled out when stacked + + var STACKED_ATTRS = { + width: null, + height: null, + focusable: null, + role: null, + 'aria-label': null + }; // --- Props --- + + var props$2h = { + animation: makeProp(PROP_TYPE_STRING), + content: makeProp(PROP_TYPE_STRING), + flipH: makeProp(PROP_TYPE_BOOLEAN, false), + flipV: makeProp(PROP_TYPE_BOOLEAN, false), + fontScale: makeProp(PROP_TYPE_NUMBER_STRING, 1), + rotate: makeProp(PROP_TYPE_NUMBER_STRING, 0), + scale: makeProp(PROP_TYPE_NUMBER_STRING, 1), + shiftH: makeProp(PROP_TYPE_NUMBER_STRING, 0), + shiftV: makeProp(PROP_TYPE_NUMBER_STRING, 0), + stacked: makeProp(PROP_TYPE_BOOLEAN, false), + title: makeProp(PROP_TYPE_STRING), + variant: makeProp(PROP_TYPE_STRING) + }; // --- Main component --- + // Shared private base component to reduce bundle/runtime size + // @vue/component + + var BVIconBase = /*#__PURE__*/extend({ + name: NAME_ICON_BASE, + functional: true, + props: props$2h, + render: function render(h, _ref) { + var _class; + + var data = _ref.data, + props = _ref.props, + children = _ref.children; + var animation = props.animation, + content = props.content, + flipH = props.flipH, + flipV = props.flipV, + stacked = props.stacked, + title = props.title, + variant = props.variant; + var fontScale = mathMax(toFloat(props.fontScale, 1), 0) || 1; + var scale = mathMax(toFloat(props.scale, 1), 0) || 1; + var rotate = toFloat(props.rotate, 0); + var shiftH = toFloat(props.shiftH, 0); + var shiftV = toFloat(props.shiftV, 0); // Compute the transforms + // Note that order is important as SVG transforms are applied in order from + // left to right and we want flipping/scale to occur before rotation + // Note shifting is applied separately + // Assumes that the viewbox is `0 0 16 16` (`8 8` is the center) + + var hasScale = flipH || flipV || scale !== 1; + var hasTransforms = hasScale || rotate; + var hasShift = shiftH || shiftV; + var hasContent = !isUndefinedOrNull(content); + var transforms = [hasTransforms ? 'translate(8 8)' : null, hasScale ? "scale(".concat((flipH ? -1 : 1) * scale, " ").concat((flipV ? -1 : 1) * scale, ")") : null, rotate ? "rotate(".concat(rotate, ")") : null, hasTransforms ? 'translate(-8 -8)' : null].filter(identity); // We wrap the content in a `` for handling the transforms (except shift) + + var $inner = h('g', { + attrs: { + transform: transforms.join(' ') || null + }, + domProps: hasContent ? { + innerHTML: content || '' + } : {} + }, children); // If needed, we wrap in an additional `` in order to handle the shifting + + if (hasShift) { + $inner = h('g', { + attrs: { + transform: "translate(".concat(16 * shiftH / 16, " ").concat(-16 * shiftV / 16, ")") + } + }, [$inner]); + } // Wrap in an additional `` for proper animation handling if stacked + + + if (stacked) { + $inner = h('g', [$inner]); + } + + var $title = title ? h('title', title) : null; + var $content = [$title, $inner].filter(identity); + return h('svg', a({ + staticClass: 'b-icon bi', + class: (_class = {}, _defineProperty(_class, "text-".concat(variant), variant), _defineProperty(_class, "b-icon-animation-".concat(animation), animation), _class), + attrs: BASE_ATTRS, + style: stacked ? {} : { + fontSize: fontScale === 1 ? null : "".concat(fontScale * 100, "%") + } + }, // Merge in user supplied data + data, // If icon is stacked, null-out some attrs + stacked ? { + attrs: STACKED_ATTRS + } : {}, // These cannot be overridden by users + { + attrs: { + xmlns: stacked ? null : 'http://www.w3.org/2000/svg', + fill: 'currentColor' + } + }), $content); + } + }); + + var iconProps$1 = omit(props$2h, ['content']); + /** + * Icon component generator function + * + * @param {string} icon name (minus the leading `BIcon`) + * @param {string} raw `innerHTML` for SVG + * @return {VueComponent} + */ + + var makeIcon = function makeIcon(name, content) { + // For performance reason we pre-compute some values, so that + // they are not computed on each render of the icon component + var kebabName = kebabCase(name); + var iconName = "BIcon".concat(pascalCase(name)); + var iconNameClass = "bi-".concat(kebabName); + var iconTitle = kebabName.replace(/-/g, ' '); + var svgContent = trim(content || ''); + return /*#__PURE__*/extend({ + name: iconName, + functional: true, + props: iconProps$1, + render: function render(h, _ref) { + var data = _ref.data, + props = _ref.props; + return h(BVIconBase, a( // Defaults + { + props: { + title: iconTitle + }, + attrs: { + 'aria-label': iconTitle + } + }, // User data + data, // Required data + { + staticClass: iconNameClass, + props: _objectSpread2$3(_objectSpread2$3({}, props), {}, { + content: svgContent + }) + })); + } + }); + }; + + // --- BEGIN AUTO-GENERATED FILE --- + var BIconBlank=/*#__PURE__*/makeIcon('Blank','');// --- Bootstrap Icons --- + var BIconCalendar=/*#__PURE__*/makeIcon('Calendar','');// eslint-disable-next-line + var BIconCalendarFill=/*#__PURE__*/makeIcon('CalendarFill','');// eslint-disable-next-line + var BIconChevronBarLeft=/*#__PURE__*/makeIcon('ChevronBarLeft','');// eslint-disable-next-line + var BIconChevronDoubleLeft=/*#__PURE__*/makeIcon('ChevronDoubleLeft','');// eslint-disable-next-line + var BIconChevronDown=/*#__PURE__*/makeIcon('ChevronDown','');// eslint-disable-next-line + var BIconChevronLeft=/*#__PURE__*/makeIcon('ChevronLeft','');// eslint-disable-next-line + var BIconChevronUp=/*#__PURE__*/makeIcon('ChevronUp','');// eslint-disable-next-line + var BIconCircleFill=/*#__PURE__*/makeIcon('CircleFill','');// eslint-disable-next-line + var BIconClock=/*#__PURE__*/makeIcon('Clock','');// eslint-disable-next-line + var BIconClockFill=/*#__PURE__*/makeIcon('ClockFill','');// eslint-disable-next-line + var BIconDash=/*#__PURE__*/makeIcon('Dash','');// eslint-disable-next-line + var BIconPersonFill=/*#__PURE__*/makeIcon('PersonFill','');// eslint-disable-next-line + var BIconPlus=/*#__PURE__*/makeIcon('Plus','');// eslint-disable-next-line + var BIconStar=/*#__PURE__*/makeIcon('Star','');// eslint-disable-next-line + var BIconStarFill=/*#__PURE__*/makeIcon('StarFill','');// eslint-disable-next-line + var BIconStarHalf=/*#__PURE__*/makeIcon('StarHalf','');// eslint-disable-next-line + var BIconX=/*#__PURE__*/makeIcon('X','');// eslint-disable-next-line + // --- END AUTO-GENERATED FILE --- + + var findIconComponent = function findIconComponent(ctx, iconName) { + if (!ctx) { + return Vue__default['default'].component(iconName); + } + + var components = (ctx.$options || {}).components; + var iconComponent = components && components[iconName]; + return iconComponent || findIconComponent(ctx.$parent, iconName); + }; // --- Props --- + + + var iconProps = omit(props$2h, ['content']); + var props$2g = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, iconProps), {}, { + icon: makeProp(PROP_TYPE_STRING) + })), NAME_ICON); // --- Main component --- + // Helper BIcon component + // Requires the requested icon component to be installed + // @vue/component + + var BIcon = /*#__PURE__*/extend({ + name: NAME_ICON, + functional: true, + props: props$2g, + render: function render(h, _ref) { + var data = _ref.data, + props = _ref.props, + parent = _ref.parent; + var icon = pascalCase(trim(props.icon || '')).replace(RX_ICON_PREFIX, ''); // If parent context exists, we check to see if the icon has been registered + // either locally in the parent component, or globally at the `$root` level + // If not registered, we render a blank icon + + return h(icon ? findIconComponent(parent, "BIcon".concat(icon)) || BIconBlank : BIconBlank, a(data, { + props: pluckProps(iconProps, props) + })); + } + }); + + var CODE_BACKSPACE = 8; + var CODE_DELETE = 46; + var CODE_DOWN = 40; + var CODE_END = 35; + var CODE_ENTER = 13; + var CODE_ESC = 27; + var CODE_HOME = 36; + var CODE_LEFT = 37; + var CODE_PAGEDOWN = 34; + var CODE_PAGEUP = 33; + var CODE_RIGHT = 39; + var CODE_SPACE = 32; + var CODE_UP = 38; + + // Handles when arrays are "sparse" (array.every(...) doesn't handle sparse) + + var compareArrays = function compareArrays(a, b) { + if (a.length !== b.length) { + return false; + } + + var equal = true; + + for (var i = 0; equal && i < a.length; i++) { + equal = looseEqual(a[i], b[i]); + } + + return equal; + }; + /** + * Check if two values are loosely equal - that is, + * if they are plain objects, do they have the same shape? + * Returns boolean true or false + */ + + + var looseEqual = function looseEqual(a, b) { + if (a === b) { + return true; + } + + var aValidType = isDate(a); + var bValidType = isDate(b); + + if (aValidType || bValidType) { + return aValidType && bValidType ? a.getTime() === b.getTime() : false; + } + + aValidType = isArray(a); + bValidType = isArray(b); + + if (aValidType || bValidType) { + return aValidType && bValidType ? compareArrays(a, b) : false; + } + + aValidType = isObject(a); + bValidType = isObject(b); + + if (aValidType || bValidType) { + /* istanbul ignore if: this if will probably never be called */ + if (!aValidType || !bValidType) { + return false; + } + + var aKeysCount = keys(a).length; + var bKeysCount = keys(b).length; + + if (aKeysCount !== bKeysCount) { + return false; + } + + for (var key in a) { + var aHasKey = hasOwnProperty(a, key); + var bHasKey = hasOwnProperty(b, key); + + if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) { + return false; + } + } + } + + return String(a) === String(b); + }; + + var isEmpty = function isEmpty(value) { + return !value || keys(value).length === 0; + }; + + var makePropWatcher = function makePropWatcher(propName) { + return { + handler: function handler(newValue, oldValue) { + if (looseEqual(newValue, oldValue)) { + return; + } + + if (isEmpty(newValue) || isEmpty(oldValue)) { + this[propName] = cloneDeep(newValue); + return; + } + + for (var key in oldValue) { + if (!hasOwnProperty(newValue, key)) { + this.$delete(this.$data[propName], key); + } + } + + for (var _key in newValue) { + this.$set(this.$data[propName], _key, newValue[_key]); + } + } + }; + }; + var makePropCacheMixin = function makePropCacheMixin(propName, proxyPropName) { + return extend({ + data: function data() { + return _defineProperty({}, proxyPropName, cloneDeep(this[propName])); + }, + watch: _defineProperty({}, propName, makePropWatcher(proxyPropName)) + }); + }; + + var attrsMixinVue2 = makePropCacheMixin('$attrs', 'bvAttrs'); + var attrsMixinVue3 = extend({ + computed: { + bvAttrs: function bvAttrs() { + var bvAttrs = _objectSpread2$3({}, this.$attrs); + + Object.keys(bvAttrs).forEach(function (key) { + if (bvAttrs[key] === undefined) { + delete bvAttrs[key]; + } + }); + return bvAttrs; + } + } + }); + var attrsMixin = isVue3 ? attrsMixinVue3 : attrsMixinVue2; + + var getEventRoot = function getEventRoot(vm) { + return vm.$root.$options.bvEventRoot || vm.$root; + }; + + var PROP$3 = '$_rootListeners'; // --- Mixin --- + // @vue/component + + var listenOnRootMixin = extend({ + computed: { + bvEventRoot: function bvEventRoot() { + return getEventRoot(this); + } + }, + created: function created() { + // Define non-reactive property + // Object of arrays, keyed by event name, + // where value is an array of callbacks + this[PROP$3] = {}; + }, + beforeDestroy: function beforeDestroy() { + var _this = this; + + // Unregister all registered listeners + keys(this[PROP$3] || {}).forEach(function (event) { + _this[PROP$3][event].forEach(function (callback) { + _this.listenOffRoot(event, callback); + }); + }); + this[PROP$3] = null; + }, + methods: { + registerRootListener: function registerRootListener(event, callback) { + if (this[PROP$3]) { + this[PROP$3][event] = this[PROP$3][event] || []; + + if (!arrayIncludes(this[PROP$3][event], callback)) { + this[PROP$3][event].push(callback); + } + } + }, + unregisterRootListener: function unregisterRootListener(event, callback) { + if (this[PROP$3] && this[PROP$3][event]) { + this[PROP$3][event] = this[PROP$3][event].filter(function (cb) { + return cb !== callback; + }); + } + }, + + /** + * Safely register event listeners on the root Vue node + * While Vue automatically removes listeners for individual components, + * when a component registers a listener on `$root` and is destroyed, + * this orphans a callback because the node is gone, but the `$root` + * does not clear the callback + * + * When registering a `$root` listener, it also registers the listener + * to be removed in the component's `beforeDestroy()` hook + * + * @param {string} event + * @param {function} callback + */ + listenOnRoot: function listenOnRoot(event, callback) { + if (this.bvEventRoot) { + this.bvEventRoot.$on(event, callback); + this.registerRootListener(event, callback); + } + }, + + /** + * Safely register a `$once()` event listener on the root Vue node + * While Vue automatically removes listeners for individual components, + * when a component registers a listener on `$root` and is destroyed, + * this orphans a callback because the node is gone, but the `$root` + * does not clear the callback + * + * When registering a `$root` listener, it also registers the listener + * to be removed in the component's `beforeDestroy()` hook + * + * @param {string} event + * @param {function} callback + */ + listenOnRootOnce: function listenOnRootOnce(event, callback) { + var _this2 = this; + + if (this.bvEventRoot) { + var _callback = function _callback() { + _this2.unregisterRootListener(_callback); // eslint-disable-next-line node/no-callback-literal + + + callback.apply(void 0, arguments); + }; + + this.bvEventRoot.$once(event, _callback); + this.registerRootListener(event, _callback); + } + }, + + /** + * Safely unregister event listeners from the root Vue node + * + * @param {string} event + * @param {function} callback + */ + listenOffRoot: function listenOffRoot(event, callback) { + this.unregisterRootListener(event, callback); + + if (this.bvEventRoot) { + this.bvEventRoot.$off(event, callback); + } + }, + + /** + * Convenience method for calling `vm.$emit()` on `$root` + * + * @param {string} event + * @param {*} args + */ + emitOnRoot: function emitOnRoot(event) { + if (this.bvEventRoot) { + var _this$bvEventRoot; + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + (_this$bvEventRoot = this.bvEventRoot).$emit.apply(_this$bvEventRoot, [event].concat(args)); + } + } + } + }); + + var listenersMixinVue2 = makePropCacheMixin('$listeners', 'bvListeners'); + var listenersMixinVue3 = extend({ + data: function data() { + return { + bvListeners: {} + }; + }, + created: function created() { + this.bvListeners = _objectSpread2$3({}, this.$listeners); + }, + beforeUpdate: function beforeUpdate() { + this.bvListeners = _objectSpread2$3({}, this.$listeners); + } + }); + var listenersMixin = isVue3 ? listenersMixinVue3 : listenersMixinVue2; + + var ROOT_EVENT_NAME_CLICKED = getRootEventName(NAME_LINK, 'clicked'); // --- Props --- + // `` specific props + + var routerLinkProps = { + activeClass: makeProp(PROP_TYPE_STRING), + append: makeProp(PROP_TYPE_BOOLEAN, false), + event: makeProp(PROP_TYPE_ARRAY_STRING), + exact: makeProp(PROP_TYPE_BOOLEAN, false), + exactActiveClass: makeProp(PROP_TYPE_STRING), + exactPath: makeProp(PROP_TYPE_BOOLEAN, false), + exactPathActiveClass: makeProp(PROP_TYPE_STRING), + replace: makeProp(PROP_TYPE_BOOLEAN, false), + routerTag: makeProp(PROP_TYPE_STRING), + to: makeProp(PROP_TYPE_OBJECT_STRING) + }; // `` specific props + + var nuxtLinkProps = { + noPrefetch: makeProp(PROP_TYPE_BOOLEAN, false), + // Must be `null` to fall back to the value defined in the + // `nuxt.config.js` configuration file for `router.prefetchLinks` + // We convert `null` to `undefined`, so that Nuxt.js will use the + // compiled default + // Vue treats `undefined` as default of `false` for Boolean props, + // so we must set it as `null` here to be a true tri-state prop + prefetch: makeProp(PROP_TYPE_BOOLEAN, null) + }; // All `` props + + var props$2f = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, nuxtLinkProps), routerLinkProps), {}, { + active: makeProp(PROP_TYPE_BOOLEAN, false), + disabled: makeProp(PROP_TYPE_BOOLEAN, false), + href: makeProp(PROP_TYPE_STRING), + // Must be `null` if no value provided + rel: makeProp(PROP_TYPE_STRING, null), + // To support 3rd party router links based on `` (i.e. `g-link` for Gridsome) + // Default is to auto choose between `` and `` + // Gridsome doesn't provide a mechanism to auto detect and has caveats + // such as not supporting FQDN URLs or hash only URLs + routerComponentName: makeProp(PROP_TYPE_STRING), + target: makeProp(PROP_TYPE_STRING, '_self') + })), NAME_LINK); // --- Main component --- + // @vue/component + + var BLink = /*#__PURE__*/extend({ + name: NAME_LINK, + // Mixin order is important! + mixins: [attrsMixin, listenersMixin, listenOnRootMixin, normalizeSlotMixin], + inheritAttrs: false, + props: props$2f, + computed: { + computedTag: function computedTag() { + // We don't pass `this` as the first arg as we need reactivity of the props + var to = this.to, + disabled = this.disabled, + routerComponentName = this.routerComponentName; + return computeTag({ + to: to, + disabled: disabled, + routerComponentName: routerComponentName + }, this); + }, + isRouterLink: function isRouterLink$1() { + return isRouterLink(this.computedTag); + }, + computedRel: function computedRel() { + // We don't pass `this` as the first arg as we need reactivity of the props + var target = this.target, + rel = this.rel; + return computeRel({ + target: target, + rel: rel + }); + }, + computedHref: function computedHref() { + // We don't pass `this` as the first arg as we need reactivity of the props + var to = this.to, + href = this.href; + return computeHref({ + to: to, + href: href + }, this.computedTag); + }, + computedProps: function computedProps() { + var event = this.event, + prefetch = this.prefetch, + routerTag = this.routerTag; + return this.isRouterLink ? _objectSpread2$3(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, pluckProps(omit(_objectSpread2$3(_objectSpread2$3({}, routerLinkProps), this.computedTag === 'nuxt-link' ? nuxtLinkProps : {}), ['event', 'prefetch', 'routerTag']), this)), event ? { + event: event + } : {}), isBoolean(prefetch) ? { + prefetch: prefetch + } : {}), routerTag ? { + tag: routerTag + } : {}) : {}; + }, + computedAttrs: function computedAttrs() { + var bvAttrs = this.bvAttrs, + href = this.computedHref, + rel = this.computedRel, + disabled = this.disabled, + target = this.target, + routerTag = this.routerTag, + isRouterLink = this.isRouterLink; + return _objectSpread2$3(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, bvAttrs), href ? { + href: href + } : {}), isRouterLink && routerTag && !isTag(routerTag, 'a') ? {} : { + rel: rel, + target: target + }), {}, { + tabindex: disabled ? '-1' : isUndefined(bvAttrs.tabindex) ? null : bvAttrs.tabindex, + 'aria-disabled': disabled ? 'true' : null + }); + }, + computedListeners: function computedListeners() { + return _objectSpread2$3(_objectSpread2$3({}, this.bvListeners), {}, { + // We want to overwrite any click handler since our callback + // will invoke the user supplied handler(s) if `!this.disabled` + click: this.onClick + }); + } + }, + methods: { + onClick: function onClick(event) { + var _arguments = arguments; + var eventIsEvent = isEvent(event); + var isRouterLink = this.isRouterLink; + var suppliedHandler = this.bvListeners.click; + + if (eventIsEvent && this.disabled) { + // Stop event from bubbling up + // Kill the event loop attached to this specific `EventTarget` + // Needed to prevent `vue-router` for doing its thing + stopEvent(event, { + immediatePropagation: true + }); + } else { + // Router links do not emit instance `click` events, so we + // add in an `$emit('click', event)` on its Vue instance + // + // seems not to be required for Vue3 compat build + + /* istanbul ignore next: difficult to test, but we know it works */ + if (isRouterLink) { + var _event$currentTarget$; + + (_event$currentTarget$ = event.currentTarget.__vue__) === null || _event$currentTarget$ === void 0 ? void 0 : _event$currentTarget$.$emit(EVENT_NAME_CLICK, event); + } // Call the suppliedHandler(s), if any provided + + + concat(suppliedHandler).filter(function (h) { + return isFunction$1(h); + }).forEach(function (handler) { + handler.apply(void 0, _toConsumableArray$1(_arguments)); + }); // Emit the global `$root` click event + + this.emitOnRoot(ROOT_EVENT_NAME_CLICKED, event); // TODO: Remove deprecated 'clicked::link' event with next major release + + this.emitOnRoot('clicked::link', event); + } // Stop scroll-to-top behavior or navigation on + // regular links when href is just '#' + + + if (eventIsEvent && !isRouterLink && this.computedHref === '#') { + stopEvent(event, { + propagation: false + }); + } + }, + focus: function focus() { + attemptFocus(this.$el); + }, + blur: function blur() { + attemptBlur(this.$el); + } + }, + render: function render(h) { + var active = this.active, + disabled = this.disabled; + return h(this.computedTag, _defineProperty({ + class: { + active: active, + disabled: disabled + }, + attrs: this.computedAttrs, + props: this.computedProps + }, this.isRouterLink ? 'nativeOn' : 'on', this.computedListeners), this.normalizeSlot()); + } + }); + + var linkProps$7 = omit(props$2f, ['event', 'routerTag']); + delete linkProps$7.href.default; + delete linkProps$7.to.default; + var props$2e = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, linkProps$7), {}, { + block: makeProp(PROP_TYPE_BOOLEAN, false), + disabled: makeProp(PROP_TYPE_BOOLEAN, false), + pill: makeProp(PROP_TYPE_BOOLEAN, false), + // Tri-state: `true`, `false` or `null` + // => On, off, not a toggle + pressed: makeProp(PROP_TYPE_BOOLEAN, null), + size: makeProp(PROP_TYPE_STRING), + squared: makeProp(PROP_TYPE_BOOLEAN, false), + tag: makeProp(PROP_TYPE_STRING, 'button'), + type: makeProp(PROP_TYPE_STRING, 'button'), + variant: makeProp(PROP_TYPE_STRING, 'secondary') + })), NAME_BUTTON); // --- Helper methods --- + // Focus handler for toggle buttons + // Needs class of 'focus' when focused + + var handleFocus = function handleFocus(event) { + if (event.type === 'focusin') { + addClass(event.target, 'focus'); + } else if (event.type === 'focusout') { + removeClass(event.target, 'focus'); + } + }; // Is the requested button a link? + // If tag prop is set to `a`, we use a to get proper disabled handling + + + var isLink = function isLink(props) { + return isLink$1(props) || isTag(props.tag, 'a'); + }; // Is the button to be a toggle button? + + + var isToggle = function isToggle(props) { + return isBoolean(props.pressed); + }; // Is the button "really" a button? + + + var isButton = function isButton(props) { + return !(isLink(props) || props.tag && !isTag(props.tag, 'button')); + }; // Is the requested tag not a button or link? + + + var isNonStandardTag$1 = function isNonStandardTag(props) { + return !isLink(props) && !isButton(props); + }; // Compute required classes (non static classes) + + + var computeClass = function computeClass(props) { + var _ref; + + return ["btn-".concat(props.variant || 'secondary'), (_ref = {}, _defineProperty(_ref, "btn-".concat(props.size), props.size), _defineProperty(_ref, 'btn-block', props.block), _defineProperty(_ref, 'rounded-pill', props.pill), _defineProperty(_ref, 'rounded-0', props.squared && !props.pill), _defineProperty(_ref, "disabled", props.disabled), _defineProperty(_ref, "active", props.pressed), _ref)]; + }; // Compute the link props to pass to b-link (if required) + + + var computeLinkProps = function computeLinkProps(props) { + return isLink(props) ? pluckProps(linkProps$7, props) : {}; + }; // Compute the attributes for a button + + + var computeAttrs = function computeAttrs(props, data) { + var button = isButton(props); + var link = isLink(props); + var toggle = isToggle(props); + var nonStandardTag = isNonStandardTag$1(props); + var hashLink = link && props.href === '#'; + var role = data.attrs && data.attrs.role ? data.attrs.role : null; + var tabindex = data.attrs ? data.attrs.tabindex : null; + + if (nonStandardTag || hashLink) { + tabindex = '0'; + } + + return { + // Type only used for "real" buttons + type: button && !link ? props.type : null, + // Disabled only set on "real" buttons + disabled: button ? props.disabled : null, + // We add a role of button when the tag is not a link or button for ARIA + // Don't bork any role provided in `data.attrs` when `isLink` or `isButton` + // Except when link has `href` of `#` + role: nonStandardTag || hashLink ? 'button' : role, + // We set the `aria-disabled` state for non-standard tags + 'aria-disabled': nonStandardTag ? String(props.disabled) : null, + // For toggles, we need to set the pressed state for ARIA + 'aria-pressed': toggle ? String(props.pressed) : null, + // `autocomplete="off"` is needed in toggle mode to prevent some browsers + // from remembering the previous setting when using the back button + autocomplete: toggle ? 'off' : null, + // `tabindex` is used when the component is not a button + // Links are tabbable, but don't allow disabled, while non buttons or links + // are not tabbable, so we mimic that functionality by disabling tabbing + // when disabled, and adding a `tabindex="0"` to non buttons or non links + tabindex: props.disabled && !button ? '-1' : tabindex + }; + }; // --- Main component --- + // @vue/component + + + var BButton = /*#__PURE__*/extend({ + name: NAME_BUTTON, + functional: true, + props: props$2e, + render: function render(h, _ref2) { + var props = _ref2.props, + data = _ref2.data, + listeners = _ref2.listeners, + children = _ref2.children; + var toggle = isToggle(props); + var link = isLink(props); + var nonStandardTag = isNonStandardTag$1(props); + var hashLink = link && props.href === '#'; + var on = { + keydown: function keydown(event) { + // When the link is a `href="#"` or a non-standard tag (has `role="button"`), + // we add a keydown handlers for CODE_SPACE/CODE_ENTER + + /* istanbul ignore next */ + if (props.disabled || !(nonStandardTag || hashLink)) { + return; + } + + var keyCode = event.keyCode; // Add CODE_SPACE handler for `href="#"` and CODE_ENTER handler for non-standard tags + + if (keyCode === CODE_SPACE || keyCode === CODE_ENTER && nonStandardTag) { + var target = event.currentTarget || event.target; + stopEvent(event, { + propagation: false + }); + target.click(); + } + }, + click: function click(event) { + /* istanbul ignore if: blink/button disabled should handle this */ + if (props.disabled && isEvent(event)) { + stopEvent(event); + } else if (toggle && listeners && listeners['update:pressed']) { + // Send `.sync` updates to any "pressed" prop (if `.sync` listeners) + // `concat()` will normalize the value to an array without + // double wrapping an array value in an array + concat(listeners['update:pressed']).forEach(function (fn) { + if (isFunction$1(fn)) { + fn(!props.pressed); + } + }); + } + } + }; + + if (toggle) { + on.focusin = handleFocus; + on.focusout = handleFocus; + } + + var componentData = { + staticClass: 'btn', + class: computeClass(props), + props: computeLinkProps(props), + attrs: computeAttrs(props, data), + on: on + }; + return h(link ? BLink : props.tag, a(_objectSpread2$3(_objectSpread2$3({}, data), {}, { + props: undefined + }), componentData), children); + } + }); + + var CLASS_NAME$2 = 'b-avatar'; + var SIZES = ['sm', null, 'lg']; + var FONT_SIZE_SCALE = 0.4; + var BADGE_FONT_SIZE_SCALE = FONT_SIZE_SCALE * 0.7; // --- Helper methods --- + + var computeSize = function computeSize(value) { + // Parse to number when value is a float-like string + value = isString(value) && isNumeric$1(value) ? toFloat(value, 0) : value; // Convert all numbers to pixel values + + return isNumber(value) ? "".concat(value, "px") : value || null; + }; // --- Props --- + + var linkProps$6 = omit(props$2f, ['active', 'event', 'routerTag']); + var props$2d = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, linkProps$6), {}, { + alt: makeProp(PROP_TYPE_STRING, 'avatar'), + ariaLabel: makeProp(PROP_TYPE_STRING), + badge: makeProp(PROP_TYPE_BOOLEAN_STRING, false), + badgeLeft: makeProp(PROP_TYPE_BOOLEAN, false), + badgeOffset: makeProp(PROP_TYPE_STRING), + badgeTop: makeProp(PROP_TYPE_BOOLEAN, false), + badgeVariant: makeProp(PROP_TYPE_STRING, 'primary'), + button: makeProp(PROP_TYPE_BOOLEAN, false), + buttonType: makeProp(PROP_TYPE_STRING, 'button'), + icon: makeProp(PROP_TYPE_STRING), + rounded: makeProp(PROP_TYPE_BOOLEAN_STRING, false), + size: makeProp(PROP_TYPE_NUMBER_STRING), + square: makeProp(PROP_TYPE_BOOLEAN, false), + src: makeProp(PROP_TYPE_STRING), + text: makeProp(PROP_TYPE_STRING), + variant: makeProp(PROP_TYPE_STRING, 'secondary') + })), NAME_AVATAR); // --- Main component --- + // @vue/component + + var BAvatar = /*#__PURE__*/extend({ + name: NAME_AVATAR, + mixins: [normalizeSlotMixin], + inject: { + getBvAvatarGroup: { + default: function _default() { + return function () { + return null; + }; + } + } + }, + props: props$2d, + data: function data() { + return { + localSrc: this.src || null + }; + }, + computed: { + bvAvatarGroup: function bvAvatarGroup() { + return this.getBvAvatarGroup(); + }, + computedSize: function computedSize() { + // Always use the avatar group size + var bvAvatarGroup = this.bvAvatarGroup; + return computeSize(bvAvatarGroup ? bvAvatarGroup.size : this.size); + }, + computedVariant: function computedVariant() { + var bvAvatarGroup = this.bvAvatarGroup; + return bvAvatarGroup && bvAvatarGroup.variant ? bvAvatarGroup.variant : this.variant; + }, + computedRounded: function computedRounded() { + var bvAvatarGroup = this.bvAvatarGroup; + var square = bvAvatarGroup && bvAvatarGroup.square ? true : this.square; + var rounded = bvAvatarGroup && bvAvatarGroup.rounded ? bvAvatarGroup.rounded : this.rounded; + return square ? '0' : rounded === '' ? true : rounded || 'circle'; + }, + fontStyle: function fontStyle() { + var size = this.computedSize; + var fontSize = SIZES.indexOf(size) === -1 ? "calc(".concat(size, " * ").concat(FONT_SIZE_SCALE, ")") : null; + return fontSize ? { + fontSize: fontSize + } : {}; + }, + marginStyle: function marginStyle() { + var size = this.computedSize, + bvAvatarGroup = this.bvAvatarGroup; + var overlapScale = bvAvatarGroup ? bvAvatarGroup.overlapScale : 0; + var value = size && overlapScale ? "calc(".concat(size, " * -").concat(overlapScale, ")") : null; + return value ? { + marginLeft: value, + marginRight: value + } : {}; + }, + badgeStyle: function badgeStyle() { + var size = this.computedSize, + badgeTop = this.badgeTop, + badgeLeft = this.badgeLeft, + badgeOffset = this.badgeOffset; + var offset = badgeOffset || '0px'; + return { + fontSize: SIZES.indexOf(size) === -1 ? "calc(".concat(size, " * ").concat(BADGE_FONT_SIZE_SCALE, " )") : null, + top: badgeTop ? offset : null, + bottom: badgeTop ? null : offset, + left: badgeLeft ? offset : null, + right: badgeLeft ? null : offset + }; + } + }, + watch: { + src: function src(newValue, oldValue) { + if (newValue !== oldValue) { + this.localSrc = newValue || null; + } + } + }, + methods: { + onImgError: function onImgError(event) { + this.localSrc = null; + this.$emit(EVENT_NAME_IMG_ERROR, event); + }, + onClick: function onClick(event) { + this.$emit(EVENT_NAME_CLICK, event); + } + }, + render: function render(h) { + var _class2; + + var variant = this.computedVariant, + disabled = this.disabled, + rounded = this.computedRounded, + icon = this.icon, + src = this.localSrc, + text = this.text, + fontStyle = this.fontStyle, + marginStyle = this.marginStyle, + size = this.computedSize, + button = this.button, + type = this.buttonType, + badge = this.badge, + badgeVariant = this.badgeVariant, + badgeStyle = this.badgeStyle; + var link = !button && isLink$1(this); + var tag = button ? BButton : link ? BLink : 'span'; + var alt = this.alt; + var ariaLabel = this.ariaLabel || null; + var $content = null; + + if (this.hasNormalizedSlot()) { + // Default slot overrides props + $content = h('span', { + staticClass: 'b-avatar-custom' + }, [this.normalizeSlot()]); + } else if (src) { + $content = h('img', { + style: variant ? {} : { + width: '100%', + height: '100%' + }, + attrs: { + src: src, + alt: alt + }, + on: { + error: this.onImgError + } + }); + $content = h('span', { + staticClass: 'b-avatar-img' + }, [$content]); + } else if (icon) { + $content = h(BIcon, { + props: { + icon: icon + }, + attrs: { + 'aria-hidden': 'true', + alt: alt + } + }); + } else if (text) { + $content = h('span', { + staticClass: 'b-avatar-text', + style: fontStyle + }, [h('span', text)]); + } else { + // Fallback default avatar content + $content = h(BIconPersonFill, { + attrs: { + 'aria-hidden': 'true', + alt: alt + } + }); + } + + var $badge = h(); + var hasBadgeSlot = this.hasNormalizedSlot(SLOT_NAME_BADGE); + + if (badge || badge === '' || hasBadgeSlot) { + var badgeText = badge === true ? '' : badge; + $badge = h('span', { + staticClass: 'b-avatar-badge', + class: _defineProperty({}, "badge-".concat(badgeVariant), badgeVariant), + style: badgeStyle + }, [hasBadgeSlot ? this.normalizeSlot(SLOT_NAME_BADGE) : badgeText]); + } + + var componentData = { + staticClass: CLASS_NAME$2, + class: (_class2 = {}, _defineProperty(_class2, "".concat(CLASS_NAME$2, "-").concat(size), size && SIZES.indexOf(size) !== -1), _defineProperty(_class2, "badge-".concat(variant), !button && variant), _defineProperty(_class2, "rounded", rounded === true), _defineProperty(_class2, "rounded-".concat(rounded), rounded && rounded !== true), _defineProperty(_class2, "disabled", disabled), _class2), + style: _objectSpread2$3(_objectSpread2$3({}, marginStyle), {}, { + width: size, + height: size + }), + attrs: { + 'aria-label': ariaLabel || null + }, + props: button ? { + variant: variant, + disabled: disabled, + type: type + } : link ? pluckProps(linkProps$6, this) : {}, + on: button || link ? { + click: this.onClick + } : {} + }; + return h(tag, componentData, [$content, $badge]); + } + }); + + var props$2c = makePropsConfigurable({ + overlap: makeProp(PROP_TYPE_NUMBER_STRING, 0.3), + // Child avatars will prefer this prop (if set) over their own + rounded: makeProp(PROP_TYPE_BOOLEAN_STRING, false), + // Child avatars will always use this over their own size + size: makeProp(PROP_TYPE_STRING), + // Child avatars will prefer this prop (if set) over their own + square: makeProp(PROP_TYPE_BOOLEAN, false), + tag: makeProp(PROP_TYPE_STRING, 'div'), + // Child avatars will prefer this variant over their own + variant: makeProp(PROP_TYPE_STRING) + }, NAME_AVATAR_GROUP); // --- Main component --- + // @vue/component + + var BAvatarGroup = /*#__PURE__*/extend({ + name: NAME_AVATAR_GROUP, + mixins: [normalizeSlotMixin], + provide: function provide() { + var _this = this; + + return { + getBvAvatarGroup: function getBvAvatarGroup() { + return _this; + } + }; + }, + props: props$2c, + computed: { + computedSize: function computedSize() { + return computeSize(this.size); + }, + overlapScale: function overlapScale() { + return mathMin(mathMax(toFloat(this.overlap, 0), 0), 1) / 2; + }, + paddingStyle: function paddingStyle() { + var value = this.computedSize; + value = value ? "calc(".concat(value, " * ").concat(this.overlapScale, ")") : null; + return value ? { + paddingLeft: value, + paddingRight: value + } : {}; + } + }, + render: function render(h) { + var $inner = h('div', { + staticClass: 'b-avatar-group-inner', + style: this.paddingStyle + }, this.normalizeSlot()); + return h(this.tag, { + staticClass: 'b-avatar-group', + attrs: { + role: 'group' + } + }, [$inner]); + } + }); + + var AvatarPlugin = /*#__PURE__*/pluginFactory({ + components: { + BAvatar: BAvatar, + BAvatarGroup: BAvatarGroup + } + }); + + var linkProps$5 = omit(props$2f, ['event', 'routerTag']); + delete linkProps$5.href.default; + delete linkProps$5.to.default; + var props$2b = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, linkProps$5), {}, { + pill: makeProp(PROP_TYPE_BOOLEAN, false), + tag: makeProp(PROP_TYPE_STRING, 'span'), + variant: makeProp(PROP_TYPE_STRING, 'secondary') + })), NAME_BADGE); // --- Main component --- + // @vue/component + + var BBadge = /*#__PURE__*/extend({ + name: NAME_BADGE, + functional: true, + props: props$2b, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + var active = props.active, + disabled = props.disabled; + var link = isLink$1(props); + var tag = link ? BLink : props.tag; + var variant = props.variant || 'secondary'; + return h(tag, a(data, { + staticClass: 'badge', + class: ["badge-".concat(variant), { + 'badge-pill': props.pill, + active: active, + disabled: disabled + }], + props: link ? pluckProps(linkProps$5, props) : {} + }), children); + } + }); + + var BadgePlugin = /*#__PURE__*/pluginFactory({ + components: { + BBadge: BBadge + } + }); + + var stripTags = function stripTags() { + var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + return String(text).replace(RX_HTML_TAGS, ''); + }; // Generate a `domProps` object for either `innerHTML`, `textContent` or an empty object + + var htmlOrText = function htmlOrText(innerHTML, textContent) { + return innerHTML ? { + innerHTML: innerHTML + } : textContent ? { + textContent: textContent + } : {}; + }; + + var props$2a = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, omit(props$2f, ['event', 'routerTag'])), {}, { + ariaCurrent: makeProp(PROP_TYPE_STRING, 'location'), + html: makeProp(PROP_TYPE_STRING), + text: makeProp(PROP_TYPE_STRING) + })), NAME_BREADCRUMB_LINK); // --- Main component --- + // @vue/component + + var BBreadcrumbLink = /*#__PURE__*/extend({ + name: NAME_BREADCRUMB_LINK, + functional: true, + props: props$2a, + render: function render(h, _ref) { + var suppliedProps = _ref.props, + data = _ref.data, + children = _ref.children; + var active = suppliedProps.active; + var tag = active ? 'span' : BLink; + var componentData = { + attrs: { + 'aria-current': active ? suppliedProps.ariaCurrent : null + }, + props: pluckProps(props$2a, suppliedProps) + }; + + if (!children) { + componentData.domProps = htmlOrText(suppliedProps.html, suppliedProps.text); + } + + return h(tag, a(data, componentData), children); + } + }); + + var props$29 = makePropsConfigurable(props$2a, NAME_BREADCRUMB_ITEM); // --- Main component --- + // @vue/component + + var BBreadcrumbItem = /*#__PURE__*/extend({ + name: NAME_BREADCRUMB_ITEM, + functional: true, + props: props$29, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + return h('li', a(data, { + staticClass: 'breadcrumb-item', + class: { + active: props.active + } + }), [h(BBreadcrumbLink, { + props: props + }, children)]); + } + }); + + var props$28 = makePropsConfigurable({ + items: makeProp(PROP_TYPE_ARRAY) + }, NAME_BREADCRUMB); // --- Main component --- + // @vue/component + + var BBreadcrumb = /*#__PURE__*/extend({ + name: NAME_BREADCRUMB, + functional: true, + props: props$28, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + var items = props.items; // Build child nodes from items, if given + + var childNodes = children; + + if (isArray(items)) { + var activeDefined = false; + childNodes = items.map(function (item, idx) { + if (!isObject(item)) { + item = { + text: toString(item) + }; + } // Copy the value here so we can normalize it + + + var _item = item, + active = _item.active; + + if (active) { + activeDefined = true; + } // Auto-detect active by position in list + + + if (!active && !activeDefined) { + active = idx + 1 === items.length; + } + + return h(BBreadcrumbItem, { + props: _objectSpread2$3(_objectSpread2$3({}, item), {}, { + active: active + }) + }); + }); + } + + return h('ol', a(data, { + staticClass: 'breadcrumb' + }), childNodes); + } + }); + + var BreadcrumbPlugin = /*#__PURE__*/pluginFactory({ + components: { + BBreadcrumb: BBreadcrumb, + BBreadcrumbItem: BBreadcrumbItem, + BBreadcrumbLink: BBreadcrumbLink + } + }); + + var ButtonPlugin = /*#__PURE__*/pluginFactory({ + components: { + BButton: BButton, + BBtn: BButton, + BButtonClose: BButtonClose, + BBtnClose: BButtonClose + } + }); + + var props$27 = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, pick$1(props$2e, ['size'])), {}, { + ariaRole: makeProp(PROP_TYPE_STRING, 'group'), + size: makeProp(PROP_TYPE_STRING), + tag: makeProp(PROP_TYPE_STRING, 'div'), + vertical: makeProp(PROP_TYPE_BOOLEAN, false) + })), NAME_BUTTON_GROUP); // --- Main component --- + // @vue/component + + var BButtonGroup = /*#__PURE__*/extend({ + name: NAME_BUTTON_GROUP, + functional: true, + props: props$27, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + return h(props.tag, a(data, { + class: _defineProperty({ + 'btn-group': !props.vertical, + 'btn-group-vertical': props.vertical + }, "btn-group-".concat(props.size), props.size), + attrs: { + role: props.ariaRole + } + }), children); + } + }); + + var ButtonGroupPlugin = /*#__PURE__*/pluginFactory({ + components: { + BButtonGroup: BButtonGroup, + BBtnGroup: BButtonGroup + } + }); + + var ITEM_SELECTOR = ['.btn:not(.disabled):not([disabled]):not(.dropdown-item)', '.form-control:not(.disabled):not([disabled])', 'select:not(.disabled):not([disabled])', 'input[type="checkbox"]:not(.disabled)', 'input[type="radio"]:not(.disabled)'].join(','); // --- Props --- + + var props$26 = makePropsConfigurable({ + justify: makeProp(PROP_TYPE_BOOLEAN, false), + keyNav: makeProp(PROP_TYPE_BOOLEAN, false) + }, NAME_BUTTON_TOOLBAR); // --- Main component --- + // @vue/component + + var BButtonToolbar = /*#__PURE__*/extend({ + name: NAME_BUTTON_TOOLBAR, + mixins: [normalizeSlotMixin], + props: props$26, + mounted: function mounted() { + // Pre-set the tabindexes if the markup does not include + // `tabindex="-1"` on the toolbar items + if (this.keyNav) { + this.getItems(); + } + }, + methods: { + getItems: function getItems() { + var items = selectAll(ITEM_SELECTOR, this.$el); // Ensure `tabindex="-1"` is set on every item + + items.forEach(function (item) { + item.tabIndex = -1; + }); + return items.filter(function (el) { + return isVisible(el); + }); + }, + focusFirst: function focusFirst() { + var items = this.getItems(); + attemptFocus(items[0]); + }, + focusPrev: function focusPrev(event) { + var items = this.getItems(); + var index = items.indexOf(event.target); + + if (index > -1) { + items = items.slice(0, index).reverse(); + attemptFocus(items[0]); + } + }, + focusNext: function focusNext(event) { + var items = this.getItems(); + var index = items.indexOf(event.target); + + if (index > -1) { + items = items.slice(index + 1); + attemptFocus(items[0]); + } + }, + focusLast: function focusLast() { + var items = this.getItems().reverse(); + attemptFocus(items[0]); + }, + onFocusin: function onFocusin(event) { + var $el = this.$el; + + if (event.target === $el && !contains($el, event.relatedTarget)) { + stopEvent(event); + this.focusFirst(event); + } + }, + onKeydown: function onKeydown(event) { + var keyCode = event.keyCode, + shiftKey = event.shiftKey; + + if (keyCode === CODE_UP || keyCode === CODE_LEFT) { + stopEvent(event); + shiftKey ? this.focusFirst(event) : this.focusPrev(event); + } else if (keyCode === CODE_DOWN || keyCode === CODE_RIGHT) { + stopEvent(event); + shiftKey ? this.focusLast(event) : this.focusNext(event); + } + } + }, + render: function render(h) { + var keyNav = this.keyNav; + return h('div', { + staticClass: 'btn-toolbar', + class: { + 'justify-content-between': this.justify + }, + attrs: { + role: 'toolbar', + tabindex: keyNav ? '0' : null + }, + on: keyNav ? { + focusin: this.onFocusin, + keydown: this.onKeydown + } : {} + }, [this.normalizeSlot()]); + } + }); + + var ButtonToolbarPlugin = /*#__PURE__*/pluginFactory({ + components: { + BButtonToolbar: BButtonToolbar, + BBtnToolbar: BButtonToolbar + } + }); + + var CALENDAR_GREGORY = 'gregory'; + var CALENDAR_LONG = 'long'; + var CALENDAR_NARROW = 'narrow'; + var CALENDAR_SHORT = 'short'; + var DATE_FORMAT_2_DIGIT = '2-digit'; + var DATE_FORMAT_NUMERIC = 'numeric'; + + // Create or clone a date (`new Date(...)` shortcut) + + var createDate = function createDate() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return _construct(Date, args); + }; // Parse a date sting, or Date object, into a Date object (with no time information) + + var parseYMD = function parseYMD(date) { + if (isString(date) && RX_DATE.test(date.trim())) { + var _date$split$map = date.split(RX_DATE_SPLIT).map(function (v) { + return toInteger(v, 1); + }), + _date$split$map2 = _slicedToArray(_date$split$map, 3), + year = _date$split$map2[0], + month = _date$split$map2[1], + day = _date$split$map2[2]; + + return createDate(year, month - 1, day); + } else if (isDate(date)) { + return createDate(date.getFullYear(), date.getMonth(), date.getDate()); + } + + return null; + }; // Format a date object as `YYYY-MM-DD` format + + var formatYMD = function formatYMD(date) { + date = parseYMD(date); + + if (!date) { + return null; + } + + var year = date.getFullYear(); + var month = "0".concat(date.getMonth() + 1).slice(-2); + var day = "0".concat(date.getDate()).slice(-2); + return "".concat(year, "-").concat(month, "-").concat(day); + }; // Given a locale (or locales), resolve the browser available locale + + var resolveLocale = function resolveLocale(locales) + /* istanbul ignore next */ + { + var calendar = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : CALENDAR_GREGORY; + locales = concat(locales).filter(identity); + var fmt = new Intl.DateTimeFormat(locales, { + calendar: calendar + }); + return fmt.resolvedOptions().locale; + }; // Create a `Intl.DateTimeFormat` formatter function + + var createDateFormatter = function createDateFormatter(locale, options) + /* istanbul ignore next */ + { + var dtf = new Intl.DateTimeFormat(locale, options); + return dtf.format; + }; // Determine if two dates are the same date (ignoring time portion) + + var datesEqual = function datesEqual(date1, date2) { + // Returns true of the date portion of two date objects are equal + // We don't compare the time portion + return formatYMD(date1) === formatYMD(date2); + }; // --- Date "math" utility methods (for BCalendar component mainly) --- + + var firstDateOfMonth = function firstDateOfMonth(date) { + date = createDate(date); + date.setDate(1); + return date; + }; + var lastDateOfMonth = function lastDateOfMonth(date) { + date = createDate(date); + date.setMonth(date.getMonth() + 1); + date.setDate(0); + return date; + }; + var addYears = function addYears(date, numberOfYears) { + date = createDate(date); + var month = date.getMonth(); + date.setFullYear(date.getFullYear() + numberOfYears); // Handle Feb 29th for leap years + + if (date.getMonth() !== month) { + date.setDate(0); + } + + return date; + }; + var oneMonthAgo = function oneMonthAgo(date) { + date = createDate(date); + var month = date.getMonth(); + date.setMonth(month - 1); // Handle when days in month are different + + if (date.getMonth() === month) { + date.setDate(0); + } + + return date; + }; + var oneMonthAhead = function oneMonthAhead(date) { + date = createDate(date); + var month = date.getMonth(); + date.setMonth(month + 1); // Handle when days in month are different + + if (date.getMonth() === (month + 2) % 12) { + date.setDate(0); + } + + return date; + }; + var oneYearAgo = function oneYearAgo(date) { + return addYears(date, -1); + }; + var oneYearAhead = function oneYearAhead(date) { + return addYears(date, 1); + }; + var oneDecadeAgo = function oneDecadeAgo(date) { + return addYears(date, -10); + }; + var oneDecadeAhead = function oneDecadeAhead(date) { + return addYears(date, 10); + }; // Helper function to constrain a date between two values + // Always returns a `Date` object or `null` if no date passed + + var constrainDate = function constrainDate(date) { + var min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + // Ensure values are `Date` objects (or `null`) + date = parseYMD(date); + min = parseYMD(min) || date; + max = parseYMD(max) || date; // Return a new `Date` object (or `null`) + + return date ? date < min ? min : date > max ? max : date : null; + }; + + // Localization utilities + + var RTL_LANGS = ['ar', 'az', 'ckb', 'fa', 'he', 'ks', 'lrc', 'mzn', 'ps', 'sd', 'te', 'ug', 'ur', 'yi'].map(function (locale) { + return locale.toLowerCase(); + }); // Returns true if the locale is RTL + + var isLocaleRTL = function isLocaleRTL(locale) { + // Determines if the locale is RTL (only single locale supported) + var parts = toString(locale).toLowerCase().replace(RX_STRIP_LOCALE_MODS, '').split('-'); + var locale1 = parts.slice(0, 2).join('-'); + var locale2 = parts[0]; + return arrayIncludes(RTL_LANGS, locale1) || arrayIncludes(RTL_LANGS, locale2); + }; + + // SSR safe client-side ID attribute generation + + var props$25 = { + id: makeProp(PROP_TYPE_STRING) + }; // --- Mixin --- + // @vue/component + + var idMixin = extend({ + props: props$25, + data: function data() { + return { + localId_: null + }; + }, + computed: { + safeId: function safeId() { + // Computed property that returns a dynamic function for creating the ID + // Reacts to changes in both `.id` and `.localId_` and regenerates a new function + var id = this.id || this.localId_; // We return a function that accepts an optional suffix string + // So this computed prop looks and works like a method + // but benefits from Vue's computed prop caching + + var fn = function fn(suffix) { + if (!id) { + return null; + } + + suffix = String(suffix || '').replace(/\s+/g, '_'); + return suffix ? id + '_' + suffix : id; + }; + + return fn; + } + }, + mounted: function mounted() { + var _this = this; + + // `mounted()` only occurs client-side + this.$nextTick(function () { + // Update DOM with auto-generated ID after mount + // to prevent SSR hydration errors + _this.localId_ = "__BVID__".concat(_this[COMPONENT_UID_KEY]); + }); + } + }); + + var _watch$j; + + var _makeModelMixin$j = makeModelMixin('value', { + type: PROP_TYPE_DATE_STRING + }), + modelMixin$i = _makeModelMixin$j.mixin, + modelProps$i = _makeModelMixin$j.props, + MODEL_PROP_NAME$i = _makeModelMixin$j.prop, + MODEL_EVENT_NAME$i = _makeModelMixin$j.event; // --- Props --- + + + var props$24 = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, props$25), modelProps$i), {}, { + ariaControls: makeProp(PROP_TYPE_STRING), + // Makes calendar the full width of its parent container + block: makeProp(PROP_TYPE_BOOLEAN, false), + dateDisabledFn: makeProp(PROP_TYPE_FUNCTION), + // `Intl.DateTimeFormat` object + dateFormatOptions: makeProp(PROP_TYPE_OBJECT, { + year: DATE_FORMAT_NUMERIC, + month: CALENDAR_LONG, + day: DATE_FORMAT_NUMERIC, + weekday: CALENDAR_LONG + }), + // Function to set a class of (classes) on the date cell + // if passed a string or an array + // TODO: + // If the function returns an object, look for class prop for classes, + // and other props for handling events/details/descriptions + dateInfoFn: makeProp(PROP_TYPE_FUNCTION), + // 'ltr', 'rtl', or `null` (for auto detect) + direction: makeProp(PROP_TYPE_STRING), + disabled: makeProp(PROP_TYPE_BOOLEAN, false), + headerTag: makeProp(PROP_TYPE_STRING, 'header'), + // When `true`, renders a comment node, but keeps the component instance active + // Mainly for , so that we can get the component's value and locale + // But we might just use separate date formatters, using the resolved locale + // (adjusted for the gregorian calendar) + hidden: makeProp(PROP_TYPE_BOOLEAN, false), + // When `true` makes the selected date header `sr-only` + hideHeader: makeProp(PROP_TYPE_BOOLEAN, false), + // This specifies the calendar year/month/day that will be shown when + // first opening the datepicker if no v-model value is provided + // Default is the current date (or `min`/`max`) + initialDate: makeProp(PROP_TYPE_DATE_STRING), + // Labels for buttons and keyboard shortcuts + labelCalendar: makeProp(PROP_TYPE_STRING, 'Calendar'), + labelCurrentMonth: makeProp(PROP_TYPE_STRING, 'Current month'), + labelHelp: makeProp(PROP_TYPE_STRING, 'Use cursor keys to navigate calendar dates'), + labelNav: makeProp(PROP_TYPE_STRING, 'Calendar navigation'), + labelNextDecade: makeProp(PROP_TYPE_STRING, 'Next decade'), + labelNextMonth: makeProp(PROP_TYPE_STRING, 'Next month'), + labelNextYear: makeProp(PROP_TYPE_STRING, 'Next year'), + labelNoDateSelected: makeProp(PROP_TYPE_STRING, 'No date selected'), + labelPrevDecade: makeProp(PROP_TYPE_STRING, 'Previous decade'), + labelPrevMonth: makeProp(PROP_TYPE_STRING, 'Previous month'), + labelPrevYear: makeProp(PROP_TYPE_STRING, 'Previous year'), + labelSelected: makeProp(PROP_TYPE_STRING, 'Selected date'), + labelToday: makeProp(PROP_TYPE_STRING, 'Today'), + // Locale(s) to use + // Default is to use page/browser default setting + locale: makeProp(PROP_TYPE_ARRAY_STRING), + max: makeProp(PROP_TYPE_DATE_STRING), + min: makeProp(PROP_TYPE_DATE_STRING), + // Variant color to use for the navigation buttons + navButtonVariant: makeProp(PROP_TYPE_STRING, 'secondary'), + // Disable highlighting today's date + noHighlightToday: makeProp(PROP_TYPE_BOOLEAN, false), + noKeyNav: makeProp(PROP_TYPE_BOOLEAN, false), + readonly: makeProp(PROP_TYPE_BOOLEAN, false), + roleDescription: makeProp(PROP_TYPE_STRING), + // Variant color to use for the selected date + selectedVariant: makeProp(PROP_TYPE_STRING, 'primary'), + // When `true` enables the decade navigation buttons + showDecadeNav: makeProp(PROP_TYPE_BOOLEAN, false), + // Day of week to start calendar on + // `0` (Sunday), `1` (Monday), ... `6` (Saturday) + startWeekday: makeProp(PROP_TYPE_NUMBER_STRING, 0), + // Variant color to use for today's date (defaults to `selectedVariant`) + todayVariant: makeProp(PROP_TYPE_STRING), + // Always return the `v-model` value as a date object + valueAsDate: makeProp(PROP_TYPE_BOOLEAN, false), + // Format of the weekday names at the top of the calendar + // `short` is typically a 3 letter abbreviation, + // `narrow` is typically a single letter + // `long` is the full week day name + // Although some locales may override this (i.e `ar`, etc.) + weekdayHeaderFormat: makeProp(PROP_TYPE_STRING, CALENDAR_SHORT, function (value) { + return arrayIncludes([CALENDAR_LONG, CALENDAR_SHORT, CALENDAR_NARROW], value); + }), + // Has no effect if prop `block` is set + width: makeProp(PROP_TYPE_STRING, '270px') + })), NAME_CALENDAR); // --- Main component --- + // @vue/component + + var BCalendar = extend({ + name: NAME_CALENDAR, + // Mixin order is important! + mixins: [attrsMixin, idMixin, modelMixin$i, normalizeSlotMixin], + props: props$24, + data: function data() { + var selected = formatYMD(this[MODEL_PROP_NAME$i]) || ''; + return { + // Selected date + selectedYMD: selected, + // Date in calendar grid that has `tabindex` of `0` + activeYMD: selected || formatYMD(constrainDate(this.initialDate || this.getToday()), this.min, this.max), + // Will be true if the calendar grid has/contains focus + gridHasFocus: false, + // Flag to enable the `aria-live` region(s) after mount + // to prevent screen reader "outbursts" when mounting + isLive: false + }; + }, + computed: { + valueId: function valueId() { + return this.safeId(); + }, + widgetId: function widgetId() { + return this.safeId('_calendar-wrapper_'); + }, + navId: function navId() { + return this.safeId('_calendar-nav_'); + }, + gridId: function gridId() { + return this.safeId('_calendar-grid_'); + }, + gridCaptionId: function gridCaptionId() { + return this.safeId('_calendar-grid-caption_'); + }, + gridHelpId: function gridHelpId() { + return this.safeId('_calendar-grid-help_'); + }, + activeId: function activeId() { + return this.activeYMD ? this.safeId("_cell-".concat(this.activeYMD, "_")) : null; + }, + // TODO: Use computed props to convert `YYYY-MM-DD` to `Date` object + selectedDate: function selectedDate() { + // Selected as a `Date` object + return parseYMD(this.selectedYMD); + }, + activeDate: function activeDate() { + // Active as a `Date` object + return parseYMD(this.activeYMD); + }, + computedMin: function computedMin() { + return parseYMD(this.min); + }, + computedMax: function computedMax() { + return parseYMD(this.max); + }, + computedWeekStarts: function computedWeekStarts() { + // `startWeekday` is a prop (constrained to `0` through `6`) + return mathMax(toInteger(this.startWeekday, 0), 0) % 7; + }, + computedLocale: function computedLocale() { + // Returns the resolved locale used by the calendar + return resolveLocale(concat(this.locale).filter(identity), CALENDAR_GREGORY); + }, + computedDateDisabledFn: function computedDateDisabledFn() { + var dateDisabledFn = this.dateDisabledFn; + return hasPropFunction(dateDisabledFn) ? dateDisabledFn : function () { + return false; + }; + }, + // TODO: Change `dateInfoFn` to handle events and notes as well as classes + computedDateInfoFn: function computedDateInfoFn() { + var dateInfoFn = this.dateInfoFn; + return hasPropFunction(dateInfoFn) ? dateInfoFn : function () { + return {}; + }; + }, + calendarLocale: function calendarLocale() { + // This locale enforces the gregorian calendar (for use in formatter functions) + // Needed because IE 11 resolves `ar-IR` as islamic-civil calendar + // and IE 11 (and some other browsers) do not support the `calendar` option + // And we currently only support the gregorian calendar + var fmt = new Intl.DateTimeFormat(this.computedLocale, { + calendar: CALENDAR_GREGORY + }); + var calendar = fmt.resolvedOptions().calendar; + var locale = fmt.resolvedOptions().locale; + /* istanbul ignore if: mainly for IE 11 and a few other browsers, hard to test in JSDOM */ + + if (calendar !== CALENDAR_GREGORY) { + // Ensure the locale requests the gregorian calendar + // Mainly for IE 11, and currently we can't handle non-gregorian calendars + // TODO: Should we always return this value? + locale = locale.replace(/-u-.+$/i, '').concat('-u-ca-gregory'); + } + + return locale; + }, + calendarYear: function calendarYear() { + return this.activeDate.getFullYear(); + }, + calendarMonth: function calendarMonth() { + return this.activeDate.getMonth(); + }, + calendarFirstDay: function calendarFirstDay() { + // We set the time for this date to 12pm to work around + // date formatting issues in Firefox and Safari + // See: https://github.com/bootstrap-vue/bootstrap-vue/issues/5818 + return createDate(this.calendarYear, this.calendarMonth, 1, 12); + }, + calendarDaysInMonth: function calendarDaysInMonth() { + // We create a new date as to not mutate the original + var date = createDate(this.calendarFirstDay); + date.setMonth(date.getMonth() + 1, 0); + return date.getDate(); + }, + computedVariant: function computedVariant() { + return "btn-".concat(this.selectedVariant || 'primary'); + }, + computedTodayVariant: function computedTodayVariant() { + return "btn-outline-".concat(this.todayVariant || this.selectedVariant || 'primary'); + }, + computedNavButtonVariant: function computedNavButtonVariant() { + return "btn-outline-".concat(this.navButtonVariant || 'primary'); + }, + isRTL: function isRTL() { + // `true` if the language requested is RTL + var dir = toString(this.direction).toLowerCase(); + + if (dir === 'rtl') { + /* istanbul ignore next */ + return true; + } else if (dir === 'ltr') { + /* istanbul ignore next */ + return false; + } + + return isLocaleRTL(this.computedLocale); + }, + context: function context() { + var selectedYMD = this.selectedYMD, + activeYMD = this.activeYMD; + var selectedDate = parseYMD(selectedYMD); + var activeDate = parseYMD(activeYMD); + return { + // The current value of the `v-model` + selectedYMD: selectedYMD, + selectedDate: selectedDate, + selectedFormatted: selectedDate ? this.formatDateString(selectedDate) : this.labelNoDateSelected, + // Which date cell is considered active due to navigation + activeYMD: activeYMD, + activeDate: activeDate, + activeFormatted: activeDate ? this.formatDateString(activeDate) : '', + // `true` if the date is disabled (when using keyboard navigation) + disabled: this.dateDisabled(activeDate), + // Locales used in formatting dates + locale: this.computedLocale, + calendarLocale: this.calendarLocale, + rtl: this.isRTL + }; + }, + // Computed props that return a function reference + dateOutOfRange: function dateOutOfRange() { + // Check whether a date is within the min/max range + // Returns a new function ref if the pops change + // We do this as we need to trigger the calendar computed prop + // to update when these props update + var min = this.computedMin, + max = this.computedMax; + return function (date) { + // Handle both `YYYY-MM-DD` and `Date` objects + date = parseYMD(date); + return min && date < min || max && date > max; + }; + }, + dateDisabled: function dateDisabled() { + var _this = this; + + // Returns a function for validating if a date is within range + // We grab this variables first to ensure a new function ref + // is generated when the props value changes + // We do this as we need to trigger the calendar computed prop + // to update when these props update + var rangeFn = this.dateOutOfRange; // Return the function ref + + return function (date) { + // Handle both `YYYY-MM-DD` and `Date` objects + date = parseYMD(date); + var ymd = formatYMD(date); + return !!(rangeFn(date) || _this.computedDateDisabledFn(ymd, date)); + }; + }, + // Computed props that return date formatter functions + formatDateString: function formatDateString() { + // Returns a date formatter function + return createDateFormatter(this.calendarLocale, _objectSpread2$3(_objectSpread2$3({ + // Ensure we have year, month, day shown for screen readers/ARIA + // If users really want to leave one of these out, they can + // pass `undefined` for the property value + year: DATE_FORMAT_NUMERIC, + month: DATE_FORMAT_2_DIGIT, + day: DATE_FORMAT_2_DIGIT + }, this.dateFormatOptions), {}, { + // Ensure hours/minutes/seconds are not shown + // As we do not support the time portion (yet) + hour: undefined, + minute: undefined, + second: undefined, + // Ensure calendar is gregorian + calendar: CALENDAR_GREGORY + })); + }, + formatYearMonth: function formatYearMonth() { + // Returns a date formatter function + return createDateFormatter(this.calendarLocale, { + year: DATE_FORMAT_NUMERIC, + month: CALENDAR_LONG, + calendar: CALENDAR_GREGORY + }); + }, + formatWeekdayName: function formatWeekdayName() { + // Long weekday name for weekday header aria-label + return createDateFormatter(this.calendarLocale, { + weekday: CALENDAR_LONG, + calendar: CALENDAR_GREGORY + }); + }, + formatWeekdayNameShort: function formatWeekdayNameShort() { + // Weekday header cell format + // defaults to 'short' 3 letter days, where possible + return createDateFormatter(this.calendarLocale, { + weekday: this.weekdayHeaderFormat || CALENDAR_SHORT, + calendar: CALENDAR_GREGORY + }); + }, + formatDay: function formatDay() { + // Calendar grid day number formatter + // We don't use DateTimeFormatter here as it can place extra + // character(s) after the number (i.e the `zh` locale) + var nf = new Intl.NumberFormat([this.computedLocale], { + style: 'decimal', + minimumIntegerDigits: 1, + minimumFractionDigits: 0, + maximumFractionDigits: 0, + notation: 'standard' + }); // Return a formatter function instance + + return function (date) { + return nf.format(date.getDate()); + }; + }, + // Disabled states for the nav buttons + prevDecadeDisabled: function prevDecadeDisabled() { + var min = this.computedMin; + return this.disabled || min && lastDateOfMonth(oneDecadeAgo(this.activeDate)) < min; + }, + prevYearDisabled: function prevYearDisabled() { + var min = this.computedMin; + return this.disabled || min && lastDateOfMonth(oneYearAgo(this.activeDate)) < min; + }, + prevMonthDisabled: function prevMonthDisabled() { + var min = this.computedMin; + return this.disabled || min && lastDateOfMonth(oneMonthAgo(this.activeDate)) < min; + }, + thisMonthDisabled: function thisMonthDisabled() { + // TODO: We could/should check if today is out of range + return this.disabled; + }, + nextMonthDisabled: function nextMonthDisabled() { + var max = this.computedMax; + return this.disabled || max && firstDateOfMonth(oneMonthAhead(this.activeDate)) > max; + }, + nextYearDisabled: function nextYearDisabled() { + var max = this.computedMax; + return this.disabled || max && firstDateOfMonth(oneYearAhead(this.activeDate)) > max; + }, + nextDecadeDisabled: function nextDecadeDisabled() { + var max = this.computedMax; + return this.disabled || max && firstDateOfMonth(oneDecadeAhead(this.activeDate)) > max; + }, + // Calendar dates generation + calendar: function calendar() { + var matrix = []; + var firstDay = this.calendarFirstDay; + var calendarYear = firstDay.getFullYear(); + var calendarMonth = firstDay.getMonth(); + var daysInMonth = this.calendarDaysInMonth; + var startIndex = firstDay.getDay(); // `0`..`6` + + var weekOffset = (this.computedWeekStarts > startIndex ? 7 : 0) - this.computedWeekStarts; // Build the calendar matrix + + var currentDay = 0 - weekOffset - startIndex; + + for (var week = 0; week < 6 && currentDay < daysInMonth; week++) { + // For each week + matrix[week] = []; // The following could be a map function + + for (var j = 0; j < 7; j++) { + // For each day in week + currentDay++; + var date = createDate(calendarYear, calendarMonth, currentDay); + var month = date.getMonth(); + var dayYMD = formatYMD(date); + var dayDisabled = this.dateDisabled(date); // TODO: This could be a normalizer method + + var dateInfo = this.computedDateInfoFn(dayYMD, parseYMD(dayYMD)); + dateInfo = isString(dateInfo) || isArray(dateInfo) ? + /* istanbul ignore next */ + { + class: dateInfo + } : isPlainObject(dateInfo) ? _objectSpread2$3({ + class: '' + }, dateInfo) : + /* istanbul ignore next */ + { + class: '' + }; + matrix[week].push({ + ymd: dayYMD, + // Cell content + day: this.formatDay(date), + label: this.formatDateString(date), + // Flags for styling + isThisMonth: month === calendarMonth, + isDisabled: dayDisabled, + // TODO: Handle other dateInfo properties such as notes/events + info: dateInfo + }); + } + } + + return matrix; + }, + calendarHeadings: function calendarHeadings() { + var _this2 = this; + + return this.calendar[0].map(function (d) { + return { + text: _this2.formatWeekdayNameShort(parseYMD(d.ymd)), + label: _this2.formatWeekdayName(parseYMD(d.ymd)) + }; + }); + } + }, + watch: (_watch$j = {}, _defineProperty(_watch$j, MODEL_PROP_NAME$i, function (newValue, oldValue) { + var selected = formatYMD(newValue) || ''; + var old = formatYMD(oldValue) || ''; + + if (!datesEqual(selected, old)) { + this.activeYMD = selected || this.activeYMD; + this.selectedYMD = selected; + } + }), _defineProperty(_watch$j, "selectedYMD", function selectedYMD(newYMD, oldYMD) { + // TODO: + // Should we compare to `formatYMD(this.value)` and emit + // only if they are different? + if (newYMD !== oldYMD) { + this.$emit(MODEL_EVENT_NAME$i, this.valueAsDate ? parseYMD(newYMD) || null : newYMD || ''); + } + }), _defineProperty(_watch$j, "context", function context(newValue, oldValue) { + if (!looseEqual(newValue, oldValue)) { + this.$emit(EVENT_NAME_CONTEXT, newValue); + } + }), _defineProperty(_watch$j, "hidden", function hidden(newValue) { + // Reset the active focused day when hidden + this.activeYMD = this.selectedYMD || formatYMD(this[MODEL_PROP_NAME$i] || this.constrainDate(this.initialDate || this.getToday())); // Enable/disable the live regions + + this.setLive(!newValue); + }), _watch$j), + created: function created() { + var _this3 = this; + + this.$nextTick(function () { + _this3.$emit(EVENT_NAME_CONTEXT, _this3.context); + }); + }, + mounted: function mounted() { + this.setLive(true); + }, + + /* istanbul ignore next */ + activated: function activated() { + this.setLive(true); + }, + + /* istanbul ignore next */ + deactivated: function deactivated() { + this.setLive(false); + }, + beforeDestroy: function beforeDestroy() { + this.setLive(false); + }, + methods: { + // Public method(s) + focus: function focus() { + if (!this.disabled) { + attemptFocus(this.$refs.grid); + } + }, + blur: function blur() { + if (!this.disabled) { + attemptBlur(this.$refs.grid); + } + }, + // Private methods + setLive: function setLive(on) { + var _this4 = this; + + if (on) { + this.$nextTick(function () { + requestAF(function () { + _this4.isLive = true; + }); + }); + } else { + this.isLive = false; + } + }, + getToday: function getToday() { + return parseYMD(createDate()); + }, + constrainDate: function constrainDate$1(date) { + // Constrains a date between min and max + // returns a new `Date` object instance + return constrainDate(date, this.computedMin, this.computedMax); + }, + emitSelected: function emitSelected(date) { + var _this5 = this; + + // Performed in a `$nextTick()` to (probably) ensure + // the input event has emitted first + this.$nextTick(function () { + _this5.$emit(EVENT_NAME_SELECTED, formatYMD(date) || '', parseYMD(date) || null); + }); + }, + // Event handlers + setGridFocusFlag: function setGridFocusFlag(event) { + // Sets the gridHasFocus flag to make date "button" look focused + this.gridHasFocus = !this.disabled && event.type === 'focus'; + }, + onKeydownWrapper: function onKeydownWrapper(event) { + // Calendar keyboard navigation + // Handles PAGEUP/PAGEDOWN/END/HOME/LEFT/UP/RIGHT/DOWN + // Focuses grid after updating + if (this.noKeyNav) { + /* istanbul ignore next */ + return; + } + + var altKey = event.altKey, + ctrlKey = event.ctrlKey, + keyCode = event.keyCode; + + if (!arrayIncludes([CODE_PAGEUP, CODE_PAGEDOWN, CODE_END, CODE_HOME, CODE_LEFT, CODE_UP, CODE_RIGHT, CODE_DOWN], keyCode)) { + /* istanbul ignore next */ + return; + } + + stopEvent(event); + var activeDate = createDate(this.activeDate); + var checkDate = createDate(this.activeDate); + var day = activeDate.getDate(); + var constrainedToday = this.constrainDate(this.getToday()); + var isRTL = this.isRTL; + + if (keyCode === CODE_PAGEUP) { + // PAGEUP - Previous month/year + activeDate = (altKey ? ctrlKey ? oneDecadeAgo : oneYearAgo : oneMonthAgo)(activeDate); // We check the first day of month to be in rage + + checkDate = createDate(activeDate); + checkDate.setDate(1); + } else if (keyCode === CODE_PAGEDOWN) { + // PAGEDOWN - Next month/year + activeDate = (altKey ? ctrlKey ? oneDecadeAhead : oneYearAhead : oneMonthAhead)(activeDate); // We check the last day of month to be in rage + + checkDate = createDate(activeDate); + checkDate.setMonth(checkDate.getMonth() + 1); + checkDate.setDate(0); + } else if (keyCode === CODE_LEFT) { + // LEFT - Previous day (or next day for RTL) + activeDate.setDate(day + (isRTL ? 1 : -1)); + activeDate = this.constrainDate(activeDate); + checkDate = activeDate; + } else if (keyCode === CODE_RIGHT) { + // RIGHT - Next day (or previous day for RTL) + activeDate.setDate(day + (isRTL ? -1 : 1)); + activeDate = this.constrainDate(activeDate); + checkDate = activeDate; + } else if (keyCode === CODE_UP) { + // UP - Previous week + activeDate.setDate(day - 7); + activeDate = this.constrainDate(activeDate); + checkDate = activeDate; + } else if (keyCode === CODE_DOWN) { + // DOWN - Next week + activeDate.setDate(day + 7); + activeDate = this.constrainDate(activeDate); + checkDate = activeDate; + } else if (keyCode === CODE_HOME) { + // HOME - Today + activeDate = constrainedToday; + checkDate = activeDate; + } else if (keyCode === CODE_END) { + // END - Selected date, or today if no selected date + activeDate = parseYMD(this.selectedDate) || constrainedToday; + checkDate = activeDate; + } + + if (!this.dateOutOfRange(checkDate) && !datesEqual(activeDate, this.activeDate)) { + // We only jump to date if within min/max + // We don't check for individual disabled dates though (via user function) + this.activeYMD = formatYMD(activeDate); + } // Ensure grid is focused + + + this.focus(); + }, + onKeydownGrid: function onKeydownGrid(event) { + // Pressing enter/space on grid to select active date + var keyCode = event.keyCode; + var activeDate = this.activeDate; + + if (keyCode === CODE_ENTER || keyCode === CODE_SPACE) { + stopEvent(event); + + if (!this.disabled && !this.readonly && !this.dateDisabled(activeDate)) { + this.selectedYMD = formatYMD(activeDate); + this.emitSelected(activeDate); + } // Ensure grid is focused + + + this.focus(); + } + }, + onClickDay: function onClickDay(day) { + // Clicking on a date "button" to select it + var selectedDate = this.selectedDate, + activeDate = this.activeDate; + var clickedDate = parseYMD(day.ymd); + + if (!this.disabled && !day.isDisabled && !this.dateDisabled(clickedDate)) { + if (!this.readonly) { + // If readonly mode, we don't set the selected date, just the active date + // If the clicked date is equal to the already selected date, we don't update the model + this.selectedYMD = formatYMD(datesEqual(clickedDate, selectedDate) ? selectedDate : clickedDate); + this.emitSelected(clickedDate); + } + + this.activeYMD = formatYMD(datesEqual(clickedDate, activeDate) ? activeDate : createDate(clickedDate)); // Ensure grid is focused + + this.focus(); + } + }, + gotoPrevDecade: function gotoPrevDecade() { + this.activeYMD = formatYMD(this.constrainDate(oneDecadeAgo(this.activeDate))); + }, + gotoPrevYear: function gotoPrevYear() { + this.activeYMD = formatYMD(this.constrainDate(oneYearAgo(this.activeDate))); + }, + gotoPrevMonth: function gotoPrevMonth() { + this.activeYMD = formatYMD(this.constrainDate(oneMonthAgo(this.activeDate))); + }, + gotoCurrentMonth: function gotoCurrentMonth() { + // TODO: Maybe this goto date should be configurable? + this.activeYMD = formatYMD(this.constrainDate(this.getToday())); + }, + gotoNextMonth: function gotoNextMonth() { + this.activeYMD = formatYMD(this.constrainDate(oneMonthAhead(this.activeDate))); + }, + gotoNextYear: function gotoNextYear() { + this.activeYMD = formatYMD(this.constrainDate(oneYearAhead(this.activeDate))); + }, + gotoNextDecade: function gotoNextDecade() { + this.activeYMD = formatYMD(this.constrainDate(oneDecadeAhead(this.activeDate))); + }, + onHeaderClick: function onHeaderClick() { + if (!this.disabled) { + this.activeYMD = this.selectedYMD || formatYMD(this.getToday()); + this.focus(); + } + } + }, + render: function render(h) { + var _this6 = this; + + // If `hidden` prop is set, render just a placeholder node + if (this.hidden) { + return h(); + } + + var valueId = this.valueId, + widgetId = this.widgetId, + navId = this.navId, + gridId = this.gridId, + gridCaptionId = this.gridCaptionId, + gridHelpId = this.gridHelpId, + activeId = this.activeId, + disabled = this.disabled, + noKeyNav = this.noKeyNav, + isLive = this.isLive, + isRTL = this.isRTL, + activeYMD = this.activeYMD, + selectedYMD = this.selectedYMD, + safeId = this.safeId; + var hideDecadeNav = !this.showDecadeNav; + var todayYMD = formatYMD(this.getToday()); + var highlightToday = !this.noHighlightToday; // Header showing current selected date + + var $header = h('output', { + staticClass: 'form-control form-control-sm text-center', + class: { + 'text-muted': disabled, + readonly: this.readonly || disabled + }, + attrs: { + id: valueId, + for: gridId, + role: 'status', + tabindex: disabled ? null : '-1', + // Mainly for testing purposes, as we do not know + // the exact format `Intl` will format the date string + 'data-selected': toString(selectedYMD), + // We wait until after mount to enable `aria-live` + // to prevent initial announcement on page render + 'aria-live': isLive ? 'polite' : 'off', + 'aria-atomic': isLive ? 'true' : null + }, + on: { + // Transfer focus/click to focus grid + // and focus active date (or today if no selection) + click: this.onHeaderClick, + focus: this.onHeaderClick + } + }, this.selectedDate ? [// We use `bdi` elements here in case the label doesn't match the locale + // Although IE 11 does not deal with at all (equivalent to a span) + h('bdi', { + staticClass: 'sr-only' + }, " (".concat(toString(this.labelSelected), ") ")), h('bdi', this.formatDateString(this.selectedDate))] : this.labelNoDateSelected || "\xA0" // ' ' + ); + $header = h(this.headerTag, { + staticClass: 'b-calendar-header', + class: { + 'sr-only': this.hideHeader + }, + attrs: { + title: this.selectedDate ? this.labelSelected || null : null + } + }, [$header]); // Content for the date navigation buttons + + var navScope = { + isRTL: isRTL + }; + var navProps = { + shiftV: 0.5 + }; + + var navPrevProps = _objectSpread2$3(_objectSpread2$3({}, navProps), {}, { + flipH: isRTL + }); + + var navNextProps = _objectSpread2$3(_objectSpread2$3({}, navProps), {}, { + flipH: !isRTL + }); + + var $prevDecadeIcon = this.normalizeSlot(SLOT_NAME_NAV_PEV_DECADE, navScope) || h(BIconChevronBarLeft, { + props: navPrevProps + }); + var $prevYearIcon = this.normalizeSlot(SLOT_NAME_NAV_PEV_YEAR, navScope) || h(BIconChevronDoubleLeft, { + props: navPrevProps + }); + var $prevMonthIcon = this.normalizeSlot(SLOT_NAME_NAV_PEV_MONTH, navScope) || h(BIconChevronLeft, { + props: navPrevProps + }); + var $thisMonthIcon = this.normalizeSlot(SLOT_NAME_NAV_THIS_MONTH, navScope) || h(BIconCircleFill, { + props: navProps + }); + var $nextMonthIcon = this.normalizeSlot(SLOT_NAME_NAV_NEXT_MONTH, navScope) || h(BIconChevronLeft, { + props: navNextProps + }); + var $nextYearIcon = this.normalizeSlot(SLOT_NAME_NAV_NEXT_YEAR, navScope) || h(BIconChevronDoubleLeft, { + props: navNextProps + }); + var $nextDecadeIcon = this.normalizeSlot(SLOT_NAME_NAV_NEXT_DECADE, navScope) || h(BIconChevronBarLeft, { + props: navNextProps + }); // Utility to create the date navigation buttons + + var makeNavBtn = function makeNavBtn(content, label, handler, btnDisabled, shortcut) { + return h('button', { + staticClass: 'btn btn-sm border-0 flex-fill', + class: [_this6.computedNavButtonVariant, { + disabled: btnDisabled + }], + attrs: { + title: label || null, + type: 'button', + tabindex: noKeyNav ? '-1' : null, + 'aria-label': label || null, + 'aria-disabled': btnDisabled ? 'true' : null, + 'aria-keyshortcuts': shortcut || null + }, + on: btnDisabled ? {} : { + click: handler + } + }, [h('div', { + attrs: { + 'aria-hidden': 'true' + } + }, [content])]); + }; // Generate the date navigation buttons + + + var $nav = h('div', { + staticClass: 'b-calendar-nav d-flex', + attrs: { + id: navId, + role: 'group', + tabindex: noKeyNav ? '-1' : null, + 'aria-hidden': disabled ? 'true' : null, + 'aria-label': this.labelNav || null, + 'aria-controls': gridId + } + }, [hideDecadeNav ? h() : makeNavBtn($prevDecadeIcon, this.labelPrevDecade, this.gotoPrevDecade, this.prevDecadeDisabled, 'Ctrl+Alt+PageDown'), makeNavBtn($prevYearIcon, this.labelPrevYear, this.gotoPrevYear, this.prevYearDisabled, 'Alt+PageDown'), makeNavBtn($prevMonthIcon, this.labelPrevMonth, this.gotoPrevMonth, this.prevMonthDisabled, 'PageDown'), makeNavBtn($thisMonthIcon, this.labelCurrentMonth, this.gotoCurrentMonth, this.thisMonthDisabled, 'Home'), makeNavBtn($nextMonthIcon, this.labelNextMonth, this.gotoNextMonth, this.nextMonthDisabled, 'PageUp'), makeNavBtn($nextYearIcon, this.labelNextYear, this.gotoNextYear, this.nextYearDisabled, 'Alt+PageUp'), hideDecadeNav ? h() : makeNavBtn($nextDecadeIcon, this.labelNextDecade, this.gotoNextDecade, this.nextDecadeDisabled, 'Ctrl+Alt+PageUp')]); // Caption for calendar grid + + var $gridCaption = h('div', { + staticClass: 'b-calendar-grid-caption text-center font-weight-bold', + class: { + 'text-muted': disabled + }, + attrs: { + id: gridCaptionId, + 'aria-live': isLive ? 'polite' : null, + 'aria-atomic': isLive ? 'true' : null + }, + key: 'grid-caption' + }, this.formatYearMonth(this.calendarFirstDay)); // Calendar weekday headings + + var $gridWeekDays = h('div', { + staticClass: 'b-calendar-grid-weekdays row no-gutters border-bottom', + attrs: { + 'aria-hidden': 'true' + } + }, this.calendarHeadings.map(function (d, idx) { + return h('small', { + staticClass: 'col text-truncate', + class: { + 'text-muted': disabled + }, + attrs: { + title: d.label === d.text ? null : d.label, + 'aria-label': d.label + }, + key: idx + }, d.text); + })); // Calendar day grid + + var $gridBody = this.calendar.map(function (week) { + var $cells = week.map(function (day, dIndex) { + var _class; + + var isSelected = day.ymd === selectedYMD; + var isActive = day.ymd === activeYMD; + var isToday = day.ymd === todayYMD; + var idCell = safeId("_cell-".concat(day.ymd, "_")); // "fake" button + + var $btn = h('span', { + staticClass: 'btn border-0 rounded-circle text-nowrap', + // Should we add some classes to signify if today/selected/etc? + class: (_class = { + // Give the fake button a focus ring + focus: isActive && _this6.gridHasFocus, + // Styling + disabled: day.isDisabled || disabled, + active: isSelected + }, _defineProperty(_class, _this6.computedVariant, isSelected), _defineProperty(_class, _this6.computedTodayVariant, isToday && highlightToday && !isSelected && day.isThisMonth), _defineProperty(_class, 'btn-outline-light', !(isToday && highlightToday) && !isSelected && !isActive), _defineProperty(_class, 'btn-light', !(isToday && highlightToday) && !isSelected && isActive), _defineProperty(_class, 'text-muted', !day.isThisMonth && !isSelected), _defineProperty(_class, 'text-dark', !(isToday && highlightToday) && !isSelected && !isActive && day.isThisMonth), _defineProperty(_class, 'font-weight-bold', (isSelected || day.isThisMonth) && !day.isDisabled), _class), + on: { + click: function click() { + return _this6.onClickDay(day); + } + } + }, day.day); + return h('div', // Cell with button + { + staticClass: 'col p-0', + class: day.isDisabled ? 'bg-light' : day.info.class || '', + attrs: { + id: idCell, + role: 'button', + 'data-date': day.ymd, + // Primarily for testing purposes + // Only days in the month are presented as buttons to screen readers + 'aria-hidden': day.isThisMonth ? null : 'true', + 'aria-disabled': day.isDisabled || disabled ? 'true' : null, + 'aria-label': [day.label, isSelected ? "(".concat(_this6.labelSelected, ")") : null, isToday ? "(".concat(_this6.labelToday, ")") : null].filter(identity).join(' '), + // NVDA doesn't convey `aria-selected`, but does `aria-current`, + // ChromeVox doesn't convey `aria-current`, but does `aria-selected`, + // so we set both attributes for robustness + 'aria-selected': isSelected ? 'true' : null, + 'aria-current': isSelected ? 'date' : null + }, + key: dIndex + }, [$btn]); + }); // Return the week "row" + // We use the first day of the weeks YMD value as a + // key for efficient DOM patching / element re-use + + return h('div', { + staticClass: 'row no-gutters', + key: week[0].ymd + }, $cells); + }); + $gridBody = h('div', { + // A key is only required on the body if we add in transition support + staticClass: 'b-calendar-grid-body', + style: disabled ? { + pointerEvents: 'none' + } : {} // key: this.activeYMD.slice(0, -3) + + }, $gridBody); + var $gridHelp = h('div', { + staticClass: 'b-calendar-grid-help border-top small text-muted text-center bg-light', + attrs: { + id: gridHelpId + } + }, [h('div', { + staticClass: 'small' + }, this.labelHelp)]); + var $grid = h('div', { + staticClass: 'b-calendar-grid form-control h-auto text-center', + attrs: { + id: gridId, + role: 'application', + tabindex: noKeyNav ? '-1' : disabled ? null : '0', + 'data-month': activeYMD.slice(0, -3), + // `YYYY-MM`, mainly for testing + 'aria-roledescription': this.labelCalendar || null, + 'aria-labelledby': gridCaptionId, + 'aria-describedby': gridHelpId, + // `aria-readonly` is not considered valid on `role="application"` + // https://www.w3.org/TR/wai-aria-1.1/#aria-readonly + // 'aria-readonly': this.readonly && !disabled ? 'true' : null, + 'aria-disabled': disabled ? 'true' : null, + 'aria-activedescendant': activeId + }, + on: { + keydown: this.onKeydownGrid, + focus: this.setGridFocusFlag, + blur: this.setGridFocusFlag + }, + ref: 'grid' + }, [$gridCaption, $gridWeekDays, $gridBody, $gridHelp]); // Optional bottom slot + + var $slot = this.normalizeSlot(); + $slot = $slot ? h('footer', { + staticClass: 'b-calendar-footer' + }, $slot) : h(); + var $widget = h('div', { + staticClass: 'b-calendar-inner', + style: this.block ? {} : { + width: this.width + }, + attrs: { + id: widgetId, + dir: isRTL ? 'rtl' : 'ltr', + lang: this.computedLocale || null, + role: 'group', + 'aria-disabled': disabled ? 'true' : null, + // If datepicker controls an input, this will specify the ID of the input + 'aria-controls': this.ariaControls || null, + // This should be a prop (so it can be changed to Date picker, etc, localized + 'aria-roledescription': this.roleDescription || null, + 'aria-describedby': [// Should the attr (if present) go last? + // Or should this attr be a prop? + this.bvAttrs['aria-describedby'], valueId, gridHelpId].filter(identity).join(' ') + }, + on: { + keydown: this.onKeydownWrapper + } + }, [$header, $nav, $grid, $slot]); // Wrap in an outer div that can be styled + + return h('div', { + staticClass: 'b-calendar', + class: { + 'd-block': this.block + } + }, [$widget]); + } + }); + + var CalendarPlugin = /*#__PURE__*/pluginFactory({ + components: { + BCalendar: BCalendar + } + }); + + var props$23 = makePropsConfigurable({ + bgVariant: makeProp(PROP_TYPE_STRING), + borderVariant: makeProp(PROP_TYPE_STRING), + tag: makeProp(PROP_TYPE_STRING, 'div'), + textVariant: makeProp(PROP_TYPE_STRING) + }, NAME_CARD); // --- Mixin --- + // @vue/component + + extend({ + props: props$23 + }); + + var props$22 = makePropsConfigurable({ + title: makeProp(PROP_TYPE_STRING), + titleTag: makeProp(PROP_TYPE_STRING, 'h4') + }, NAME_CARD_TITLE); // --- Main component --- + // @vue/component + + var BCardTitle = /*#__PURE__*/extend({ + name: NAME_CARD_TITLE, + functional: true, + props: props$22, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + return h(props.titleTag, a(data, { + staticClass: 'card-title' + }), children || toString(props.title)); + } + }); + + var props$21 = makePropsConfigurable({ + subTitle: makeProp(PROP_TYPE_STRING), + subTitleTag: makeProp(PROP_TYPE_STRING, 'h6'), + subTitleTextVariant: makeProp(PROP_TYPE_STRING, 'muted') + }, NAME_CARD_SUB_TITLE); // --- Main component --- + // @vue/component + + var BCardSubTitle = /*#__PURE__*/extend({ + name: NAME_CARD_SUB_TITLE, + functional: true, + props: props$21, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + return h(props.subTitleTag, a(data, { + staticClass: 'card-subtitle', + class: [props.subTitleTextVariant ? "text-".concat(props.subTitleTextVariant) : null] + }), children || toString(props.subTitle)); + } + }); + + var props$20 = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, props$22), props$21), copyProps(props$23, prefixPropName.bind(null, 'body'))), {}, { + bodyClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), + overlay: makeProp(PROP_TYPE_BOOLEAN, false) + })), NAME_CARD_BODY); // --- Main component --- + // @vue/component + + var BCardBody = /*#__PURE__*/extend({ + name: NAME_CARD_BODY, + functional: true, + props: props$20, + render: function render(h, _ref) { + var _ref2; + + var props = _ref.props, + data = _ref.data, + children = _ref.children; + var bodyBgVariant = props.bodyBgVariant, + bodyBorderVariant = props.bodyBorderVariant, + bodyTextVariant = props.bodyTextVariant; + var $title = h(); + + if (props.title) { + $title = h(BCardTitle, { + props: pluckProps(props$22, props) + }); + } + + var $subTitle = h(); + + if (props.subTitle) { + $subTitle = h(BCardSubTitle, { + props: pluckProps(props$21, props), + class: ['mb-2'] + }); + } + + return h(props.bodyTag, a(data, { + staticClass: 'card-body', + class: [(_ref2 = { + 'card-img-overlay': props.overlay + }, _defineProperty(_ref2, "bg-".concat(bodyBgVariant), bodyBgVariant), _defineProperty(_ref2, "border-".concat(bodyBorderVariant), bodyBorderVariant), _defineProperty(_ref2, "text-".concat(bodyTextVariant), bodyTextVariant), _ref2), props.bodyClass] + }), [$title, $subTitle, children]); + } + }); + + var props$1$ = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, copyProps(props$23, prefixPropName.bind(null, 'header'))), {}, { + header: makeProp(PROP_TYPE_STRING), + headerClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), + headerHtml: makeProp(PROP_TYPE_STRING) + })), NAME_CARD_HEADER); // --- Main component --- + // @vue/component + + var BCardHeader = /*#__PURE__*/extend({ + name: NAME_CARD_HEADER, + functional: true, + props: props$1$, + render: function render(h, _ref) { + var _ref2; + + var props = _ref.props, + data = _ref.data, + children = _ref.children; + var headerBgVariant = props.headerBgVariant, + headerBorderVariant = props.headerBorderVariant, + headerTextVariant = props.headerTextVariant; + return h(props.headerTag, a(data, { + staticClass: 'card-header', + class: [props.headerClass, (_ref2 = {}, _defineProperty(_ref2, "bg-".concat(headerBgVariant), headerBgVariant), _defineProperty(_ref2, "border-".concat(headerBorderVariant), headerBorderVariant), _defineProperty(_ref2, "text-".concat(headerTextVariant), headerTextVariant), _ref2)], + domProps: children ? {} : htmlOrText(props.headerHtml, props.header) + }), children); + } + }); + + var props$1_ = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, copyProps(props$23, prefixPropName.bind(null, 'footer'))), {}, { + footer: makeProp(PROP_TYPE_STRING), + footerClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), + footerHtml: makeProp(PROP_TYPE_STRING) + })), NAME_CARD_FOOTER); // --- Main component --- + // @vue/component + + var BCardFooter = /*#__PURE__*/extend({ + name: NAME_CARD_FOOTER, + functional: true, + props: props$1_, + render: function render(h, _ref) { + var _ref2; + + var props = _ref.props, + data = _ref.data, + children = _ref.children; + var footerBgVariant = props.footerBgVariant, + footerBorderVariant = props.footerBorderVariant, + footerTextVariant = props.footerTextVariant; + return h(props.footerTag, a(data, { + staticClass: 'card-footer', + class: [props.footerClass, (_ref2 = {}, _defineProperty(_ref2, "bg-".concat(footerBgVariant), footerBgVariant), _defineProperty(_ref2, "border-".concat(footerBorderVariant), footerBorderVariant), _defineProperty(_ref2, "text-".concat(footerTextVariant), footerTextVariant), _ref2)], + domProps: children ? {} : htmlOrText(props.footerHtml, props.footer) + }), children); + } + }); + + // Blank image with fill template + + var BLANK_TEMPLATE = '' + '' + ''; // --- Helper methods --- + + var makeBlankImgSrc = function makeBlankImgSrc(width, height, color) { + var src = encodeURIComponent(BLANK_TEMPLATE.replace('%{w}', toString(width)).replace('%{h}', toString(height)).replace('%{f}', color)); + return "data:image/svg+xml;charset=UTF-8,".concat(src); + }; // --- Props --- + + + var props$1Z = makePropsConfigurable({ + alt: makeProp(PROP_TYPE_STRING), + blank: makeProp(PROP_TYPE_BOOLEAN, false), + blankColor: makeProp(PROP_TYPE_STRING, 'transparent'), + block: makeProp(PROP_TYPE_BOOLEAN, false), + center: makeProp(PROP_TYPE_BOOLEAN, false), + fluid: makeProp(PROP_TYPE_BOOLEAN, false), + // Gives fluid images class `w-100` to make them grow to fit container + fluidGrow: makeProp(PROP_TYPE_BOOLEAN, false), + height: makeProp(PROP_TYPE_NUMBER_STRING), + left: makeProp(PROP_TYPE_BOOLEAN, false), + right: makeProp(PROP_TYPE_BOOLEAN, false), + // Possible values: + // `false`: no rounding of corners + // `true`: slightly rounded corners + // 'top': top corners rounded + // 'right': right corners rounded + // 'bottom': bottom corners rounded + // 'left': left corners rounded + // 'circle': circle/oval + // '0': force rounding off + rounded: makeProp(PROP_TYPE_BOOLEAN_STRING, false), + sizes: makeProp(PROP_TYPE_ARRAY_STRING), + src: makeProp(PROP_TYPE_STRING), + srcset: makeProp(PROP_TYPE_ARRAY_STRING), + thumbnail: makeProp(PROP_TYPE_BOOLEAN, false), + width: makeProp(PROP_TYPE_NUMBER_STRING) + }, NAME_IMG); // --- Main component --- + // @vue/component + + var BImg = /*#__PURE__*/extend({ + name: NAME_IMG, + functional: true, + props: props$1Z, + render: function render(h, _ref) { + var _class; + + var props = _ref.props, + data = _ref.data; + var alt = props.alt, + src = props.src, + block = props.block, + fluidGrow = props.fluidGrow, + rounded = props.rounded; + var width = toInteger(props.width) || null; + var height = toInteger(props.height) || null; + var align = null; + var srcset = concat(props.srcset).filter(identity).join(','); + var sizes = concat(props.sizes).filter(identity).join(','); + + if (props.blank) { + if (!height && width) { + height = width; + } else if (!width && height) { + width = height; + } + + if (!width && !height) { + width = 1; + height = 1; + } // Make a blank SVG image + + + src = makeBlankImgSrc(width, height, props.blankColor || 'transparent'); // Disable srcset and sizes + + srcset = null; + sizes = null; + } + + if (props.left) { + align = 'float-left'; + } else if (props.right) { + align = 'float-right'; + } else if (props.center) { + align = 'mx-auto'; + block = true; + } + + return h('img', a(data, { + attrs: { + src: src, + alt: alt, + width: width ? toString(width) : null, + height: height ? toString(height) : null, + srcset: srcset || null, + sizes: sizes || null + }, + class: (_class = { + 'img-thumbnail': props.thumbnail, + 'img-fluid': props.fluid || fluidGrow, + 'w-100': fluidGrow, + rounded: rounded === '' || rounded === true + }, _defineProperty(_class, "rounded-".concat(rounded), isString(rounded) && rounded !== ''), _defineProperty(_class, align, align), _defineProperty(_class, 'd-block', block), _class) + })); + } + }); + + var props$1Y = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, pick$1(props$1Z, ['src', 'alt', 'width', 'height', 'left', 'right'])), {}, { + bottom: makeProp(PROP_TYPE_BOOLEAN, false), + end: makeProp(PROP_TYPE_BOOLEAN, false), + start: makeProp(PROP_TYPE_BOOLEAN, false), + top: makeProp(PROP_TYPE_BOOLEAN, false) + })), NAME_CARD_IMG); // --- Main component --- + // @vue/component + + var BCardImg = /*#__PURE__*/extend({ + name: NAME_CARD_IMG, + functional: true, + props: props$1Y, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data; + var src = props.src, + alt = props.alt, + width = props.width, + height = props.height; + var baseClass = 'card-img'; + + if (props.top) { + baseClass += '-top'; + } else if (props.right || props.end) { + baseClass += '-right'; + } else if (props.bottom) { + baseClass += '-bottom'; + } else if (props.left || props.start) { + baseClass += '-left'; + } + + return h('img', a(data, { + class: baseClass, + attrs: { + src: src, + alt: alt, + width: width, + height: height + } + })); + } + }); + + var cardImgProps = copyProps(props$1Y, prefixPropName.bind(null, 'img')); + cardImgProps.imgSrc.required = false; + var props$1X = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, props$20), props$1$), props$1_), cardImgProps), props$23), {}, { + align: makeProp(PROP_TYPE_STRING), + noBody: makeProp(PROP_TYPE_BOOLEAN, false) + })), NAME_CARD); // --- Main component --- + // @vue/component + + var BCard = /*#__PURE__*/extend({ + name: NAME_CARD, + functional: true, + props: props$1X, + render: function render(h, _ref) { + var _class; + + var props = _ref.props, + data = _ref.data, + slots = _ref.slots, + scopedSlots = _ref.scopedSlots; + var imgSrc = props.imgSrc, + imgLeft = props.imgLeft, + imgRight = props.imgRight, + imgStart = props.imgStart, + imgEnd = props.imgEnd, + imgBottom = props.imgBottom, + header = props.header, + headerHtml = props.headerHtml, + footer = props.footer, + footerHtml = props.footerHtml, + align = props.align, + textVariant = props.textVariant, + bgVariant = props.bgVariant, + borderVariant = props.borderVariant; + var $scopedSlots = scopedSlots || {}; + var $slots = slots(); + var slotScope = {}; + var $imgFirst = h(); + var $imgLast = h(); + + if (imgSrc) { + var $img = h(BCardImg, { + props: pluckProps(cardImgProps, props, unprefixPropName.bind(null, 'img')) + }); + + if (imgBottom) { + $imgLast = $img; + } else { + $imgFirst = $img; + } + } + + var $header = h(); + var hasHeaderSlot = hasNormalizedSlot(SLOT_NAME_HEADER, $scopedSlots, $slots); + + if (hasHeaderSlot || header || headerHtml) { + $header = h(BCardHeader, { + props: pluckProps(props$1$, props), + domProps: hasHeaderSlot ? {} : htmlOrText(headerHtml, header) + }, normalizeSlot(SLOT_NAME_HEADER, slotScope, $scopedSlots, $slots)); + } + + var $content = normalizeSlot(SLOT_NAME_DEFAULT, slotScope, $scopedSlots, $slots); // Wrap content in `` when `noBody` prop set + + if (!props.noBody) { + $content = h(BCardBody, { + props: pluckProps(props$20, props) + }, $content); // When the `overlap` prop is set we need to wrap the `` and `` + // into a relative positioned wrapper to don't distract a potential header or footer + + if (props.overlay && imgSrc) { + $content = h('div', { + staticClass: 'position-relative' + }, [$imgFirst, $content, $imgLast]); // Reset image variables since they are already in the wrapper + + $imgFirst = h(); + $imgLast = h(); + } + } + + var $footer = h(); + var hasFooterSlot = hasNormalizedSlot(SLOT_NAME_FOOTER, $scopedSlots, $slots); + + if (hasFooterSlot || footer || footerHtml) { + $footer = h(BCardFooter, { + props: pluckProps(props$1_, props), + domProps: hasHeaderSlot ? {} : htmlOrText(footerHtml, footer) + }, normalizeSlot(SLOT_NAME_FOOTER, slotScope, $scopedSlots, $slots)); + } + + return h(props.tag, a(data, { + staticClass: 'card', + class: (_class = { + 'flex-row': imgLeft || imgStart, + 'flex-row-reverse': (imgRight || imgEnd) && !(imgLeft || imgStart) + }, _defineProperty(_class, "text-".concat(align), align), _defineProperty(_class, "bg-".concat(bgVariant), bgVariant), _defineProperty(_class, "border-".concat(borderVariant), borderVariant), _defineProperty(_class, "text-".concat(textVariant), textVariant), _class) + }), [$imgFirst, $header, $content, $footer, $imgLast]); + } + }); + + var OBSERVER_PROP_NAME = '__bv__visibility_observer'; + + var VisibilityObserver = /*#__PURE__*/function () { + function VisibilityObserver(el, options) { + _classCallCheck(this, VisibilityObserver); + + this.el = el; + this.callback = options.callback; + this.margin = options.margin || 0; + this.once = options.once || false; + this.observer = null; + this.visible = undefined; + this.doneOnce = false; // Create the observer instance (if possible) + + this.createObserver(); + } + + _createClass(VisibilityObserver, [{ + key: "createObserver", + value: function createObserver() { + var _this = this; + + // Remove any previous observer + if (this.observer) { + /* istanbul ignore next */ + this.stop(); + } // Should only be called once and `callback` prop should be a function + + + if (this.doneOnce || !isFunction$1(this.callback)) { + /* istanbul ignore next */ + return; + } // Create the observer instance + + + try { + // Future: Possibly add in other modifiers for left/right/top/bottom + // offsets, root element reference, and thresholds + this.observer = new IntersectionObserver(this.handler.bind(this), { + // `null` = 'viewport' + root: null, + // Pixels away from view port to consider "visible" + rootMargin: this.margin, + // Intersection ratio of el and root (as a value from 0 to 1) + threshold: 0 + }); + } catch (_unused) { + // No IntersectionObserver support, so just stop trying to observe + this.doneOnce = true; + this.observer = undefined; + this.callback(null); + return; + } // Start observing in a `$nextTick()` (to allow DOM to complete rendering) + + /* istanbul ignore next: IntersectionObserver not supported in JSDOM */ + + + nextTick(function () { + requestAF(function () { + // Placed in an `if` just in case we were destroyed before + // this `requestAnimationFrame` runs + if (_this.observer) { + _this.observer.observe(_this.el); + } + }); + }); + } + /* istanbul ignore next */ + + }, { + key: "handler", + value: function handler(entries) { + var entry = entries ? entries[0] : {}; + var isIntersecting = Boolean(entry.isIntersecting || entry.intersectionRatio > 0.0); + + if (isIntersecting !== this.visible) { + this.visible = isIntersecting; + this.callback(isIntersecting); + + if (this.once && this.visible) { + this.doneOnce = true; + this.stop(); + } + } + } + }, { + key: "stop", + value: function stop() { + /* istanbul ignore next */ + this.observer && this.observer.disconnect(); + this.observer = null; + } + }]); + + return VisibilityObserver; + }(); + + var destroy$1 = function destroy(el) { + var observer = el[OBSERVER_PROP_NAME]; + + if (observer && observer.stop) { + observer.stop(); + } + + delete el[OBSERVER_PROP_NAME]; + }; + + var bind$1 = function bind(el, _ref) { + var value = _ref.value, + modifiers = _ref.modifiers; + // `value` is the callback function + var options = { + margin: '0px', + once: false, + callback: value + }; // Parse modifiers + + keys(modifiers).forEach(function (mod) { + /* istanbul ignore else: Until is switched to use this directive */ + if (RX_DIGITS.test(mod)) { + options.margin = "".concat(mod, "px"); + } else if (mod.toLowerCase() === 'once') { + options.once = true; + } + }); // Destroy any previous observer + + destroy$1(el); // Create new observer + + el[OBSERVER_PROP_NAME] = new VisibilityObserver(el, options); // Store the current modifiers on the object (cloned) + + el[OBSERVER_PROP_NAME]._prevModifiers = clone(modifiers); + }; // When the directive options may have been updated (or element) + + + var componentUpdated$1 = function componentUpdated(el, _ref2, vnode) { + var value = _ref2.value, + oldValue = _ref2.oldValue, + modifiers = _ref2.modifiers; + // Compare value/oldValue and modifiers to see if anything has changed + // and if so, destroy old observer and create new observer + + /* istanbul ignore next */ + modifiers = clone(modifiers); + /* istanbul ignore next */ + + if (el && (value !== oldValue || !el[OBSERVER_PROP_NAME] || !looseEqual(modifiers, el[OBSERVER_PROP_NAME]._prevModifiers))) { + // Re-bind on element + bind$1(el, { + value: value, + modifiers: modifiers + }); + } + }; // When directive un-binds from element + + + var unbind$1 = function unbind(el) { + // Remove the observer + destroy$1(el); + }; // Export the directive + + + var VBVisible = { + bind: bind$1, + componentUpdated: componentUpdated$1, + unbind: unbind$1 + }; + + var _watch$i; + + var MODEL_PROP_NAME_SHOW$1 = 'show'; + var MODEL_EVENT_NAME_SHOW$1 = MODEL_EVENT_NAME_PREFIX + MODEL_PROP_NAME_SHOW$1; // --- Props --- + + var imgProps$1 = omit(props$1Z, ['blank']); + var props$1W = makePropsConfigurable(_objectSpread2$3(_objectSpread2$3({}, imgProps$1), {}, _defineProperty({ + blankHeight: makeProp(PROP_TYPE_NUMBER_STRING), + // If `null`, a blank image is generated + blankSrc: makeProp(PROP_TYPE_STRING, null), + blankWidth: makeProp(PROP_TYPE_NUMBER_STRING), + // Distance away from viewport (in pixels) + // before being considered "visible" + offset: makeProp(PROP_TYPE_NUMBER_STRING, 360) + }, MODEL_PROP_NAME_SHOW$1, makeProp(PROP_TYPE_BOOLEAN, false))), NAME_IMG_LAZY); // --- Main component --- + // @vue/component + + var BImgLazy = /*#__PURE__*/extend({ + name: NAME_IMG_LAZY, + directives: { + 'b-visible': VBVisible + }, + props: props$1W, + data: function data() { + return { + isShown: this[MODEL_PROP_NAME_SHOW$1] + }; + }, + computed: { + computedSrc: function computedSrc() { + var blankSrc = this.blankSrc; + return !blankSrc || this.isShown ? this.src : blankSrc; + }, + computedBlank: function computedBlank() { + return !(this.isShown || this.blankSrc); + }, + computedWidth: function computedWidth() { + var width = this.width; + return this.isShown ? width : this.blankWidth || width; + }, + computedHeight: function computedHeight() { + var height = this.height; + return this.isShown ? height : this.blankHeight || height; + }, + computedSrcset: function computedSrcset() { + var srcset = concat(this.srcset).filter(identity).join(','); + return srcset && (!this.blankSrc || this.isShown) ? srcset : null; + }, + computedSizes: function computedSizes() { + var sizes = concat(this.sizes).filter(identity).join(','); + return sizes && (!this.blankSrc || this.isShown) ? sizes : null; + } + }, + watch: (_watch$i = {}, _defineProperty(_watch$i, MODEL_PROP_NAME_SHOW$1, function (newValue, oldValue) { + if (newValue !== oldValue) { + // If `IntersectionObserver` support is not available, image is always shown + var visible = HAS_INTERACTION_OBSERVER_SUPPORT ? newValue : true; + this.isShown = visible; // Ensure the show prop is synced (when no `IntersectionObserver`) + + if (newValue !== visible) { + this.$nextTick(this.updateShowProp); + } + } + }), _defineProperty(_watch$i, "isShown", function isShown(newValue, oldValue) { + // Update synched show prop + if (newValue !== oldValue) { + this.updateShowProp(); + } + }), _watch$i), + mounted: function mounted() { + var _this = this; + + // If `IntersectionObserver` is not available, image is always shown + this.$nextTick(function () { + _this.isShown = HAS_INTERACTION_OBSERVER_SUPPORT ? _this[MODEL_PROP_NAME_SHOW$1] : true; + }); + }, + methods: { + updateShowProp: function updateShowProp() { + this.$emit(MODEL_EVENT_NAME_SHOW$1, this.isShown); + }, + doShow: function doShow(visible) { + var _this2 = this; + + // If IntersectionObserver is not supported, the callback + // will be called with `null` rather than `true` or `false` + if ((visible || visible === null) && !this.isShown) { + // In a `requestAF()` to render the `blank` placeholder properly + // for fast loading images in some browsers (i.e. Firefox) + requestAF(function () { + _this2.isShown = true; + }); + } + } + }, + render: function render(h) { + var directives = []; + + if (!this.isShown) { + var _modifiers; + + // We only add the visible directive if we are not shown + directives.push({ + // Visible directive will silently do nothing if + // `IntersectionObserver` is not supported + name: 'b-visible', + // Value expects a callback (passed one arg of `visible` = `true` or `false`) + value: this.doShow, + modifiers: (_modifiers = {}, _defineProperty(_modifiers, "".concat(toInteger(this.offset, 0)), true), _defineProperty(_modifiers, "once", true), _modifiers) + }); + } + + return h(BImg, { + directives: directives, + props: _objectSpread2$3(_objectSpread2$3({}, pluckProps(imgProps$1, this.$props)), {}, { + // Computed value props + src: this.computedSrc, + blank: this.computedBlank, + width: this.computedWidth, + height: this.computedHeight, + srcset: this.computedSrcset, + sizes: this.computedSizes + }) + }); + } + }); + + var props$1V = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, omit(props$1W, keys(props$1Z))), omit(props$1Y, ['src', 'alt', 'width', 'height']))), NAME_CARD_IMG_LAZY); // --- Main component --- + // @vue/component + + var BCardImgLazy = /*#__PURE__*/extend({ + name: NAME_CARD_IMG_LAZY, + functional: true, + props: props$1V, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data; + var baseClass = 'card-img'; + + if (props.top) { + baseClass += '-top'; + } else if (props.right || props.end) { + baseClass += '-right'; + } else if (props.bottom) { + baseClass += '-bottom'; + } else if (props.left || props.start) { + baseClass += '-left'; + } + + return h(BImgLazy, a(data, { + class: [baseClass], + // Exclude `left` and `right` props before passing to `` + props: omit(props, ['left', 'right']) + })); + } + }); + + var props$1U = makePropsConfigurable({ + textTag: makeProp(PROP_TYPE_STRING, 'p') + }, NAME_CARD_TEXT); // --- Main component --- + // @vue/component + + var BCardText = /*#__PURE__*/extend({ + name: NAME_CARD_TEXT, + functional: true, + props: props$1U, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + return h(props.textTag, a(data, { + staticClass: 'card-text' + }), children); + } + }); + + var props$1T = makePropsConfigurable({ + columns: makeProp(PROP_TYPE_BOOLEAN, false), + deck: makeProp(PROP_TYPE_BOOLEAN, false), + tag: makeProp(PROP_TYPE_STRING, 'div') + }, NAME_CARD_GROUP); // --- Main component --- + // @vue/component + + var BCardGroup = /*#__PURE__*/extend({ + name: NAME_CARD_GROUP, + functional: true, + props: props$1T, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + return h(props.tag, a(data, { + class: props.deck ? 'card-deck' : props.columns ? 'card-columns' : 'card-group' + }), children); + } + }); + + var CardPlugin = /*#__PURE__*/pluginFactory({ + components: { + BCard: BCard, + BCardHeader: BCardHeader, + BCardBody: BCardBody, + BCardTitle: BCardTitle, + BCardSubTitle: BCardSubTitle, + BCardFooter: BCardFooter, + BCardImg: BCardImg, + BCardImgLazy: BCardImgLazy, + BCardText: BCardText, + BCardGroup: BCardGroup + } + }); + + var noop = function noop() {}; + + /** + * Observe a DOM element changes, falls back to eventListener mode + * @param {Element} el The DOM element to observe + * @param {Function} callback callback to be called on change + * @param {object} [options={childList: true, subtree: true}] observe options + * @see https://stackoverflow.com/questions/3219758 + */ + + var observeDom = function observeDom(el, callback, options) + /* istanbul ignore next: difficult to test in JSDOM */ + { + // Handle cases where we might be passed a Vue instance + el = el ? el.$el || el : null; // Early exit when we have no element + + /* istanbul ignore next: difficult to test in JSDOM */ + + if (!isElement(el)) { + return null; + } // Exit and throw a warning when `MutationObserver` isn't available + + + if (warnNoMutationObserverSupport('observeDom')) { + return null; + } // Define a new observer + + + var obs = new MutationObs(function (mutations) { + var changed = false; // A mutation can contain several change records, so we loop + // through them to see what has changed + // We break out of the loop early if any "significant" change + // has been detected + + for (var i = 0; i < mutations.length && !changed; i++) { + // The mutation record + var mutation = mutations[i]; // Mutation type + + var type = mutation.type; // DOM node (could be any DOM node type - HTMLElement, Text, comment, etc.) + + var target = mutation.target; // Detect whether a change happened based on type and target + + if (type === 'characterData' && target.nodeType === Node.TEXT_NODE) { + // We ignore nodes that are not TEXT (i.e. comments, etc.) + // as they don't change layout + changed = true; + } else if (type === 'attributes') { + changed = true; + } else if (type === 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)) { + // This includes HTMLElement and text nodes being + // added/removed/re-arranged + changed = true; + } + } // We only call the callback if a change that could affect + // layout/size truly happened + + + if (changed) { + callback(); + } + }); // Have the observer observe foo for changes in children, etc + + obs.observe(el, _objectSpread2$3({ + childList: true, + subtree: true + }, options)); // We return a reference to the observer so that `obs.disconnect()` + // can be called if necessary + // To reduce overhead when the root element is hidden + + return obs; + }; + + var _watch$h; + + var _makeModelMixin$i = makeModelMixin('value', { + type: PROP_TYPE_NUMBER, + defaultValue: 0 + }), + modelMixin$h = _makeModelMixin$i.mixin, + modelProps$h = _makeModelMixin$i.props, + MODEL_PROP_NAME$h = _makeModelMixin$i.prop, + MODEL_EVENT_NAME$h = _makeModelMixin$i.event; // Slide directional classes + + + var DIRECTION = { + next: { + dirClass: 'carousel-item-left', + overlayClass: 'carousel-item-next' + }, + prev: { + dirClass: 'carousel-item-right', + overlayClass: 'carousel-item-prev' + } + }; // Fallback Transition duration (with a little buffer) in ms + + var TRANS_DURATION = 600 + 50; // Time for mouse compat events to fire after touch + + var TOUCH_EVENT_COMPAT_WAIT = 500; // Number of pixels to consider touch move a swipe + + var SWIPE_THRESHOLD = 40; // PointerEvent pointer types + + var PointerType = { + TOUCH: 'touch', + PEN: 'pen' + }; // Transition Event names + + var TransitionEndEvents$1 = { + WebkitTransition: 'webkitTransitionEnd', + MozTransition: 'transitionend', + OTransition: 'otransitionend oTransitionEnd', + transition: 'transitionend' + }; // --- Helper methods --- + // Return the browser specific transitionEnd event name + + var getTransitionEndEvent = function getTransitionEndEvent(el) { + for (var name in TransitionEndEvents$1) { + if (!isUndefined(el.style[name])) { + return TransitionEndEvents$1[name]; + } + } // Fallback + + /* istanbul ignore next */ + + + return null; + }; // --- Props --- + + + var props$1S = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, props$25), modelProps$h), {}, { + background: makeProp(PROP_TYPE_STRING), + controls: makeProp(PROP_TYPE_BOOLEAN, false), + // Enable cross-fade animation instead of slide animation + fade: makeProp(PROP_TYPE_BOOLEAN, false), + // Sniffed by carousel-slide + imgHeight: makeProp(PROP_TYPE_NUMBER_STRING), + // Sniffed by carousel-slide + imgWidth: makeProp(PROP_TYPE_NUMBER_STRING), + indicators: makeProp(PROP_TYPE_BOOLEAN, false), + interval: makeProp(PROP_TYPE_NUMBER, 5000), + labelGotoSlide: makeProp(PROP_TYPE_STRING, 'Goto slide'), + labelIndicators: makeProp(PROP_TYPE_STRING, 'Select a slide to display'), + labelNext: makeProp(PROP_TYPE_STRING, 'Next slide'), + labelPrev: makeProp(PROP_TYPE_STRING, 'Previous slide'), + // Disable slide/fade animation + noAnimation: makeProp(PROP_TYPE_BOOLEAN, false), + // Disable pause on hover + noHoverPause: makeProp(PROP_TYPE_BOOLEAN, false), + // Sniffed by carousel-slide + noTouch: makeProp(PROP_TYPE_BOOLEAN, false), + // Disable wrapping/looping when start/end is reached + noWrap: makeProp(PROP_TYPE_BOOLEAN, false) + })), NAME_CAROUSEL); // --- Main component --- + // @vue/component + + var BCarousel = /*#__PURE__*/extend({ + name: NAME_CAROUSEL, + mixins: [idMixin, modelMixin$h, normalizeSlotMixin], + provide: function provide() { + var _this = this; + + return { + getBvCarousel: function getBvCarousel() { + return _this; + } + }; + }, + props: props$1S, + data: function data() { + return { + index: this[MODEL_PROP_NAME$h] || 0, + isSliding: false, + transitionEndEvent: null, + slides: [], + direction: null, + isPaused: !(toInteger(this.interval, 0) > 0), + // Touch event handling values + touchStartX: 0, + touchDeltaX: 0 + }; + }, + computed: { + numSlides: function numSlides() { + return this.slides.length; + } + }, + watch: (_watch$h = {}, _defineProperty(_watch$h, MODEL_PROP_NAME$h, function (newValue, oldValue) { + if (newValue !== oldValue) { + this.setSlide(toInteger(newValue, 0)); + } + }), _defineProperty(_watch$h, "interval", function interval(newValue, oldValue) { + /* istanbul ignore next */ + if (newValue === oldValue) { + return; + } + + if (!newValue) { + // Pausing slide show + this.pause(false); + } else { + // Restarting or Changing interval + this.pause(true); + this.start(false); + } + }), _defineProperty(_watch$h, "isPaused", function isPaused(newValue, oldValue) { + if (newValue !== oldValue) { + this.$emit(newValue ? EVENT_NAME_PAUSED : EVENT_NAME_UNPAUSED); + } + }), _defineProperty(_watch$h, "index", function index(to, from) { + /* istanbul ignore next */ + if (to === from || this.isSliding) { + return; + } + + this.doSlide(to, from); + }), _watch$h), + created: function created() { + // Create private non-reactive props + this.$_interval = null; + this.$_animationTimeout = null; + this.$_touchTimeout = null; + this.$_observer = null; // Set initial paused state + + this.isPaused = !(toInteger(this.interval, 0) > 0); + }, + mounted: function mounted() { + // Cache current browser transitionend event name + this.transitionEndEvent = getTransitionEndEvent(this.$el) || null; // Get all slides + + this.updateSlides(); // Observe child changes so we can update slide list + + this.setObserver(true); + }, + beforeDestroy: function beforeDestroy() { + this.clearInterval(); + this.clearAnimationTimeout(); + this.clearTouchTimeout(); + this.setObserver(false); + }, + methods: { + clearInterval: function (_clearInterval) { + function clearInterval() { + return _clearInterval.apply(this, arguments); + } + + clearInterval.toString = function () { + return _clearInterval.toString(); + }; + + return clearInterval; + }(function () { + clearInterval(this.$_interval); + this.$_interval = null; + }), + clearAnimationTimeout: function clearAnimationTimeout() { + clearTimeout(this.$_animationTimeout); + this.$_animationTimeout = null; + }, + clearTouchTimeout: function clearTouchTimeout() { + clearTimeout(this.$_touchTimeout); + this.$_touchTimeout = null; + }, + setObserver: function setObserver() { + var on = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + this.$_observer && this.$_observer.disconnect(); + this.$_observer = null; + + if (on) { + this.$_observer = observeDom(this.$refs.inner, this.updateSlides.bind(this), { + subtree: false, + childList: true, + attributes: true, + attributeFilter: ['id'] + }); + } + }, + // Set slide + setSlide: function setSlide(slide) { + var _this2 = this; + + var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + // Don't animate when page is not visible + + /* istanbul ignore if: difficult to test */ + if (IS_BROWSER && document.visibilityState && document.hidden) { + return; + } + + var noWrap = this.noWrap; + var numSlides = this.numSlides; // Make sure we have an integer (you never know!) + + slide = mathFloor(slide); // Don't do anything if nothing to slide to + + if (numSlides === 0) { + return; + } // Don't change slide while transitioning, wait until transition is done + + + if (this.isSliding) { + // Schedule slide after sliding complete + this.$once(EVENT_NAME_SLIDING_END, function () { + // Wrap in `requestAF()` to allow the slide to properly finish to avoid glitching + requestAF(function () { + return _this2.setSlide(slide, direction); + }); + }); + return; + } + + this.direction = direction; // Set new slide index + // Wrap around if necessary (if no-wrap not enabled) + + this.index = slide >= numSlides ? noWrap ? numSlides - 1 : 0 : slide < 0 ? noWrap ? 0 : numSlides - 1 : slide; // Ensure the v-model is synched up if no-wrap is enabled + // and user tried to slide pass either ends + + if (noWrap && this.index !== slide && this.index !== this[MODEL_PROP_NAME$h]) { + this.$emit(MODEL_EVENT_NAME$h, this.index); + } + }, + // Previous slide + prev: function prev() { + this.setSlide(this.index - 1, 'prev'); + }, + // Next slide + next: function next() { + this.setSlide(this.index + 1, 'next'); + }, + // Pause auto rotation + pause: function pause(event) { + if (!event) { + this.isPaused = true; + } + + this.clearInterval(); + }, + // Start auto rotate slides + start: function start(event) { + if (!event) { + this.isPaused = false; + } + /* istanbul ignore next: most likely will never happen, but just in case */ + + + this.clearInterval(); // Don't start if no interval, or less than 2 slides + + if (this.interval && this.numSlides > 1) { + this.$_interval = setInterval(this.next, mathMax(1000, this.interval)); + } + }, + // Restart auto rotate slides when focus/hover leaves the carousel + + /* istanbul ignore next */ + restart: function restart() { + if (!this.$el.contains(getActiveElement())) { + this.start(); + } + }, + doSlide: function doSlide(to, from) { + var _this3 = this; + + var isCycling = Boolean(this.interval); // Determine sliding direction + + var direction = this.calcDirection(this.direction, from, to); + var overlayClass = direction.overlayClass; + var dirClass = direction.dirClass; // Determine current and next slides + + var currentSlide = this.slides[from]; + var nextSlide = this.slides[to]; // Don't do anything if there aren't any slides to slide to + + if (!currentSlide || !nextSlide) { + /* istanbul ignore next */ + return; + } // Start animating + + + this.isSliding = true; + + if (isCycling) { + this.pause(false); + } + + this.$emit(EVENT_NAME_SLIDING_START, to); // Update v-model + + this.$emit(MODEL_EVENT_NAME$h, this.index); + + if (this.noAnimation) { + addClass(nextSlide, 'active'); + removeClass(currentSlide, 'active'); + this.isSliding = false; // Notify ourselves that we're done sliding (slid) + + this.$nextTick(function () { + return _this3.$emit(EVENT_NAME_SLIDING_END, to); + }); + } else { + addClass(nextSlide, overlayClass); // Trigger a reflow of next slide + + reflow(nextSlide); + addClass(currentSlide, dirClass); + addClass(nextSlide, dirClass); // Transition End handler + + var called = false; + /* istanbul ignore next: difficult to test */ + + var onceTransEnd = function onceTransEnd() { + if (called) { + return; + } + + called = true; + /* istanbul ignore if: transition events cant be tested in JSDOM */ + + if (_this3.transitionEndEvent) { + var events = _this3.transitionEndEvent.split(/\s+/); + + events.forEach(function (event) { + return eventOff(nextSlide, event, onceTransEnd, EVENT_OPTIONS_NO_CAPTURE); + }); + } + + _this3.clearAnimationTimeout(); + + removeClass(nextSlide, dirClass); + removeClass(nextSlide, overlayClass); + addClass(nextSlide, 'active'); + removeClass(currentSlide, 'active'); + removeClass(currentSlide, dirClass); + removeClass(currentSlide, overlayClass); + setAttr(currentSlide, 'aria-current', 'false'); + setAttr(nextSlide, 'aria-current', 'true'); + setAttr(currentSlide, 'aria-hidden', 'true'); + setAttr(nextSlide, 'aria-hidden', 'false'); + _this3.isSliding = false; + _this3.direction = null; // Notify ourselves that we're done sliding (slid) + + _this3.$nextTick(function () { + return _this3.$emit(EVENT_NAME_SLIDING_END, to); + }); + }; // Set up transitionend handler + + /* istanbul ignore if: transition events cant be tested in JSDOM */ + + + if (this.transitionEndEvent) { + var events = this.transitionEndEvent.split(/\s+/); + events.forEach(function (event) { + return eventOn(nextSlide, event, onceTransEnd, EVENT_OPTIONS_NO_CAPTURE); + }); + } // Fallback to setTimeout() + + + this.$_animationTimeout = setTimeout(onceTransEnd, TRANS_DURATION); + } + + if (isCycling) { + this.start(false); + } + }, + // Update slide list + updateSlides: function updateSlides() { + this.pause(true); // Get all slides as DOM elements + + this.slides = selectAll('.carousel-item', this.$refs.inner); + var numSlides = this.slides.length; // Keep slide number in range + + var index = mathMax(0, mathMin(mathFloor(this.index), numSlides - 1)); + this.slides.forEach(function (slide, idx) { + var n = idx + 1; + + if (idx === index) { + addClass(slide, 'active'); + setAttr(slide, 'aria-current', 'true'); + } else { + removeClass(slide, 'active'); + setAttr(slide, 'aria-current', 'false'); + } + + setAttr(slide, 'aria-posinset', String(n)); + setAttr(slide, 'aria-setsize', String(numSlides)); + }); // Set slide as active + + this.setSlide(index); + this.start(this.isPaused); + }, + calcDirection: function calcDirection() { + var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var curIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var nextIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + + if (!direction) { + return nextIndex > curIndex ? DIRECTION.next : DIRECTION.prev; + } + + return DIRECTION[direction]; + }, + handleClick: function handleClick(event, fn) { + var keyCode = event.keyCode; + + if (event.type === 'click' || keyCode === CODE_SPACE || keyCode === CODE_ENTER) { + stopEvent(event); + fn(); + } + }, + + /* istanbul ignore next: JSDOM doesn't support touch events */ + handleSwipe: function handleSwipe() { + var absDeltaX = mathAbs(this.touchDeltaX); + + if (absDeltaX <= SWIPE_THRESHOLD) { + return; + } + + var direction = absDeltaX / this.touchDeltaX; // Reset touch delta X + // https://github.com/twbs/bootstrap/pull/28558 + + this.touchDeltaX = 0; + + if (direction > 0) { + // Swipe left + this.prev(); + } else if (direction < 0) { + // Swipe right + this.next(); + } + }, + + /* istanbul ignore next: JSDOM doesn't support touch events */ + touchStart: function touchStart(event) { + if (HAS_POINTER_EVENT_SUPPORT && PointerType[event.pointerType.toUpperCase()]) { + this.touchStartX = event.clientX; + } else if (!HAS_POINTER_EVENT_SUPPORT) { + this.touchStartX = event.touches[0].clientX; + } + }, + + /* istanbul ignore next: JSDOM doesn't support touch events */ + touchMove: function touchMove(event) { + // Ensure swiping with one touch and not pinching + if (event.touches && event.touches.length > 1) { + this.touchDeltaX = 0; + } else { + this.touchDeltaX = event.touches[0].clientX - this.touchStartX; + } + }, + + /* istanbul ignore next: JSDOM doesn't support touch events */ + touchEnd: function touchEnd(event) { + if (HAS_POINTER_EVENT_SUPPORT && PointerType[event.pointerType.toUpperCase()]) { + this.touchDeltaX = event.clientX - this.touchStartX; + } + + this.handleSwipe(); // If it's a touch-enabled device, mouseenter/leave are fired as + // part of the mouse compatibility events on first tap - the carousel + // would stop cycling until user tapped out of it; + // here, we listen for touchend, explicitly pause the carousel + // (as if it's the second time we tap on it, mouseenter compat event + // is NOT fired) and after a timeout (to allow for mouse compatibility + // events to fire) we explicitly restart cycling + + this.pause(false); + this.clearTouchTimeout(); + this.$_touchTimeout = setTimeout(this.start, TOUCH_EVENT_COMPAT_WAIT + mathMax(1000, this.interval)); + } + }, + render: function render(h) { + var _this4 = this; + + var indicators = this.indicators, + background = this.background, + noAnimation = this.noAnimation, + noHoverPause = this.noHoverPause, + noTouch = this.noTouch, + index = this.index, + isSliding = this.isSliding, + pause = this.pause, + restart = this.restart, + touchStart = this.touchStart, + touchEnd = this.touchEnd; + var idInner = this.safeId('__BV_inner_'); // Wrapper for slides + + var $inner = h('div', { + staticClass: 'carousel-inner', + attrs: { + id: idInner, + role: 'list' + }, + ref: 'inner' + }, [this.normalizeSlot()]); // Prev and next controls + + var $controls = h(); + + if (this.controls) { + var makeControl = function makeControl(direction, label, handler) { + var handlerWrapper = function handlerWrapper(event) { + /* istanbul ignore next */ + if (!isSliding) { + _this4.handleClick(event, handler); + } else { + stopEvent(event, { + propagation: false + }); + } + }; + + return h('a', { + staticClass: "carousel-control-".concat(direction), + attrs: { + href: '#', + role: 'button', + 'aria-controls': idInner, + 'aria-disabled': isSliding ? 'true' : null + }, + on: { + click: handlerWrapper, + keydown: handlerWrapper + } + }, [h('span', { + staticClass: "carousel-control-".concat(direction, "-icon"), + attrs: { + 'aria-hidden': 'true' + } + }), h('span', { + class: 'sr-only' + }, [label])]); + }; + + $controls = [makeControl('prev', this.labelPrev, this.prev), makeControl('next', this.labelNext, this.next)]; + } // Indicators + + + var $indicators = h('ol', { + staticClass: 'carousel-indicators', + directives: [{ + name: 'show', + value: indicators + }], + attrs: { + id: this.safeId('__BV_indicators_'), + 'aria-hidden': indicators ? 'false' : 'true', + 'aria-label': this.labelIndicators, + 'aria-owns': idInner + } + }, this.slides.map(function (slide, i) { + var handler = function handler(event) { + _this4.handleClick(event, function () { + _this4.setSlide(i); + }); + }; + + return h('li', { + class: { + active: i === index + }, + attrs: { + role: 'button', + id: _this4.safeId("__BV_indicator_".concat(i + 1, "_")), + tabindex: indicators ? '0' : '-1', + 'aria-current': i === index ? 'true' : 'false', + 'aria-label': "".concat(_this4.labelGotoSlide, " ").concat(i + 1), + 'aria-describedby': slide.id || null, + 'aria-controls': idInner + }, + on: { + click: handler, + keydown: handler + }, + key: "slide_".concat(i) + }); + })); + var on = { + mouseenter: noHoverPause ? noop : pause, + mouseleave: noHoverPause ? noop : restart, + focusin: pause, + focusout: restart, + keydown: function keydown(event) { + /* istanbul ignore next */ + if (/input|textarea/i.test(event.target.tagName)) { + return; + } + + var keyCode = event.keyCode; + + if (keyCode === CODE_LEFT || keyCode === CODE_RIGHT) { + stopEvent(event); + + _this4[keyCode === CODE_LEFT ? 'prev' : 'next'](); + } + } + }; // Touch support event handlers for environment + + if (HAS_TOUCH_SUPPORT && !noTouch) { + // Attach appropriate listeners (prepend event name with '&' for passive mode) + + /* istanbul ignore next: JSDOM doesn't support touch events */ + if (HAS_POINTER_EVENT_SUPPORT) { + on['&pointerdown'] = touchStart; + on['&pointerup'] = touchEnd; + } else { + on['&touchstart'] = touchStart; + on['&touchmove'] = this.touchMove; + on['&touchend'] = touchEnd; + } + } // Return the carousel + + + return h('div', { + staticClass: 'carousel', + class: { + slide: !noAnimation, + 'carousel-fade': !noAnimation && this.fade, + 'pointer-event': HAS_TOUCH_SUPPORT && HAS_POINTER_EVENT_SUPPORT && !noTouch + }, + style: { + background: background + }, + attrs: { + role: 'region', + id: this.safeId(), + 'aria-busy': isSliding ? 'true' : 'false' + }, + on: on + }, [$inner, $controls, $indicators]); + } + }); + + var imgProps = { + imgAlt: makeProp(PROP_TYPE_STRING), + imgBlank: makeProp(PROP_TYPE_BOOLEAN, false), + imgBlankColor: makeProp(PROP_TYPE_STRING, 'transparent'), + imgHeight: makeProp(PROP_TYPE_NUMBER_STRING), + imgSrc: makeProp(PROP_TYPE_STRING), + imgWidth: makeProp(PROP_TYPE_NUMBER_STRING) + }; + var props$1R = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, props$25), imgProps), {}, { + background: makeProp(PROP_TYPE_STRING), + caption: makeProp(PROP_TYPE_STRING), + captionHtml: makeProp(PROP_TYPE_STRING), + captionTag: makeProp(PROP_TYPE_STRING, 'h3'), + contentTag: makeProp(PROP_TYPE_STRING, 'div'), + contentVisibleUp: makeProp(PROP_TYPE_STRING), + text: makeProp(PROP_TYPE_STRING), + textHtml: makeProp(PROP_TYPE_STRING), + textTag: makeProp(PROP_TYPE_STRING, 'p') + })), NAME_CAROUSEL_SLIDE); // --- Main component --- + // @vue/component + + var BCarouselSlide = /*#__PURE__*/extend({ + name: NAME_CAROUSEL_SLIDE, + mixins: [idMixin, normalizeSlotMixin], + inject: { + getBvCarousel: { + // Explicitly disable touch if not a child of carousel + default: function _default() { + return function () { + return { + noTouch: true + }; + }; + } + } + }, + props: props$1R, + computed: { + bvCarousel: function bvCarousel() { + return this.getBvCarousel(); + }, + contentClasses: function contentClasses() { + return [this.contentVisibleUp ? 'd-none' : '', this.contentVisibleUp ? "d-".concat(this.contentVisibleUp, "-block") : '']; + }, + computedWidth: function computedWidth() { + // Use local width, or try parent width + return this.imgWidth || this.bvCarousel.imgWidth || null; + }, + computedHeight: function computedHeight() { + // Use local height, or try parent height + return this.imgHeight || this.bvCarousel.imgHeight || null; + } + }, + render: function render(h) { + var $img = this.normalizeSlot(SLOT_NAME_IMG); + + if (!$img && (this.imgSrc || this.imgBlank)) { + var on = {}; // Touch support event handler + + /* istanbul ignore if: difficult to test in JSDOM */ + + if (!this.bvCarousel.noTouch && HAS_TOUCH_SUPPORT) { + on.dragstart = function (event) { + return stopEvent(event, { + propagation: false + }); + }; + } + + $img = h(BImg, { + props: _objectSpread2$3(_objectSpread2$3({}, pluckProps(imgProps, this.$props, unprefixPropName.bind(null, 'img'))), {}, { + width: this.computedWidth, + height: this.computedHeight, + fluidGrow: true, + block: true + }), + on: on + }); + } + + var $contentChildren = [// Caption + this.caption || this.captionHtml ? h(this.captionTag, { + domProps: htmlOrText(this.captionHtml, this.caption) + }) : false, // Text + this.text || this.textHtml ? h(this.textTag, { + domProps: htmlOrText(this.textHtml, this.text) + }) : false, // Children + this.normalizeSlot() || false]; + var $content = h(); + + if ($contentChildren.some(identity)) { + $content = h(this.contentTag, { + staticClass: 'carousel-caption', + class: this.contentClasses + }, $contentChildren.map(function ($child) { + return $child || h(); + })); + } + + return h('div', { + staticClass: 'carousel-item', + style: { + background: this.background || this.bvCarousel.background || null + }, + attrs: { + id: this.safeId(), + role: 'listitem' + } + }, [$img, $content]); + } + }); + + var CarouselPlugin = + /*#__PURE*/ + pluginFactory({ + components: { + BCarousel: BCarousel, + BCarouselSlide: BCarouselSlide + } + }); + + var CLASS_NAME_SHOW = 'show'; + + // Generic collapse transion helper component + // Transition event handler helpers + + var onEnter = function onEnter(el) { + setStyle(el, 'height', 0); // In a `requestAF()` for `appear` to work + + requestAF(function () { + reflow(el); + setStyle(el, 'height', "".concat(el.scrollHeight, "px")); + }); + }; + + var onAfterEnter = function onAfterEnter(el) { + removeStyle(el, 'height'); + }; + + var onLeave = function onLeave(el) { + setStyle(el, 'height', 'auto'); + setStyle(el, 'display', 'block'); + setStyle(el, 'height', "".concat(getBCR(el).height, "px")); + reflow(el); + setStyle(el, 'height', 0); + }; + + var onAfterLeave = function onAfterLeave(el) { + removeStyle(el, 'height'); + }; // --- Constants --- + // Default transition props + // `appear` will use the enter classes + + + var TRANSITION_PROPS = { + css: true, + enterClass: '', + enterActiveClass: 'collapsing', + enterToClass: 'collapse show', + leaveClass: 'collapse show', + leaveActiveClass: 'collapsing', + leaveToClass: 'collapse' + }; // Default transition handlers + // `appear` will use the enter handlers + + var TRANSITION_HANDLERS = { + enter: onEnter, + afterEnter: onAfterEnter, + leave: onLeave, + afterLeave: onAfterLeave + }; // --- Main component --- + + var props$1Q = { + // // If `true` (and `visible` is `true` on mount), animate initially visible + appear: makeProp(PROP_TYPE_BOOLEAN, false) + }; // --- Main component --- + // @vue/component + + var BVCollapse = /*#__PURE__*/extend({ + name: NAME_COLLAPSE_HELPER, + functional: true, + props: props$1Q, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + return h('transition', // We merge in the `appear` prop last + a(data, { + props: TRANSITION_PROPS, + on: TRANSITION_HANDLERS + }, { + props: props + }), // Note: `` supports a single root element only + children); + } + }); + + var _watch$g; + + var ROOT_ACTION_EVENT_NAME_TOGGLE$2 = getRootActionEventName(NAME_COLLAPSE, 'toggle'); + var ROOT_ACTION_EVENT_NAME_REQUEST_STATE$2 = getRootActionEventName(NAME_COLLAPSE, 'request-state'); + var ROOT_EVENT_NAME_ACCORDION = getRootEventName(NAME_COLLAPSE, 'accordion'); + var ROOT_EVENT_NAME_STATE$3 = getRootEventName(NAME_COLLAPSE, 'state'); + var ROOT_EVENT_NAME_SYNC_STATE$3 = getRootEventName(NAME_COLLAPSE, 'sync-state'); + + var _makeModelMixin$h = makeModelMixin('visible', { + type: PROP_TYPE_BOOLEAN, + defaultValue: false + }), + modelMixin$g = _makeModelMixin$h.mixin, + modelProps$g = _makeModelMixin$h.props, + MODEL_PROP_NAME$g = _makeModelMixin$h.prop, + MODEL_EVENT_NAME$g = _makeModelMixin$h.event; // --- Props --- + + + var props$1P = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, props$25), modelProps$g), {}, { + // If `true` (and `visible` is `true` on mount), animate initially visible + accordion: makeProp(PROP_TYPE_STRING), + appear: makeProp(PROP_TYPE_BOOLEAN, false), + isNav: makeProp(PROP_TYPE_BOOLEAN, false), + tag: makeProp(PROP_TYPE_STRING, 'div') + })), NAME_COLLAPSE); // --- Main component --- + // @vue/component + + var BCollapse = /*#__PURE__*/extend({ + name: NAME_COLLAPSE, + mixins: [idMixin, modelMixin$g, normalizeSlotMixin, listenOnRootMixin], + props: props$1P, + data: function data() { + return { + show: this[MODEL_PROP_NAME$g], + transitioning: false + }; + }, + computed: { + classObject: function classObject() { + var transitioning = this.transitioning; + return { + 'navbar-collapse': this.isNav, + collapse: !transitioning, + show: this.show && !transitioning + }; + }, + slotScope: function slotScope() { + var _this = this; + + return { + visible: this.show, + close: function close() { + _this.show = false; + } + }; + } + }, + watch: (_watch$g = {}, _defineProperty(_watch$g, MODEL_PROP_NAME$g, function (newValue) { + if (newValue !== this.show) { + this.show = newValue; + } + }), _defineProperty(_watch$g, "show", function show(newValue, oldValue) { + if (newValue !== oldValue) { + this.emitState(); + } + }), _watch$g), + created: function created() { + this.show = this[MODEL_PROP_NAME$g]; + }, + mounted: function mounted() { + var _this2 = this; + + this.show = this[MODEL_PROP_NAME$g]; // Listen for toggle events to open/close us + + this.listenOnRoot(ROOT_ACTION_EVENT_NAME_TOGGLE$2, this.handleToggleEvent); // Listen to other collapses for accordion events + + this.listenOnRoot(ROOT_EVENT_NAME_ACCORDION, this.handleAccordionEvent); + + if (this.isNav) { + // Set up handlers + this.setWindowEvents(true); + this.handleResize(); + } + + this.$nextTick(function () { + _this2.emitState(); + }); // Listen for "Sync state" requests from `v-b-toggle` + + this.listenOnRoot(ROOT_ACTION_EVENT_NAME_REQUEST_STATE$2, function (id) { + if (id === _this2.safeId()) { + _this2.$nextTick(_this2.emitSync); + } + }); + }, + updated: function updated() { + // Emit a private event every time this component updates to ensure + // the toggle button is in sync with the collapse's state + // It is emitted regardless if the visible state changes + this.emitSync(); + }, + + /* istanbul ignore next */ + deactivated: function deactivated() { + if (this.isNav) { + this.setWindowEvents(false); + } + }, + + /* istanbul ignore next */ + activated: function activated() { + if (this.isNav) { + this.setWindowEvents(true); + } + + this.emitSync(); + }, + beforeDestroy: function beforeDestroy() { + // Trigger state emit if needed + this.show = false; + + if (this.isNav && IS_BROWSER) { + this.setWindowEvents(false); + } + }, + methods: { + setWindowEvents: function setWindowEvents(on) { + eventOnOff(on, window, 'resize', this.handleResize, EVENT_OPTIONS_NO_CAPTURE); + eventOnOff(on, window, 'orientationchange', this.handleResize, EVENT_OPTIONS_NO_CAPTURE); + }, + toggle: function toggle() { + this.show = !this.show; + }, + onEnter: function onEnter() { + this.transitioning = true; // This should be moved out so we can add cancellable events + + this.$emit(EVENT_NAME_SHOW); + }, + onAfterEnter: function onAfterEnter() { + this.transitioning = false; + this.$emit(EVENT_NAME_SHOWN); + }, + onLeave: function onLeave() { + this.transitioning = true; // This should be moved out so we can add cancellable events + + this.$emit(EVENT_NAME_HIDE); + }, + onAfterLeave: function onAfterLeave() { + this.transitioning = false; + this.$emit(EVENT_NAME_HIDDEN); + }, + emitState: function emitState() { + var show = this.show, + accordion = this.accordion; + var id = this.safeId(); + this.$emit(MODEL_EVENT_NAME$g, show); // Let `v-b-toggle` know the state of this collapse + + this.emitOnRoot(ROOT_EVENT_NAME_STATE$3, id, show); + + if (accordion && show) { + // Tell the other collapses in this accordion to close + this.emitOnRoot(ROOT_EVENT_NAME_ACCORDION, id, accordion); + } + }, + emitSync: function emitSync() { + // Emit a private event every time this component updates to ensure + // the toggle button is in sync with the collapse's state + // It is emitted regardless if the visible state changes + this.emitOnRoot(ROOT_EVENT_NAME_SYNC_STATE$3, this.safeId(), this.show); + }, + checkDisplayBlock: function checkDisplayBlock() { + // Check to see if the collapse has `display: block !important` set + // We can't set `display: none` directly on `this.$el`, as it would + // trigger a new transition to start (or cancel a current one) + var $el = this.$el; + var restore = hasClass($el, CLASS_NAME_SHOW); + removeClass($el, CLASS_NAME_SHOW); + var isBlock = getCS($el).display === 'block'; + + if (restore) { + addClass($el, CLASS_NAME_SHOW); + } + + return isBlock; + }, + clickHandler: function clickHandler(event) { + var el = event.target; // If we are in a nav/navbar, close the collapse when non-disabled link clicked + + /* istanbul ignore next: can't test `getComputedStyle()` in JSDOM */ + + if (!this.isNav || !el || getCS(this.$el).display !== 'block') { + return; + } // Only close the collapse if it is not forced to be `display: block !important` + + + if ((matches(el, '.nav-link,.dropdown-item') || closest('.nav-link,.dropdown-item', el)) && !this.checkDisplayBlock()) { + this.show = false; + } + }, + handleToggleEvent: function handleToggleEvent(id) { + if (id === this.safeId()) { + this.toggle(); + } + }, + handleAccordionEvent: function handleAccordionEvent(openedId, openAccordion) { + var accordion = this.accordion, + show = this.show; + + if (!accordion || accordion !== openAccordion) { + return; + } + + var isThis = openedId === this.safeId(); // Open this collapse if not shown or + // close this collapse if shown + + if (isThis && !show || !isThis && show) { + this.toggle(); + } + }, + handleResize: function handleResize() { + // Handler for orientation/resize to set collapsed state in nav/navbar + this.show = getCS(this.$el).display === 'block'; + } + }, + render: function render(h) { + var appear = this.appear; + var $content = h(this.tag, { + class: this.classObject, + directives: [{ + name: 'show', + value: this.show + }], + attrs: { + id: this.safeId() + }, + on: { + click: this.clickHandler + } + }, this.normalizeSlot(SLOT_NAME_DEFAULT, this.slotScope)); + return h(BVCollapse, { + props: { + appear: appear + }, + on: { + enter: this.onEnter, + afterEnter: this.onAfterEnter, + leave: this.onLeave, + afterLeave: this.onAfterLeave + } + }, [$content]); + } + }); + + var getInstanceFromDirective = function getInstanceFromDirective(vnode, bindings) { + return isVue3 ? bindings.instance : vnode.context; + }; + + // Classes to apply to trigger element + + var CLASS_BV_TOGGLE_COLLAPSED = 'collapsed'; + var CLASS_BV_TOGGLE_NOT_COLLAPSED = 'not-collapsed'; // Property key for handler storage + + var BV_BASE = '__BV_toggle'; // Root event listener property (Function) + + var BV_TOGGLE_ROOT_HANDLER = "".concat(BV_BASE, "_HANDLER__"); // Trigger element click handler property (Function) + + var BV_TOGGLE_CLICK_HANDLER = "".concat(BV_BASE, "_CLICK__"); // Target visibility state property (Boolean) + + var BV_TOGGLE_STATE = "".concat(BV_BASE, "_STATE__"); // Target ID list property (Array) + + var BV_TOGGLE_TARGETS = "".concat(BV_BASE, "_TARGETS__"); // Commonly used strings + + var STRING_FALSE = 'false'; + var STRING_TRUE = 'true'; // Commonly used attribute names + + var ATTR_ARIA_CONTROLS = 'aria-controls'; + var ATTR_ARIA_EXPANDED = 'aria-expanded'; + var ATTR_ROLE = 'role'; + var ATTR_TABINDEX = 'tabindex'; // Commonly used style properties + + var STYLE_OVERFLOW_ANCHOR = 'overflow-anchor'; // Emitted control event for collapse (emitted to collapse) + + var ROOT_ACTION_EVENT_NAME_TOGGLE$1 = getRootActionEventName(NAME_COLLAPSE, 'toggle'); // Listen to event for toggle state update (emitted by collapse) + + var ROOT_EVENT_NAME_STATE$2 = getRootEventName(NAME_COLLAPSE, 'state'); // Private event emitted on `$root` to ensure the toggle state is always synced + // Gets emitted even if the state of b-collapse has not changed + // This event is NOT to be documented as people should not be using it + + var ROOT_EVENT_NAME_SYNC_STATE$2 = getRootEventName(NAME_COLLAPSE, 'sync-state'); // Private event we send to collapse to request state update sync event + + var ROOT_ACTION_EVENT_NAME_REQUEST_STATE$1 = getRootActionEventName(NAME_COLLAPSE, 'request-state'); + var KEYDOWN_KEY_CODES = [CODE_ENTER, CODE_SPACE]; // --- Helper methods --- + + var isNonStandardTag = function isNonStandardTag(el) { + return !arrayIncludes(['button', 'a'], el.tagName.toLowerCase()); + }; + + var getTargets = function getTargets(_ref, el) { + var modifiers = _ref.modifiers, + arg = _ref.arg, + value = _ref.value; + // Any modifiers are considered target IDs + var targets = keys(modifiers || {}); // If value is a string, split out individual targets (if space delimited) + + value = isString(value) ? value.split(RX_SPACE_SPLIT) : value; // Support target ID as link href (`href="#id"`) + + if (isTag(el.tagName, 'a')) { + var href = getAttr(el, 'href') || ''; + + if (RX_HASH_ID.test(href)) { + targets.push(href.replace(RX_HASH, '')); + } + } // Add ID from `arg` (if provided), and support value + // as a single string ID or an array of string IDs + // If `value` is not an array or string, then it gets filtered out + + + concat(arg, value).forEach(function (t) { + return isString(t) && targets.push(t); + }); // Return only unique and truthy target IDs + + return targets.filter(function (t, index, arr) { + return t && arr.indexOf(t) === index; + }); + }; + + var removeClickListener = function removeClickListener(el) { + var handler = el[BV_TOGGLE_CLICK_HANDLER]; + + if (handler) { + eventOff(el, 'click', handler, EVENT_OPTIONS_PASSIVE); + eventOff(el, 'keydown', handler, EVENT_OPTIONS_PASSIVE); + } + + el[BV_TOGGLE_CLICK_HANDLER] = null; + }; + + var addClickListener = function addClickListener(el, instance) { + removeClickListener(el); + + if (instance) { + var handler = function handler(event) { + if (!(event.type === 'keydown' && !arrayIncludes(KEYDOWN_KEY_CODES, event.keyCode)) && !isDisabled(el)) { + var targets = el[BV_TOGGLE_TARGETS] || []; + targets.forEach(function (target) { + getEventRoot(instance).$emit(ROOT_ACTION_EVENT_NAME_TOGGLE$1, target); + }); + } + }; + + el[BV_TOGGLE_CLICK_HANDLER] = handler; + eventOn(el, 'click', handler, EVENT_OPTIONS_PASSIVE); + + if (isNonStandardTag(el)) { + eventOn(el, 'keydown', handler, EVENT_OPTIONS_PASSIVE); + } + } + }; + + var removeRootListeners = function removeRootListeners(el, instance) { + if (el[BV_TOGGLE_ROOT_HANDLER] && instance) { + getEventRoot(instance).$off([ROOT_EVENT_NAME_STATE$2, ROOT_EVENT_NAME_SYNC_STATE$2], el[BV_TOGGLE_ROOT_HANDLER]); + } + + el[BV_TOGGLE_ROOT_HANDLER] = null; + }; + + var addRootListeners = function addRootListeners(el, instance) { + removeRootListeners(el, instance); + + if (instance) { + var handler = function handler(id, state) { + // `state` will be `true` if target is expanded + if (arrayIncludes(el[BV_TOGGLE_TARGETS] || [], id)) { + // Set/Clear 'collapsed' visibility class state + el[BV_TOGGLE_STATE] = state; // Set `aria-expanded` and class state on trigger element + + setToggleState(el, state); + } + }; + + el[BV_TOGGLE_ROOT_HANDLER] = handler; // Listen for toggle state changes (public) and sync (private) + + getEventRoot(instance).$on([ROOT_EVENT_NAME_STATE$2, ROOT_EVENT_NAME_SYNC_STATE$2], handler); + } + }; + + var setToggleState = function setToggleState(el, state) { + // State refers to the visibility of the collapse/sidebar + if (state) { + removeClass(el, CLASS_BV_TOGGLE_COLLAPSED); + addClass(el, CLASS_BV_TOGGLE_NOT_COLLAPSED); + setAttr(el, ATTR_ARIA_EXPANDED, STRING_TRUE); + } else { + removeClass(el, CLASS_BV_TOGGLE_NOT_COLLAPSED); + addClass(el, CLASS_BV_TOGGLE_COLLAPSED); + setAttr(el, ATTR_ARIA_EXPANDED, STRING_FALSE); + } + }; // Reset and remove a property from the provided element + + + var resetProp = function resetProp(el, prop) { + el[prop] = null; + delete el[prop]; + }; // Handle directive updates + + + var handleUpdate = function handleUpdate(el, binding, vnode) { + /* istanbul ignore next: should never happen */ + if (!IS_BROWSER || !getInstanceFromDirective(vnode, binding)) { + return; + } // If element is not a button or link, we add `role="button"` + // and `tabindex="0"` for accessibility reasons + + + if (isNonStandardTag(el)) { + if (!hasAttr(el, ATTR_ROLE)) { + setAttr(el, ATTR_ROLE, 'button'); + } + + if (!hasAttr(el, ATTR_TABINDEX)) { + setAttr(el, ATTR_TABINDEX, '0'); + } + } // Ensure the collapse class and `aria-*` attributes persist + // after element is updated (either by parent re-rendering + // or changes to this element or its contents) + + + setToggleState(el, el[BV_TOGGLE_STATE]); // Parse list of target IDs + + var targets = getTargets(binding, el); // Ensure the `aria-controls` hasn't been overwritten + // or removed when vnode updates + // Also ensure to set `overflow-anchor` to `none` to prevent + // the browser's scroll anchoring behavior + + /* istanbul ignore else */ + + if (targets.length > 0) { + setAttr(el, ATTR_ARIA_CONTROLS, targets.join(' ')); + setStyle(el, STYLE_OVERFLOW_ANCHOR, 'none'); + } else { + removeAttr(el, ATTR_ARIA_CONTROLS); + removeStyle(el, STYLE_OVERFLOW_ANCHOR); + } // Add/Update our click listener(s) + // Wrap in a `requestAF()` to allow any previous + // click handling to occur first + + + requestAF(function () { + addClickListener(el, getInstanceFromDirective(vnode, binding)); + }); // If targets array has changed, update + + if (!looseEqual(targets, el[BV_TOGGLE_TARGETS])) { + // Update targets array to element storage + el[BV_TOGGLE_TARGETS] = targets; // Ensure `aria-controls` is up to date + // Request a state update from targets so that we can + // ensure expanded state is correct (in most cases) + + targets.forEach(function (target) { + getEventRoot(getInstanceFromDirective(vnode, binding)).$emit(ROOT_ACTION_EVENT_NAME_REQUEST_STATE$1, target); + }); + } + }; + /* + * Export our directive + */ + + + var VBToggle = { + bind: function bind(el, binding, vnode) { + // State is initially collapsed until we receive a state event + el[BV_TOGGLE_STATE] = false; // Assume no targets initially + + el[BV_TOGGLE_TARGETS] = []; // Add our root listeners + + addRootListeners(el, getInstanceFromDirective(vnode, binding)); // Initial update of trigger + + handleUpdate(el, binding, vnode); + }, + componentUpdated: handleUpdate, + updated: handleUpdate, + unbind: function unbind(el, binding, vnode) { + removeClickListener(el); // Remove our $root listener + + removeRootListeners(el, getInstanceFromDirective(vnode, binding)); // Reset custom props + + resetProp(el, BV_TOGGLE_ROOT_HANDLER); + resetProp(el, BV_TOGGLE_CLICK_HANDLER); + resetProp(el, BV_TOGGLE_STATE); + resetProp(el, BV_TOGGLE_TARGETS); // Reset classes/attrs/styles + + removeClass(el, CLASS_BV_TOGGLE_COLLAPSED); + removeClass(el, CLASS_BV_TOGGLE_NOT_COLLAPSED); + removeAttr(el, ATTR_ARIA_EXPANDED); + removeAttr(el, ATTR_ARIA_CONTROLS); + removeAttr(el, ATTR_ROLE); + removeStyle(el, STYLE_OVERFLOW_ANCHOR); + } + }; + + var VBTogglePlugin = /*#__PURE__*/pluginFactory({ + directives: { + VBToggle: VBToggle + } + }); + + var CollapsePlugin = /*#__PURE__*/pluginFactory({ + components: { + BCollapse: BCollapse + }, + plugins: { + VBTogglePlugin: VBTogglePlugin + } + }); + + /**! + * @fileOverview Kickass library to create and place poppers near their reference elements. + * @version 1.16.1 + * @license + * Copyright (c) 2016 Federico Zivolo and contributors + * + * 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. + */ + var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined'; + + var timeoutDuration = function () { + var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; + for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { + if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { + return 1; + } + } + return 0; + }(); + + function microtaskDebounce(fn) { + var called = false; + return function () { + if (called) { + return; + } + called = true; + window.Promise.resolve().then(function () { + called = false; + fn(); + }); + }; + } + + function taskDebounce(fn) { + var scheduled = false; + return function () { + if (!scheduled) { + scheduled = true; + setTimeout(function () { + scheduled = false; + fn(); + }, timeoutDuration); + } + }; + } + + var supportsMicroTasks = isBrowser && window.Promise; + + /** + * Create a debounced version of a method, that's asynchronously deferred + * but called in the minimum time possible. + * + * @method + * @memberof Popper.Utils + * @argument {Function} fn + * @returns {Function} + */ + var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; + + /** + * Check if the given variable is a function + * @method + * @memberof Popper.Utils + * @argument {Any} functionToCheck - variable to check + * @returns {Boolean} answer to: is a function? + */ + function isFunction(functionToCheck) { + var getType = {}; + return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; + } + + /** + * Get CSS computed property of the given element + * @method + * @memberof Popper.Utils + * @argument {Eement} element + * @argument {String} property + */ + function getStyleComputedProperty(element, property) { + if (element.nodeType !== 1) { + return []; + } + // NOTE: 1 DOM access here + var window = element.ownerDocument.defaultView; + var css = window.getComputedStyle(element, null); + return property ? css[property] : css; + } + + /** + * Returns the parentNode or the host of the element + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} parent + */ + function getParentNode(element) { + if (element.nodeName === 'HTML') { + return element; + } + return element.parentNode || element.host; + } + + /** + * Returns the scrolling parent of the given element + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} scroll parent + */ + function getScrollParent(element) { + // Return body, `getScroll` will take care to get the correct `scrollTop` from it + if (!element) { + return document.body; + } + + switch (element.nodeName) { + case 'HTML': + case 'BODY': + return element.ownerDocument.body; + case '#document': + return element.body; + } + + // Firefox want us to check `-x` and `-y` variations as well + + var _getStyleComputedProp = getStyleComputedProperty(element), + overflow = _getStyleComputedProp.overflow, + overflowX = _getStyleComputedProp.overflowX, + overflowY = _getStyleComputedProp.overflowY; + + if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { + return element; + } + + return getScrollParent(getParentNode(element)); + } + + /** + * Returns the reference node of the reference object, or the reference object itself. + * @method + * @memberof Popper.Utils + * @param {Element|Object} reference - the reference element (the popper will be relative to this) + * @returns {Element} parent + */ + function getReferenceNode(reference) { + return reference && reference.referenceNode ? reference.referenceNode : reference; + } + + var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); + var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); + + /** + * Determines if the browser is Internet Explorer + * @method + * @memberof Popper.Utils + * @param {Number} version to check + * @returns {Boolean} isIE + */ + function isIE(version) { + if (version === 11) { + return isIE11; + } + if (version === 10) { + return isIE10; + } + return isIE11 || isIE10; + } + + /** + * Returns the offset parent of the given element + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} offset parent + */ + function getOffsetParent(element) { + if (!element) { + return document.documentElement; + } + + var noOffsetParent = isIE(10) ? document.body : null; + + // NOTE: 1 DOM access here + var offsetParent = element.offsetParent || null; + // Skip hidden elements which don't have an offsetParent + while (offsetParent === noOffsetParent && element.nextElementSibling) { + offsetParent = (element = element.nextElementSibling).offsetParent; + } + + var nodeName = offsetParent && offsetParent.nodeName; + + if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { + return element ? element.ownerDocument.documentElement : document.documentElement; + } + + // .offsetParent will return the closest TH, TD or TABLE in case + // no offsetParent is present, I hate this job... + if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { + return getOffsetParent(offsetParent); + } + + return offsetParent; + } + + function isOffsetContainer(element) { + var nodeName = element.nodeName; + + if (nodeName === 'BODY') { + return false; + } + return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; + } + + /** + * Finds the root node (document, shadowDOM root) of the given element + * @method + * @memberof Popper.Utils + * @argument {Element} node + * @returns {Element} root node + */ + function getRoot(node) { + if (node.parentNode !== null) { + return getRoot(node.parentNode); + } + + return node; + } + + /** + * Finds the offset parent common to the two provided nodes + * @method + * @memberof Popper.Utils + * @argument {Element} element1 + * @argument {Element} element2 + * @returns {Element} common offset parent + */ + function findCommonOffsetParent(element1, element2) { + // This check is needed to avoid errors in case one of the elements isn't defined for any reason + if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { + return document.documentElement; + } + + // Here we make sure to give as "start" the element that comes first in the DOM + var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; + var start = order ? element1 : element2; + var end = order ? element2 : element1; + + // Get common ancestor container + var range = document.createRange(); + range.setStart(start, 0); + range.setEnd(end, 0); + var commonAncestorContainer = range.commonAncestorContainer; + + // Both nodes are inside #document + + if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { + if (isOffsetContainer(commonAncestorContainer)) { + return commonAncestorContainer; + } + + return getOffsetParent(commonAncestorContainer); + } + + // one of the nodes is inside shadowDOM, find which one + var element1root = getRoot(element1); + if (element1root.host) { + return findCommonOffsetParent(element1root.host, element2); + } else { + return findCommonOffsetParent(element1, getRoot(element2).host); + } + } + + /** + * Gets the scroll value of the given element in the given side (top and left) + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @argument {String} side `top` or `left` + * @returns {number} amount of scrolled pixels + */ + function getScroll(element) { + var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; + + var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; + var nodeName = element.nodeName; + + if (nodeName === 'BODY' || nodeName === 'HTML') { + var html = element.ownerDocument.documentElement; + var scrollingElement = element.ownerDocument.scrollingElement || html; + return scrollingElement[upperSide]; + } + + return element[upperSide]; + } + + /* + * Sum or subtract the element scroll values (left and top) from a given rect object + * @method + * @memberof Popper.Utils + * @param {Object} rect - Rect object you want to change + * @param {HTMLElement} element - The element from the function reads the scroll values + * @param {Boolean} subtract - set to true if you want to subtract the scroll values + * @return {Object} rect - The modifier rect object + */ + function includeScroll(rect, element) { + var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var scrollTop = getScroll(element, 'top'); + var scrollLeft = getScroll(element, 'left'); + var modifier = subtract ? -1 : 1; + rect.top += scrollTop * modifier; + rect.bottom += scrollTop * modifier; + rect.left += scrollLeft * modifier; + rect.right += scrollLeft * modifier; + return rect; + } + + /* + * Helper to detect borders of a given element + * @method + * @memberof Popper.Utils + * @param {CSSStyleDeclaration} styles + * Result of `getStyleComputedProperty` on the given element + * @param {String} axis - `x` or `y` + * @return {number} borders - The borders size of the given axis + */ + + function getBordersSize(styles, axis) { + var sideA = axis === 'x' ? 'Left' : 'Top'; + var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; + + return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']); + } + + function getSize(axis, body, html, computedStyle) { + return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0); + } + + function getWindowSizes(document) { + var body = document.body; + var html = document.documentElement; + var computedStyle = isIE(10) && getComputedStyle(html); + + return { + height: getSize('Height', body, html, computedStyle), + width: getSize('Width', body, html, computedStyle) + }; + } + + var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + }; + + var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + + + + + var defineProperty = function (obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + }; + + var _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + /** + * Given element offsets, generate an output similar to getBoundingClientRect + * @method + * @memberof Popper.Utils + * @argument {Object} offsets + * @returns {Object} ClientRect like output + */ + function getClientRect(offsets) { + return _extends({}, offsets, { + right: offsets.left + offsets.width, + bottom: offsets.top + offsets.height + }); + } + + /** + * Get bounding client rect of given element + * @method + * @memberof Popper.Utils + * @param {HTMLElement} element + * @return {Object} client rect + */ + function getBoundingClientRect(element) { + var rect = {}; + + // IE10 10 FIX: Please, don't ask, the element isn't + // considered in DOM in some circumstances... + // This isn't reproducible in IE10 compatibility mode of IE11 + try { + if (isIE(10)) { + rect = element.getBoundingClientRect(); + var scrollTop = getScroll(element, 'top'); + var scrollLeft = getScroll(element, 'left'); + rect.top += scrollTop; + rect.left += scrollLeft; + rect.bottom += scrollTop; + rect.right += scrollLeft; + } else { + rect = element.getBoundingClientRect(); + } + } catch (e) {} + + var result = { + left: rect.left, + top: rect.top, + width: rect.right - rect.left, + height: rect.bottom - rect.top + }; + + // subtract scrollbar size from sizes + var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {}; + var width = sizes.width || element.clientWidth || result.width; + var height = sizes.height || element.clientHeight || result.height; + + var horizScrollbar = element.offsetWidth - width; + var vertScrollbar = element.offsetHeight - height; + + // if an hypothetical scrollbar is detected, we must be sure it's not a `border` + // we make this check conditional for performance reasons + if (horizScrollbar || vertScrollbar) { + var styles = getStyleComputedProperty(element); + horizScrollbar -= getBordersSize(styles, 'x'); + vertScrollbar -= getBordersSize(styles, 'y'); + + result.width -= horizScrollbar; + result.height -= vertScrollbar; + } + + return getClientRect(result); + } + + function getOffsetRectRelativeToArbitraryNode(children, parent) { + var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var isIE10 = isIE(10); + var isHTML = parent.nodeName === 'HTML'; + var childrenRect = getBoundingClientRect(children); + var parentRect = getBoundingClientRect(parent); + var scrollParent = getScrollParent(children); + + var styles = getStyleComputedProperty(parent); + var borderTopWidth = parseFloat(styles.borderTopWidth); + var borderLeftWidth = parseFloat(styles.borderLeftWidth); + + // In cases where the parent is fixed, we must ignore negative scroll in offset calc + if (fixedPosition && isHTML) { + parentRect.top = Math.max(parentRect.top, 0); + parentRect.left = Math.max(parentRect.left, 0); + } + var offsets = getClientRect({ + top: childrenRect.top - parentRect.top - borderTopWidth, + left: childrenRect.left - parentRect.left - borderLeftWidth, + width: childrenRect.width, + height: childrenRect.height + }); + offsets.marginTop = 0; + offsets.marginLeft = 0; + + // Subtract margins of documentElement in case it's being used as parent + // we do this only on HTML because it's the only element that behaves + // differently when margins are applied to it. The margins are included in + // the box of the documentElement, in the other cases not. + if (!isIE10 && isHTML) { + var marginTop = parseFloat(styles.marginTop); + var marginLeft = parseFloat(styles.marginLeft); + + offsets.top -= borderTopWidth - marginTop; + offsets.bottom -= borderTopWidth - marginTop; + offsets.left -= borderLeftWidth - marginLeft; + offsets.right -= borderLeftWidth - marginLeft; + + // Attach marginTop and marginLeft because in some circumstances we may need them + offsets.marginTop = marginTop; + offsets.marginLeft = marginLeft; + } + + if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { + offsets = includeScroll(offsets, parent); + } + + return offsets; + } + + function getViewportOffsetRectRelativeToArtbitraryNode(element) { + var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var html = element.ownerDocument.documentElement; + var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); + var width = Math.max(html.clientWidth, window.innerWidth || 0); + var height = Math.max(html.clientHeight, window.innerHeight || 0); + + var scrollTop = !excludeScroll ? getScroll(html) : 0; + var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; + + var offset = { + top: scrollTop - relativeOffset.top + relativeOffset.marginTop, + left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, + width: width, + height: height + }; + + return getClientRect(offset); + } + + /** + * Check if the given element is fixed or is inside a fixed parent + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @argument {Element} customContainer + * @returns {Boolean} answer to "isFixed?" + */ + function isFixed(element) { + var nodeName = element.nodeName; + if (nodeName === 'BODY' || nodeName === 'HTML') { + return false; + } + if (getStyleComputedProperty(element, 'position') === 'fixed') { + return true; + } + var parentNode = getParentNode(element); + if (!parentNode) { + return false; + } + return isFixed(parentNode); + } + + /** + * Finds the first parent of an element that has a transformed property defined + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} first transformed parent or documentElement + */ + + function getFixedPositionOffsetParent(element) { + // This check is needed to avoid errors in case one of the elements isn't defined for any reason + if (!element || !element.parentElement || isIE()) { + return document.documentElement; + } + var el = element.parentElement; + while (el && getStyleComputedProperty(el, 'transform') === 'none') { + el = el.parentElement; + } + return el || document.documentElement; + } + + /** + * Computed the boundaries limits and return them + * @method + * @memberof Popper.Utils + * @param {HTMLElement} popper + * @param {HTMLElement} reference + * @param {number} padding + * @param {HTMLElement} boundariesElement - Element used to define the boundaries + * @param {Boolean} fixedPosition - Is in fixed position mode + * @returns {Object} Coordinates of the boundaries + */ + function getBoundaries(popper, reference, padding, boundariesElement) { + var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + + // NOTE: 1 DOM access here + + var boundaries = { top: 0, left: 0 }; + var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); + + // Handle viewport case + if (boundariesElement === 'viewport') { + boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); + } else { + // Handle other cases based on DOM element used as boundaries + var boundariesNode = void 0; + if (boundariesElement === 'scrollParent') { + boundariesNode = getScrollParent(getParentNode(reference)); + if (boundariesNode.nodeName === 'BODY') { + boundariesNode = popper.ownerDocument.documentElement; + } + } else if (boundariesElement === 'window') { + boundariesNode = popper.ownerDocument.documentElement; + } else { + boundariesNode = boundariesElement; + } + + var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); + + // In case of HTML, we need a different computation + if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { + var _getWindowSizes = getWindowSizes(popper.ownerDocument), + height = _getWindowSizes.height, + width = _getWindowSizes.width; + + boundaries.top += offsets.top - offsets.marginTop; + boundaries.bottom = height + offsets.top; + boundaries.left += offsets.left - offsets.marginLeft; + boundaries.right = width + offsets.left; + } else { + // for all the other DOM elements, this one is good + boundaries = offsets; + } + } + + // Add paddings + padding = padding || 0; + var isPaddingNumber = typeof padding === 'number'; + boundaries.left += isPaddingNumber ? padding : padding.left || 0; + boundaries.top += isPaddingNumber ? padding : padding.top || 0; + boundaries.right -= isPaddingNumber ? padding : padding.right || 0; + boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; + + return boundaries; + } + + function getArea(_ref) { + var width = _ref.width, + height = _ref.height; + + return width * height; + } + + /** + * Utility used to transform the `auto` placement to the placement with more + * available space. + * @method + * @memberof Popper.Utils + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { + var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; + + if (placement.indexOf('auto') === -1) { + return placement; + } + + var boundaries = getBoundaries(popper, reference, padding, boundariesElement); + + var rects = { + top: { + width: boundaries.width, + height: refRect.top - boundaries.top + }, + right: { + width: boundaries.right - refRect.right, + height: boundaries.height + }, + bottom: { + width: boundaries.width, + height: boundaries.bottom - refRect.bottom + }, + left: { + width: refRect.left - boundaries.left, + height: boundaries.height + } + }; + + var sortedAreas = Object.keys(rects).map(function (key) { + return _extends({ + key: key + }, rects[key], { + area: getArea(rects[key]) + }); + }).sort(function (a, b) { + return b.area - a.area; + }); + + var filteredAreas = sortedAreas.filter(function (_ref2) { + var width = _ref2.width, + height = _ref2.height; + return width >= popper.clientWidth && height >= popper.clientHeight; + }); + + var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; + + var variation = placement.split('-')[1]; + + return computedPlacement + (variation ? '-' + variation : ''); + } + + /** + * Get offsets to the reference element + * @method + * @memberof Popper.Utils + * @param {Object} state + * @param {Element} popper - the popper element + * @param {Element} reference - the reference element (the popper will be relative to this) + * @param {Element} fixedPosition - is in fixed position mode + * @returns {Object} An object containing the offsets which will be applied to the popper + */ + function getReferenceOffsets(state, popper, reference) { + var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + + var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); + return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); + } + + /** + * Get the outer sizes of the given element (offset size + margins) + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Object} object containing width and height properties + */ + function getOuterSizes(element) { + var window = element.ownerDocument.defaultView; + var styles = window.getComputedStyle(element); + var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0); + var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0); + var result = { + width: element.offsetWidth + y, + height: element.offsetHeight + x + }; + return result; + } + + /** + * Get the opposite placement of the given one + * @method + * @memberof Popper.Utils + * @argument {String} placement + * @returns {String} flipped placement + */ + function getOppositePlacement(placement) { + var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; + return placement.replace(/left|right|bottom|top/g, function (matched) { + return hash[matched]; + }); + } + + /** + * Get offsets to the popper + * @method + * @memberof Popper.Utils + * @param {Object} position - CSS position the Popper will get applied + * @param {HTMLElement} popper - the popper element + * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) + * @param {String} placement - one of the valid placement options + * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper + */ + function getPopperOffsets(popper, referenceOffsets, placement) { + placement = placement.split('-')[0]; + + // Get popper node sizes + var popperRect = getOuterSizes(popper); + + // Add position, width and height to our offsets object + var popperOffsets = { + width: popperRect.width, + height: popperRect.height + }; + + // depending by the popper placement we have to compute its offsets slightly differently + var isHoriz = ['right', 'left'].indexOf(placement) !== -1; + var mainSide = isHoriz ? 'top' : 'left'; + var secondarySide = isHoriz ? 'left' : 'top'; + var measurement = isHoriz ? 'height' : 'width'; + var secondaryMeasurement = !isHoriz ? 'height' : 'width'; + + popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; + if (placement === secondarySide) { + popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; + } else { + popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; + } + + return popperOffsets; + } + + /** + * Mimics the `find` method of Array + * @method + * @memberof Popper.Utils + * @argument {Array} arr + * @argument prop + * @argument value + * @returns index or -1 + */ + function find(arr, check) { + // use native find if supported + if (Array.prototype.find) { + return arr.find(check); + } + + // use `filter` to obtain the same behavior of `find` + return arr.filter(check)[0]; + } + + /** + * Return the index of the matching object + * @method + * @memberof Popper.Utils + * @argument {Array} arr + * @argument prop + * @argument value + * @returns index or -1 + */ + function findIndex(arr, prop, value) { + // use native findIndex if supported + if (Array.prototype.findIndex) { + return arr.findIndex(function (cur) { + return cur[prop] === value; + }); + } + + // use `find` + `indexOf` if `findIndex` isn't supported + var match = find(arr, function (obj) { + return obj[prop] === value; + }); + return arr.indexOf(match); + } + + /** + * Loop trough the list of modifiers and run them in order, + * each of them will then edit the data object. + * @method + * @memberof Popper.Utils + * @param {dataObject} data + * @param {Array} modifiers + * @param {String} ends - Optional modifier name used as stopper + * @returns {dataObject} + */ + function runModifiers(modifiers, data, ends) { + var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); + + modifiersToRun.forEach(function (modifier) { + if (modifier['function']) { + // eslint-disable-line dot-notation + console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); + } + var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation + if (modifier.enabled && isFunction(fn)) { + // Add properties to offsets to make them a complete clientRect object + // we do this before each modifier to make sure the previous one doesn't + // mess with these values + data.offsets.popper = getClientRect(data.offsets.popper); + data.offsets.reference = getClientRect(data.offsets.reference); + + data = fn(data, modifier); + } + }); + + return data; + } + + /** + * Updates the position of the popper, computing the new offsets and applying + * the new style.
+ * Prefer `scheduleUpdate` over `update` because of performance reasons. + * @method + * @memberof Popper + */ + function update() { + // if popper is destroyed, don't perform any further update + if (this.state.isDestroyed) { + return; + } + + var data = { + instance: this, + styles: {}, + arrowStyles: {}, + attributes: {}, + flipped: false, + offsets: {} + }; + + // compute reference element offsets + data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); + + // compute auto placement, store placement inside the data object, + // modifiers will be able to edit `placement` if needed + // and refer to originalPlacement to know the original value + data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); + + // store the computed placement inside `originalPlacement` + data.originalPlacement = data.placement; + + data.positionFixed = this.options.positionFixed; + + // compute the popper offsets + data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); + + data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; + + // run the modifiers + data = runModifiers(this.modifiers, data); + + // the first `update` will call `onCreate` callback + // the other ones will call `onUpdate` callback + if (!this.state.isCreated) { + this.state.isCreated = true; + this.options.onCreate(data); + } else { + this.options.onUpdate(data); + } + } + + /** + * Helper used to know if the given modifier is enabled. + * @method + * @memberof Popper.Utils + * @returns {Boolean} + */ + function isModifierEnabled(modifiers, modifierName) { + return modifiers.some(function (_ref) { + var name = _ref.name, + enabled = _ref.enabled; + return enabled && name === modifierName; + }); + } + + /** + * Get the prefixed supported property name + * @method + * @memberof Popper.Utils + * @argument {String} property (camelCase) + * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) + */ + function getSupportedPropertyName(property) { + var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; + var upperProp = property.charAt(0).toUpperCase() + property.slice(1); + + for (var i = 0; i < prefixes.length; i++) { + var prefix = prefixes[i]; + var toCheck = prefix ? '' + prefix + upperProp : property; + if (typeof document.body.style[toCheck] !== 'undefined') { + return toCheck; + } + } + return null; + } + + /** + * Destroys the popper. + * @method + * @memberof Popper + */ + function destroy() { + this.state.isDestroyed = true; + + // touch DOM only if `applyStyle` modifier is enabled + if (isModifierEnabled(this.modifiers, 'applyStyle')) { + this.popper.removeAttribute('x-placement'); + this.popper.style.position = ''; + this.popper.style.top = ''; + this.popper.style.left = ''; + this.popper.style.right = ''; + this.popper.style.bottom = ''; + this.popper.style.willChange = ''; + this.popper.style[getSupportedPropertyName('transform')] = ''; + } + + this.disableEventListeners(); + + // remove the popper if user explicitly asked for the deletion on destroy + // do not use `remove` because IE11 doesn't support it + if (this.options.removeOnDestroy) { + this.popper.parentNode.removeChild(this.popper); + } + return this; + } + + /** + * Get the window associated with the element + * @argument {Element} element + * @returns {Window} + */ + function getWindow(element) { + var ownerDocument = element.ownerDocument; + return ownerDocument ? ownerDocument.defaultView : window; + } + + function attachToScrollParents(scrollParent, event, callback, scrollParents) { + var isBody = scrollParent.nodeName === 'BODY'; + var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; + target.addEventListener(event, callback, { passive: true }); + + if (!isBody) { + attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); + } + scrollParents.push(target); + } + + /** + * Setup needed event listeners used to update the popper position + * @method + * @memberof Popper.Utils + * @private + */ + function setupEventListeners(reference, options, state, updateBound) { + // Resize event listener on window + state.updateBound = updateBound; + getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); + + // Scroll event listener on scroll parents + var scrollElement = getScrollParent(reference); + attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); + state.scrollElement = scrollElement; + state.eventsEnabled = true; + + return state; + } + + /** + * It will add resize/scroll events and start recalculating + * position of the popper element when they are triggered. + * @method + * @memberof Popper + */ + function enableEventListeners() { + if (!this.state.eventsEnabled) { + this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); + } + } + + /** + * Remove event listeners used to update the popper position + * @method + * @memberof Popper.Utils + * @private + */ + function removeEventListeners(reference, state) { + // Remove resize event listener on window + getWindow(reference).removeEventListener('resize', state.updateBound); + + // Remove scroll event listener on scroll parents + state.scrollParents.forEach(function (target) { + target.removeEventListener('scroll', state.updateBound); + }); + + // Reset state + state.updateBound = null; + state.scrollParents = []; + state.scrollElement = null; + state.eventsEnabled = false; + return state; + } + + /** + * It will remove resize/scroll events and won't recalculate popper position + * when they are triggered. It also won't trigger `onUpdate` callback anymore, + * unless you call `update` method manually. + * @method + * @memberof Popper + */ + function disableEventListeners() { + if (this.state.eventsEnabled) { + cancelAnimationFrame(this.scheduleUpdate); + this.state = removeEventListeners(this.reference, this.state); + } + } + + /** + * Tells if a given input is a number + * @method + * @memberof Popper.Utils + * @param {*} input to check + * @return {Boolean} + */ + function isNumeric(n) { + return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); + } + + /** + * Set the style to the given popper + * @method + * @memberof Popper.Utils + * @argument {Element} element - Element to apply the style to + * @argument {Object} styles + * Object with a list of properties and values which will be applied to the element + */ + function setStyles(element, styles) { + Object.keys(styles).forEach(function (prop) { + var unit = ''; + // add unit if the value is numeric and is one of the following + if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { + unit = 'px'; + } + element.style[prop] = styles[prop] + unit; + }); + } + + /** + * Set the attributes to the given popper + * @method + * @memberof Popper.Utils + * @argument {Element} element - Element to apply the attributes to + * @argument {Object} styles + * Object with a list of properties and values which will be applied to the element + */ + function setAttributes(element, attributes) { + Object.keys(attributes).forEach(function (prop) { + var value = attributes[prop]; + if (value !== false) { + element.setAttribute(prop, attributes[prop]); + } else { + element.removeAttribute(prop); + } + }); + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} data.styles - List of style properties - values to apply to popper element + * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The same data object + */ + function applyStyle(data) { + // any property present in `data.styles` will be applied to the popper, + // in this way we can make the 3rd party modifiers add custom styles to it + // Be aware, modifiers could override the properties defined in the previous + // lines of this modifier! + setStyles(data.instance.popper, data.styles); + + // any property present in `data.attributes` will be applied to the popper, + // they will be set as HTML attributes of the element + setAttributes(data.instance.popper, data.attributes); + + // if arrowElement is defined and arrowStyles has some properties + if (data.arrowElement && Object.keys(data.arrowStyles).length) { + setStyles(data.arrowElement, data.arrowStyles); + } + + return data; + } + + /** + * Set the x-placement attribute before everything else because it could be used + * to add margins to the popper margins needs to be calculated to get the + * correct popper offsets. + * @method + * @memberof Popper.modifiers + * @param {HTMLElement} reference - The reference element used to position the popper + * @param {HTMLElement} popper - The HTML element used as popper + * @param {Object} options - Popper.js options + */ + function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { + // compute reference element offsets + var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); + + // compute auto placement, store placement inside the data object, + // modifiers will be able to edit `placement` if needed + // and refer to originalPlacement to know the original value + var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); + + popper.setAttribute('x-placement', placement); + + // Apply `position` to popper before anything else because + // without the position applied we can't guarantee correct computations + setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); + + return options; + } + + /** + * @function + * @memberof Popper.Utils + * @argument {Object} data - The data object generated by `update` method + * @argument {Boolean} shouldRound - If the offsets should be rounded at all + * @returns {Object} The popper's position offsets rounded + * + * The tale of pixel-perfect positioning. It's still not 100% perfect, but as + * good as it can be within reason. + * Discussion here: https://github.com/FezVrasta/popper.js/pull/715 + * + * Low DPI screens cause a popper to be blurry if not using full pixels (Safari + * as well on High DPI screens). + * + * Firefox prefers no rounding for positioning and does not have blurriness on + * high DPI screens. + * + * Only horizontal placement and left/right values need to be considered. + */ + function getRoundedOffsets(data, shouldRound) { + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + var round = Math.round, + floor = Math.floor; + + var noRound = function noRound(v) { + return v; + }; + + var referenceWidth = round(reference.width); + var popperWidth = round(popper.width); + + var isVertical = ['left', 'right'].indexOf(data.placement) !== -1; + var isVariation = data.placement.indexOf('-') !== -1; + var sameWidthParity = referenceWidth % 2 === popperWidth % 2; + var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1; + + var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor; + var verticalToInteger = !shouldRound ? noRound : round; + + return { + left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left), + top: verticalToInteger(popper.top), + bottom: verticalToInteger(popper.bottom), + right: horizontalToInteger(popper.right) + }; + } + + var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent); + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function computeStyle(data, options) { + var x = options.x, + y = options.y; + var popper = data.offsets.popper; + + // Remove this legacy support in Popper.js v2 + + var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { + return modifier.name === 'applyStyle'; + }).gpuAcceleration; + if (legacyGpuAccelerationOption !== undefined) { + console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); + } + var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; + + var offsetParent = getOffsetParent(data.instance.popper); + var offsetParentRect = getBoundingClientRect(offsetParent); + + // Styles + var styles = { + position: popper.position + }; + + var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox); + + var sideA = x === 'bottom' ? 'top' : 'bottom'; + var sideB = y === 'right' ? 'left' : 'right'; + + // if gpuAcceleration is set to `true` and transform is supported, + // we use `translate3d` to apply the position to the popper we + // automatically use the supported prefixed version if needed + var prefixedProperty = getSupportedPropertyName('transform'); + + // now, let's make a step back and look at this code closely (wtf?) + // If the content of the popper grows once it's been positioned, it + // may happen that the popper gets misplaced because of the new content + // overflowing its reference element + // To avoid this problem, we provide two options (x and y), which allow + // the consumer to define the offset origin. + // If we position a popper on top of a reference element, we can set + // `x` to `top` to make the popper grow towards its top instead of + // its bottom. + var left = void 0, + top = void 0; + if (sideA === 'bottom') { + // when offsetParent is the positioning is relative to the bottom of the screen (excluding the scrollbar) + // and not the bottom of the html element + if (offsetParent.nodeName === 'HTML') { + top = -offsetParent.clientHeight + offsets.bottom; + } else { + top = -offsetParentRect.height + offsets.bottom; + } + } else { + top = offsets.top; + } + if (sideB === 'right') { + if (offsetParent.nodeName === 'HTML') { + left = -offsetParent.clientWidth + offsets.right; + } else { + left = -offsetParentRect.width + offsets.right; + } + } else { + left = offsets.left; + } + if (gpuAcceleration && prefixedProperty) { + styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; + styles[sideA] = 0; + styles[sideB] = 0; + styles.willChange = 'transform'; + } else { + // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties + var invertTop = sideA === 'bottom' ? -1 : 1; + var invertLeft = sideB === 'right' ? -1 : 1; + styles[sideA] = top * invertTop; + styles[sideB] = left * invertLeft; + styles.willChange = sideA + ', ' + sideB; + } + + // Attributes + var attributes = { + 'x-placement': data.placement + }; + + // Update `data` attributes, styles and arrowStyles + data.attributes = _extends({}, attributes, data.attributes); + data.styles = _extends({}, styles, data.styles); + data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); + + return data; + } + + /** + * Helper used to know if the given modifier depends from another one.
+ * It checks if the needed modifier is listed and enabled. + * @method + * @memberof Popper.Utils + * @param {Array} modifiers - list of modifiers + * @param {String} requestingName - name of requesting modifier + * @param {String} requestedName - name of requested modifier + * @returns {Boolean} + */ + function isModifierRequired(modifiers, requestingName, requestedName) { + var requesting = find(modifiers, function (_ref) { + var name = _ref.name; + return name === requestingName; + }); + + var isRequired = !!requesting && modifiers.some(function (modifier) { + return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; + }); + + if (!isRequired) { + var _requesting = '`' + requestingName + '`'; + var requested = '`' + requestedName + '`'; + console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); + } + return isRequired; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function arrow(data, options) { + var _data$offsets$arrow; + + // arrow depends on keepTogether in order to work + if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { + return data; + } + + var arrowElement = options.element; + + // if arrowElement is a string, suppose it's a CSS selector + if (typeof arrowElement === 'string') { + arrowElement = data.instance.popper.querySelector(arrowElement); + + // if arrowElement is not found, don't run the modifier + if (!arrowElement) { + return data; + } + } else { + // if the arrowElement isn't a query selector we must check that the + // provided DOM node is child of its popper node + if (!data.instance.popper.contains(arrowElement)) { + console.warn('WARNING: `arrow.element` must be child of its popper element!'); + return data; + } + } + + var placement = data.placement.split('-')[0]; + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var isVertical = ['left', 'right'].indexOf(placement) !== -1; + + var len = isVertical ? 'height' : 'width'; + var sideCapitalized = isVertical ? 'Top' : 'Left'; + var side = sideCapitalized.toLowerCase(); + var altSide = isVertical ? 'left' : 'top'; + var opSide = isVertical ? 'bottom' : 'right'; + var arrowElementSize = getOuterSizes(arrowElement)[len]; + + // + // extends keepTogether behavior making sure the popper and its + // reference have enough pixels in conjunction + // + + // top/left side + if (reference[opSide] - arrowElementSize < popper[side]) { + data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); + } + // bottom/right side + if (reference[side] + arrowElementSize > popper[opSide]) { + data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; + } + data.offsets.popper = getClientRect(data.offsets.popper); + + // compute center of the popper + var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; + + // Compute the sideValue using the updated popper offsets + // take popper margin in account because we don't have this info available + var css = getStyleComputedProperty(data.instance.popper); + var popperMarginSide = parseFloat(css['margin' + sideCapitalized]); + var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']); + var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; + + // prevent arrowElement from being placed not contiguously to its popper + sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); + + data.arrowElement = arrowElement; + data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); + + return data; + } + + /** + * Get the opposite placement variation of the given one + * @method + * @memberof Popper.Utils + * @argument {String} placement variation + * @returns {String} flipped placement variation + */ + function getOppositeVariation(variation) { + if (variation === 'end') { + return 'start'; + } else if (variation === 'start') { + return 'end'; + } + return variation; + } + + /** + * List of accepted placements to use as values of the `placement` option.
+ * Valid placements are: + * - `auto` + * - `top` + * - `right` + * - `bottom` + * - `left` + * + * Each placement can have a variation from this list: + * - `-start` + * - `-end` + * + * Variations are interpreted easily if you think of them as the left to right + * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` + * is right.
+ * Vertically (`left` and `right`), `start` is top and `end` is bottom. + * + * Some valid examples are: + * - `top-end` (on top of reference, right aligned) + * - `right-start` (on right of reference, top aligned) + * - `bottom` (on bottom, centered) + * - `auto-end` (on the side with more space available, alignment depends by placement) + * + * @static + * @type {Array} + * @enum {String} + * @readonly + * @method placements + * @memberof Popper + */ + var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; + + // Get rid of `auto` `auto-start` and `auto-end` + var validPlacements = placements.slice(3); + + /** + * Given an initial placement, returns all the subsequent placements + * clockwise (or counter-clockwise). + * + * @method + * @memberof Popper.Utils + * @argument {String} placement - A valid placement (it accepts variations) + * @argument {Boolean} counter - Set to true to walk the placements counterclockwise + * @returns {Array} placements including their variations + */ + function clockwise(placement) { + var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var index = validPlacements.indexOf(placement); + var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); + return counter ? arr.reverse() : arr; + } + + var BEHAVIORS = { + FLIP: 'flip', + CLOCKWISE: 'clockwise', + COUNTERCLOCKWISE: 'counterclockwise' + }; + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function flip(data, options) { + // if `inner` modifier is enabled, we can't use the `flip` modifier + if (isModifierEnabled(data.instance.modifiers, 'inner')) { + return data; + } + + if (data.flipped && data.placement === data.originalPlacement) { + // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides + return data; + } + + var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); + + var placement = data.placement.split('-')[0]; + var placementOpposite = getOppositePlacement(placement); + var variation = data.placement.split('-')[1] || ''; + + var flipOrder = []; + + switch (options.behavior) { + case BEHAVIORS.FLIP: + flipOrder = [placement, placementOpposite]; + break; + case BEHAVIORS.CLOCKWISE: + flipOrder = clockwise(placement); + break; + case BEHAVIORS.COUNTERCLOCKWISE: + flipOrder = clockwise(placement, true); + break; + default: + flipOrder = options.behavior; + } + + flipOrder.forEach(function (step, index) { + if (placement !== step || flipOrder.length === index + 1) { + return data; + } + + placement = data.placement.split('-')[0]; + placementOpposite = getOppositePlacement(placement); + + var popperOffsets = data.offsets.popper; + var refOffsets = data.offsets.reference; + + // using floor because the reference offsets may contain decimals we are not going to consider here + var floor = Math.floor; + var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); + + var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); + var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); + var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); + var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); + + var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; + + // flip the variation if required + var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; + + // flips variation if reference element overflows boundaries + var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); + + // flips variation if popper content overflows boundaries + var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop); + + var flippedVariation = flippedVariationByRef || flippedVariationByContent; + + if (overlapsRef || overflowsBoundaries || flippedVariation) { + // this boolean to detect any flip loop + data.flipped = true; + + if (overlapsRef || overflowsBoundaries) { + placement = flipOrder[index + 1]; + } + + if (flippedVariation) { + variation = getOppositeVariation(variation); + } + + data.placement = placement + (variation ? '-' + variation : ''); + + // this object contains `position`, we want to preserve it along with + // any additional property we may add in the future + data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); + + data = runModifiers(data.instance.modifiers, data, 'flip'); + } + }); + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function keepTogether(data) { + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var placement = data.placement.split('-')[0]; + var floor = Math.floor; + var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; + var side = isVertical ? 'right' : 'bottom'; + var opSide = isVertical ? 'left' : 'top'; + var measurement = isVertical ? 'width' : 'height'; + + if (popper[side] < floor(reference[opSide])) { + data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; + } + if (popper[opSide] > floor(reference[side])) { + data.offsets.popper[opSide] = floor(reference[side]); + } + + return data; + } + + /** + * Converts a string containing value + unit into a px value number + * @function + * @memberof {modifiers~offset} + * @private + * @argument {String} str - Value + unit string + * @argument {String} measurement - `height` or `width` + * @argument {Object} popperOffsets + * @argument {Object} referenceOffsets + * @returns {Number|String} + * Value in pixels, or original string if no values were extracted + */ + function toValue(str, measurement, popperOffsets, referenceOffsets) { + // separate value from unit + var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); + var value = +split[1]; + var unit = split[2]; + + // If it's not a number it's an operator, I guess + if (!value) { + return str; + } + + if (unit.indexOf('%') === 0) { + var element = void 0; + switch (unit) { + case '%p': + element = popperOffsets; + break; + case '%': + case '%r': + default: + element = referenceOffsets; + } + + var rect = getClientRect(element); + return rect[measurement] / 100 * value; + } else if (unit === 'vh' || unit === 'vw') { + // if is a vh or vw, we calculate the size based on the viewport + var size = void 0; + if (unit === 'vh') { + size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); + } else { + size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); + } + return size / 100 * value; + } else { + // if is an explicit pixel unit, we get rid of the unit and keep the value + // if is an implicit unit, it's px, and we return just the value + return value; + } + } + + /** + * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. + * @function + * @memberof {modifiers~offset} + * @private + * @argument {String} offset + * @argument {Object} popperOffsets + * @argument {Object} referenceOffsets + * @argument {String} basePlacement + * @returns {Array} a two cells array with x and y offsets in numbers + */ + function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { + var offsets = [0, 0]; + + // Use height if placement is left or right and index is 0 otherwise use width + // in this way the first offset will use an axis and the second one + // will use the other one + var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; + + // Split the offset string to obtain a list of values and operands + // The regex addresses values with the plus or minus sign in front (+10, -20, etc) + var fragments = offset.split(/(\+|\-)/).map(function (frag) { + return frag.trim(); + }); + + // Detect if the offset string contains a pair of values or a single one + // they could be separated by comma or space + var divider = fragments.indexOf(find(fragments, function (frag) { + return frag.search(/,|\s/) !== -1; + })); + + if (fragments[divider] && fragments[divider].indexOf(',') === -1) { + console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); + } + + // If divider is found, we divide the list of values and operands to divide + // them by ofset X and Y. + var splitRegex = /\s*,\s*|\s+/; + var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; + + // Convert the values with units to absolute pixels to allow our computations + ops = ops.map(function (op, index) { + // Most of the units rely on the orientation of the popper + var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; + var mergeWithPrevious = false; + return op + // This aggregates any `+` or `-` sign that aren't considered operators + // e.g.: 10 + +5 => [10, +, +5] + .reduce(function (a, b) { + if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { + a[a.length - 1] = b; + mergeWithPrevious = true; + return a; + } else if (mergeWithPrevious) { + a[a.length - 1] += b; + mergeWithPrevious = false; + return a; + } else { + return a.concat(b); + } + }, []) + // Here we convert the string values into number values (in px) + .map(function (str) { + return toValue(str, measurement, popperOffsets, referenceOffsets); + }); + }); + + // Loop trough the offsets arrays and execute the operations + ops.forEach(function (op, index) { + op.forEach(function (frag, index2) { + if (isNumeric(frag)) { + offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); + } + }); + }); + return offsets; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @argument {Number|String} options.offset=0 + * The offset value as described in the modifier description + * @returns {Object} The data object, properly modified + */ + function offset(data, _ref) { + var offset = _ref.offset; + var placement = data.placement, + _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var basePlacement = placement.split('-')[0]; + + var offsets = void 0; + if (isNumeric(+offset)) { + offsets = [+offset, 0]; + } else { + offsets = parseOffset(offset, popper, reference, basePlacement); + } + + if (basePlacement === 'left') { + popper.top += offsets[0]; + popper.left -= offsets[1]; + } else if (basePlacement === 'right') { + popper.top += offsets[0]; + popper.left += offsets[1]; + } else if (basePlacement === 'top') { + popper.left += offsets[0]; + popper.top -= offsets[1]; + } else if (basePlacement === 'bottom') { + popper.left += offsets[0]; + popper.top += offsets[1]; + } + + data.popper = popper; + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function preventOverflow(data, options) { + var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); + + // If offsetParent is the reference element, we really want to + // go one step up and use the next offsetParent as reference to + // avoid to make this modifier completely useless and look like broken + if (data.instance.reference === boundariesElement) { + boundariesElement = getOffsetParent(boundariesElement); + } + + // NOTE: DOM access here + // resets the popper's position so that the document size can be calculated excluding + // the size of the popper element itself + var transformProp = getSupportedPropertyName('transform'); + var popperStyles = data.instance.popper.style; // assignment to help minification + var top = popperStyles.top, + left = popperStyles.left, + transform = popperStyles[transformProp]; + + popperStyles.top = ''; + popperStyles.left = ''; + popperStyles[transformProp] = ''; + + var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); + + // NOTE: DOM access here + // restores the original style properties after the offsets have been computed + popperStyles.top = top; + popperStyles.left = left; + popperStyles[transformProp] = transform; + + options.boundaries = boundaries; + + var order = options.priority; + var popper = data.offsets.popper; + + var check = { + primary: function primary(placement) { + var value = popper[placement]; + if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { + value = Math.max(popper[placement], boundaries[placement]); + } + return defineProperty({}, placement, value); + }, + secondary: function secondary(placement) { + var mainSide = placement === 'right' ? 'left' : 'top'; + var value = popper[mainSide]; + if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { + value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); + } + return defineProperty({}, mainSide, value); + } + }; + + order.forEach(function (placement) { + var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; + popper = _extends({}, popper, check[side](placement)); + }); + + data.offsets.popper = popper; + + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function shift(data) { + var placement = data.placement; + var basePlacement = placement.split('-')[0]; + var shiftvariation = placement.split('-')[1]; + + // if shift shiftvariation is specified, run the modifier + if (shiftvariation) { + var _data$offsets = data.offsets, + reference = _data$offsets.reference, + popper = _data$offsets.popper; + + var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; + var side = isVertical ? 'left' : 'top'; + var measurement = isVertical ? 'width' : 'height'; + + var shiftOffsets = { + start: defineProperty({}, side, reference[side]), + end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) + }; + + data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); + } + + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function hide(data) { + if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { + return data; + } + + var refRect = data.offsets.reference; + var bound = find(data.instance.modifiers, function (modifier) { + return modifier.name === 'preventOverflow'; + }).boundaries; + + if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { + // Avoid unnecessary DOM access if visibility hasn't changed + if (data.hide === true) { + return data; + } + + data.hide = true; + data.attributes['x-out-of-boundaries'] = ''; + } else { + // Avoid unnecessary DOM access if visibility hasn't changed + if (data.hide === false) { + return data; + } + + data.hide = false; + data.attributes['x-out-of-boundaries'] = false; + } + + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function inner(data) { + var placement = data.placement; + var basePlacement = placement.split('-')[0]; + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; + + var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; + + popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); + + data.placement = getOppositePlacement(placement); + data.offsets.popper = getClientRect(popper); + + return data; + } + + /** + * Modifier function, each modifier can have a function of this type assigned + * to its `fn` property.
+ * These functions will be called on each update, this means that you must + * make sure they are performant enough to avoid performance bottlenecks. + * + * @function ModifierFn + * @argument {dataObject} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {dataObject} The data object, properly modified + */ + + /** + * Modifiers are plugins used to alter the behavior of your poppers.
+ * Popper.js uses a set of 9 modifiers to provide all the basic functionalities + * needed by the library. + * + * Usually you don't want to override the `order`, `fn` and `onLoad` props. + * All the other properties are configurations that could be tweaked. + * @namespace modifiers + */ + var modifiers = { + /** + * Modifier used to shift the popper on the start or end of its reference + * element.
+ * It will read the variation of the `placement` property.
+ * It can be one either `-end` or `-start`. + * @memberof modifiers + * @inner + */ + shift: { + /** @prop {number} order=100 - Index used to define the order of execution */ + order: 100, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: shift + }, + + /** + * The `offset` modifier can shift your popper on both its axis. + * + * It accepts the following units: + * - `px` or unit-less, interpreted as pixels + * - `%` or `%r`, percentage relative to the length of the reference element + * - `%p`, percentage relative to the length of the popper element + * - `vw`, CSS viewport width unit + * - `vh`, CSS viewport height unit + * + * For length is intended the main axis relative to the placement of the popper.
+ * This means that if the placement is `top` or `bottom`, the length will be the + * `width`. In case of `left` or `right`, it will be the `height`. + * + * You can provide a single value (as `Number` or `String`), or a pair of values + * as `String` divided by a comma or one (or more) white spaces.
+ * The latter is a deprecated method because it leads to confusion and will be + * removed in v2.
+ * Additionally, it accepts additions and subtractions between different units. + * Note that multiplications and divisions aren't supported. + * + * Valid examples are: + * ``` + * 10 + * '10%' + * '10, 10' + * '10%, 10' + * '10 + 10%' + * '10 - 5vh + 3%' + * '-10px + 5vh, 5px - 6%' + * ``` + * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap + * > with their reference element, unfortunately, you will have to disable the `flip` modifier. + * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373). + * + * @memberof modifiers + * @inner + */ + offset: { + /** @prop {number} order=200 - Index used to define the order of execution */ + order: 200, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: offset, + /** @prop {Number|String} offset=0 + * The offset value as described in the modifier description + */ + offset: 0 + }, + + /** + * Modifier used to prevent the popper from being positioned outside the boundary. + * + * A scenario exists where the reference itself is not within the boundaries.
+ * We can say it has "escaped the boundaries" — or just "escaped".
+ * In this case we need to decide whether the popper should either: + * + * - detach from the reference and remain "trapped" in the boundaries, or + * - if it should ignore the boundary and "escape with its reference" + * + * When `escapeWithReference` is set to`true` and reference is completely + * outside its boundaries, the popper will overflow (or completely leave) + * the boundaries in order to remain attached to the edge of the reference. + * + * @memberof modifiers + * @inner + */ + preventOverflow: { + /** @prop {number} order=300 - Index used to define the order of execution */ + order: 300, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: preventOverflow, + /** + * @prop {Array} [priority=['left','right','top','bottom']] + * Popper will try to prevent overflow following these priorities by default, + * then, it could overflow on the left and on top of the `boundariesElement` + */ + priority: ['left', 'right', 'top', 'bottom'], + /** + * @prop {number} padding=5 + * Amount of pixel used to define a minimum distance between the boundaries + * and the popper. This makes sure the popper always has a little padding + * between the edges of its container + */ + padding: 5, + /** + * @prop {String|HTMLElement} boundariesElement='scrollParent' + * Boundaries used by the modifier. Can be `scrollParent`, `window`, + * `viewport` or any DOM element. + */ + boundariesElement: 'scrollParent' + }, + + /** + * Modifier used to make sure the reference and its popper stay near each other + * without leaving any gap between the two. Especially useful when the arrow is + * enabled and you want to ensure that it points to its reference element. + * It cares only about the first axis. You can still have poppers with margin + * between the popper and its reference element. + * @memberof modifiers + * @inner + */ + keepTogether: { + /** @prop {number} order=400 - Index used to define the order of execution */ + order: 400, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: keepTogether + }, + + /** + * This modifier is used to move the `arrowElement` of the popper to make + * sure it is positioned between the reference element and its popper element. + * It will read the outer size of the `arrowElement` node to detect how many + * pixels of conjunction are needed. + * + * It has no effect if no `arrowElement` is provided. + * @memberof modifiers + * @inner + */ + arrow: { + /** @prop {number} order=500 - Index used to define the order of execution */ + order: 500, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: arrow, + /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ + element: '[x-arrow]' + }, + + /** + * Modifier used to flip the popper's placement when it starts to overlap its + * reference element. + * + * Requires the `preventOverflow` modifier before it in order to work. + * + * **NOTE:** this modifier will interrupt the current update cycle and will + * restart it if it detects the need to flip the placement. + * @memberof modifiers + * @inner + */ + flip: { + /** @prop {number} order=600 - Index used to define the order of execution */ + order: 600, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: flip, + /** + * @prop {String|Array} behavior='flip' + * The behavior used to change the popper's placement. It can be one of + * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid + * placements (with optional variations) + */ + behavior: 'flip', + /** + * @prop {number} padding=5 + * The popper will flip if it hits the edges of the `boundariesElement` + */ + padding: 5, + /** + * @prop {String|HTMLElement} boundariesElement='viewport' + * The element which will define the boundaries of the popper position. + * The popper will never be placed outside of the defined boundaries + * (except if `keepTogether` is enabled) + */ + boundariesElement: 'viewport', + /** + * @prop {Boolean} flipVariations=false + * The popper will switch placement variation between `-start` and `-end` when + * the reference element overlaps its boundaries. + * + * The original placement should have a set variation. + */ + flipVariations: false, + /** + * @prop {Boolean} flipVariationsByContent=false + * The popper will switch placement variation between `-start` and `-end` when + * the popper element overlaps its reference boundaries. + * + * The original placement should have a set variation. + */ + flipVariationsByContent: false + }, + + /** + * Modifier used to make the popper flow toward the inner of the reference element. + * By default, when this modifier is disabled, the popper will be placed outside + * the reference element. + * @memberof modifiers + * @inner + */ + inner: { + /** @prop {number} order=700 - Index used to define the order of execution */ + order: 700, + /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ + enabled: false, + /** @prop {ModifierFn} */ + fn: inner + }, + + /** + * Modifier used to hide the popper when its reference element is outside of the + * popper boundaries. It will set a `x-out-of-boundaries` attribute which can + * be used to hide with a CSS selector the popper when its reference is + * out of boundaries. + * + * Requires the `preventOverflow` modifier before it in order to work. + * @memberof modifiers + * @inner + */ + hide: { + /** @prop {number} order=800 - Index used to define the order of execution */ + order: 800, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: hide + }, + + /** + * Computes the style that will be applied to the popper element to gets + * properly positioned. + * + * Note that this modifier will not touch the DOM, it just prepares the styles + * so that `applyStyle` modifier can apply it. This separation is useful + * in case you need to replace `applyStyle` with a custom implementation. + * + * This modifier has `850` as `order` value to maintain backward compatibility + * with previous versions of Popper.js. Expect the modifiers ordering method + * to change in future major versions of the library. + * + * @memberof modifiers + * @inner + */ + computeStyle: { + /** @prop {number} order=850 - Index used to define the order of execution */ + order: 850, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: computeStyle, + /** + * @prop {Boolean} gpuAcceleration=true + * If true, it uses the CSS 3D transformation to position the popper. + * Otherwise, it will use the `top` and `left` properties + */ + gpuAcceleration: true, + /** + * @prop {string} [x='bottom'] + * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. + * Change this if your popper should grow in a direction different from `bottom` + */ + x: 'bottom', + /** + * @prop {string} [x='left'] + * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. + * Change this if your popper should grow in a direction different from `right` + */ + y: 'right' + }, + + /** + * Applies the computed styles to the popper element. + * + * All the DOM manipulations are limited to this modifier. This is useful in case + * you want to integrate Popper.js inside a framework or view library and you + * want to delegate all the DOM manipulations to it. + * + * Note that if you disable this modifier, you must make sure the popper element + * has its position set to `absolute` before Popper.js can do its work! + * + * Just disable this modifier and define your own to achieve the desired effect. + * + * @memberof modifiers + * @inner + */ + applyStyle: { + /** @prop {number} order=900 - Index used to define the order of execution */ + order: 900, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: applyStyle, + /** @prop {Function} */ + onLoad: applyStyleOnLoad, + /** + * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier + * @prop {Boolean} gpuAcceleration=true + * If true, it uses the CSS 3D transformation to position the popper. + * Otherwise, it will use the `top` and `left` properties + */ + gpuAcceleration: undefined + } + }; + + /** + * The `dataObject` is an object containing all the information used by Popper.js. + * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks. + * @name dataObject + * @property {Object} data.instance The Popper.js instance + * @property {String} data.placement Placement applied to popper + * @property {String} data.originalPlacement Placement originally defined on init + * @property {Boolean} data.flipped True if popper has been flipped by flip modifier + * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper + * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier + * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`) + * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`) + * @property {Object} data.boundaries Offsets of the popper boundaries + * @property {Object} data.offsets The measurements of popper, reference and arrow elements + * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values + * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values + * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 + */ + + /** + * Default options provided to Popper.js constructor.
+ * These can be overridden using the `options` argument of Popper.js.
+ * To override an option, simply pass an object with the same + * structure of the `options` object, as the 3rd argument. For example: + * ``` + * new Popper(ref, pop, { + * modifiers: { + * preventOverflow: { enabled: false } + * } + * }) + * ``` + * @type {Object} + * @static + * @memberof Popper + */ + var Defaults = { + /** + * Popper's placement. + * @prop {Popper.placements} placement='bottom' + */ + placement: 'bottom', + + /** + * Set this to true if you want popper to position it self in 'fixed' mode + * @prop {Boolean} positionFixed=false + */ + positionFixed: false, + + /** + * Whether events (resize, scroll) are initially enabled. + * @prop {Boolean} eventsEnabled=true + */ + eventsEnabled: true, + + /** + * Set to true if you want to automatically remove the popper when + * you call the `destroy` method. + * @prop {Boolean} removeOnDestroy=false + */ + removeOnDestroy: false, + + /** + * Callback called when the popper is created.
+ * By default, it is set to no-op.
+ * Access Popper.js instance with `data.instance`. + * @prop {onCreate} + */ + onCreate: function onCreate() {}, + + /** + * Callback called when the popper is updated. This callback is not called + * on the initialization/creation of the popper, but only on subsequent + * updates.
+ * By default, it is set to no-op.
+ * Access Popper.js instance with `data.instance`. + * @prop {onUpdate} + */ + onUpdate: function onUpdate() {}, + + /** + * List of modifiers used to modify the offsets before they are applied to the popper. + * They provide most of the functionalities of Popper.js. + * @prop {modifiers} + */ + modifiers: modifiers + }; + + /** + * @callback onCreate + * @param {dataObject} data + */ + + /** + * @callback onUpdate + * @param {dataObject} data + */ + + // Utils + // Methods + var Popper = function () { + /** + * Creates a new Popper.js instance. + * @class Popper + * @param {Element|referenceObject} reference - The reference element used to position the popper + * @param {Element} popper - The HTML / XML element used as the popper + * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) + * @return {Object} instance - The generated Popper.js instance + */ + function Popper(reference, popper) { + var _this = this; + + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + classCallCheck(this, Popper); + + this.scheduleUpdate = function () { + return requestAnimationFrame(_this.update); + }; + + // make update() debounced, so that it only runs at most once-per-tick + this.update = debounce(this.update.bind(this)); + + // with {} we create a new object with the options inside it + this.options = _extends({}, Popper.Defaults, options); + + // init state + this.state = { + isDestroyed: false, + isCreated: false, + scrollParents: [] + }; + + // get reference and popper elements (allow jQuery wrappers) + this.reference = reference && reference.jquery ? reference[0] : reference; + this.popper = popper && popper.jquery ? popper[0] : popper; + + // Deep merge modifiers options + this.options.modifiers = {}; + Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { + _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); + }); + + // Refactoring modifiers' list (Object => Array) + this.modifiers = Object.keys(this.options.modifiers).map(function (name) { + return _extends({ + name: name + }, _this.options.modifiers[name]); + }) + // sort the modifiers by order + .sort(function (a, b) { + return a.order - b.order; + }); + + // modifiers have the ability to execute arbitrary code when Popper.js get inited + // such code is executed in the same order of its modifier + // they could add new properties to their options configuration + // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! + this.modifiers.forEach(function (modifierOptions) { + if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { + modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); + } + }); + + // fire the first update to position the popper in the right place + this.update(); + + var eventsEnabled = this.options.eventsEnabled; + if (eventsEnabled) { + // setup event listeners, they will take care of update the position in specific situations + this.enableEventListeners(); + } + + this.state.eventsEnabled = eventsEnabled; + } + + // We can't use class properties because they don't get listed in the + // class prototype and break stuff like Sinon stubs + + + createClass(Popper, [{ + key: 'update', + value: function update$$1() { + return update.call(this); + } + }, { + key: 'destroy', + value: function destroy$$1() { + return destroy.call(this); + } + }, { + key: 'enableEventListeners', + value: function enableEventListeners$$1() { + return enableEventListeners.call(this); + } + }, { + key: 'disableEventListeners', + value: function disableEventListeners$$1() { + return disableEventListeners.call(this); + } + + /** + * Schedules an update. It will run on the next UI update available. + * @method scheduleUpdate + * @memberof Popper + */ + + + /** + * Collection of utilities useful when writing custom modifiers. + * Starting from version 1.7, this method is available only if you + * include `popper-utils.js` before `popper.js`. + * + * **DEPRECATION**: This way to access PopperUtils is deprecated + * and will be removed in v2! Use the PopperUtils module directly instead. + * Due to the high instability of the methods contained in Utils, we can't + * guarantee them to follow semver. Use them at your own risk! + * @static + * @private + * @type {Object} + * @deprecated since version 1.8 + * @member Utils + * @memberof Popper + */ + + }]); + return Popper; + }(); + + /** + * The `referenceObject` is an object that provides an interface compatible with Popper.js + * and lets you use it as replacement of a real DOM node.
+ * You can use this method to position a popper relatively to a set of coordinates + * in case you don't have a DOM node to use as reference. + * + * ``` + * new Popper(referenceObject, popperNode); + * ``` + * + * NB: This feature isn't supported in Internet Explorer 10. + * @name referenceObject + * @property {Function} data.getBoundingClientRect + * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. + * @property {number} data.clientWidth + * An ES6 getter that will return the width of the virtual reference element. + * @property {number} data.clientHeight + * An ES6 getter that will return the height of the virtual reference element. + */ + + + Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; + Popper.placements = placements; + Popper.Defaults = Defaults; + + var PLACEMENT_TOP_START = 'top-start'; + var PLACEMENT_TOP_END = 'top-end'; + var PLACEMENT_BOTTOM_START = 'bottom-start'; + var PLACEMENT_BOTTOM_END = 'bottom-end'; + var PLACEMENT_RIGHT_START = 'right-start'; + var PLACEMENT_LEFT_START = 'left-start'; + + var BvEvent = /*#__PURE__*/function () { + function BvEvent(type) { + var eventInit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, BvEvent); + + // Start by emulating native Event constructor + if (!type) { + /* istanbul ignore next */ + throw new TypeError("Failed to construct '".concat(this.constructor.name, "'. 1 argument required, ").concat(arguments.length, " given.")); + } // Merge defaults first, the eventInit, and the type last + // so it can't be overwritten + + + assign(this, BvEvent.Defaults, this.constructor.Defaults, eventInit, { + type: type + }); // Freeze some props as readonly, but leave them enumerable + + defineProperties(this, { + type: readonlyDescriptor(), + cancelable: readonlyDescriptor(), + nativeEvent: readonlyDescriptor(), + target: readonlyDescriptor(), + relatedTarget: readonlyDescriptor(), + vueTarget: readonlyDescriptor(), + componentId: readonlyDescriptor() + }); // Create a private variable using closure scoping + + var defaultPrevented = false; // Recreate preventDefault method. One way setter + + this.preventDefault = function preventDefault() { + if (this.cancelable) { + defaultPrevented = true; + } + }; // Create `defaultPrevented` publicly accessible prop that + // can only be altered by the preventDefault method + + + defineProperty$1(this, 'defaultPrevented', { + enumerable: true, + get: function get() { + return defaultPrevented; + } + }); + } + + _createClass(BvEvent, null, [{ + key: "Defaults", + get: function get() { + return { + type: '', + cancelable: true, + nativeEvent: null, + target: null, + relatedTarget: null, + vueTarget: null, + componentId: null + }; + } + }]); + + return BvEvent; + }(); + + var clickOutMixin = extend({ + data: function data() { + return { + listenForClickOut: false + }; + }, + watch: { + listenForClickOut: function listenForClickOut(newValue, oldValue) { + if (newValue !== oldValue) { + eventOff(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); + + if (newValue) { + eventOn(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); + } + } + } + }, + beforeCreate: function beforeCreate() { + // Declare non-reactive properties + this.clickOutElement = null; + this.clickOutEventName = null; + }, + mounted: function mounted() { + if (!this.clickOutElement) { + this.clickOutElement = document; + } + + if (!this.clickOutEventName) { + this.clickOutEventName = 'click'; + } + + if (this.listenForClickOut) { + eventOn(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); + } + }, + beforeDestroy: function beforeDestroy() { + eventOff(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); + }, + methods: { + isClickOut: function isClickOut(event) { + return !contains(this.$el, event.target); + }, + _clickOutHandler: function _clickOutHandler(event) { + if (this.clickOutHandler && this.isClickOut(event)) { + this.clickOutHandler(event); + } + } + } + }); + + var focusInMixin = extend({ + data: function data() { + return { + listenForFocusIn: false + }; + }, + watch: { + listenForFocusIn: function listenForFocusIn(newValue, oldValue) { + if (newValue !== oldValue) { + eventOff(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); + + if (newValue) { + eventOn(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); + } + } + } + }, + beforeCreate: function beforeCreate() { + // Declare non-reactive properties + this.focusInElement = null; + }, + mounted: function mounted() { + if (!this.focusInElement) { + this.focusInElement = document; + } + + if (this.listenForFocusIn) { + eventOn(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); + } + }, + beforeDestroy: function beforeDestroy() { + eventOff(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); + }, + methods: { + _focusInHandler: function _focusInHandler(event) { + if (this.focusInHandler) { + this.focusInHandler(event); + } + } + } + }); + + var registry = null; + + if (isVue3) { + registry = new WeakMap(); + } + + var registerElementToInstance = function registerElementToInstance(element, instance) { + if (!isVue3) { + return; + } + + registry.set(element, instance); + }; + var removeElementToInstance = function removeElementToInstance(element) { + if (!isVue3) { + return; + } + + registry.delete(element); + }; + var getInstanceFromElement = function getInstanceFromElement(element) { + if (!isVue3) { + return element.__vue__; + } + + var currentElement = element; + + while (currentElement) { + if (registry.has(currentElement)) { + /* istanbul ignore next */ + return registry.get(currentElement); + } + + currentElement = currentElement.parentNode; + } + + return null; + }; + + var ROOT_EVENT_NAME_SHOWN = getRootEventName(NAME_DROPDOWN, EVENT_NAME_SHOWN); + var ROOT_EVENT_NAME_HIDDEN = getRootEventName(NAME_DROPDOWN, EVENT_NAME_HIDDEN); // CSS selectors + + var SELECTOR_FORM_CHILD = '.dropdown form'; + var SELECTOR_ITEM = ['.dropdown-item', '.b-dropdown-form'].map(function (selector) { + return "".concat(selector, ":not(.disabled):not([disabled])"); + }).join(', '); // --- Helper methods --- + // Return an array of visible items + + var filterVisibles = function filterVisibles(els) { + return (els || []).filter(isVisible); + }; // --- Props --- + + + var props$1O = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, props$25), {}, { + // String: `scrollParent`, `window` or `viewport` + // HTMLElement: HTML Element reference + boundary: makeProp([HTMLElement, PROP_TYPE_STRING], 'scrollParent'), + disabled: makeProp(PROP_TYPE_BOOLEAN, false), + // Place left if possible + dropleft: makeProp(PROP_TYPE_BOOLEAN, false), + // Place right if possible + dropright: makeProp(PROP_TYPE_BOOLEAN, false), + // Place on top if possible + dropup: makeProp(PROP_TYPE_BOOLEAN, false), + // Disable auto-flipping of menu from bottom <=> top + noFlip: makeProp(PROP_TYPE_BOOLEAN, false), + // Number of pixels or a CSS unit value to offset menu + // (i.e. `1px`, `1rem`, etc.) + offset: makeProp(PROP_TYPE_NUMBER_STRING, 0), + popperOpts: makeProp(PROP_TYPE_OBJECT, {}), + // Right align menu (default is left align) + right: makeProp(PROP_TYPE_BOOLEAN, false) + })), NAME_DROPDOWN); // --- Mixin --- + // @vue/component + + var dropdownMixin = extend({ + mixins: [idMixin, listenOnRootMixin, clickOutMixin, focusInMixin], + provide: function provide() { + var _this = this; + + return { + getBvDropdown: function getBvDropdown() { + return _this; + } + }; + }, + inject: { + getBvNavbar: { + default: function _default() { + return function () { + return null; + }; + } + } + }, + props: props$1O, + data: function data() { + return { + visible: false, + visibleChangePrevented: false + }; + }, + computed: { + bvNavbar: function bvNavbar() { + return this.getBvNavbar(); + }, + inNavbar: function inNavbar() { + return !isNull(this.bvNavbar); + }, + toggler: function toggler() { + var toggle = this.$refs.toggle; + return toggle ? toggle.$el || toggle : null; + }, + directionClass: function directionClass() { + if (this.dropup) { + return 'dropup'; + } else if (this.dropright) { + return 'dropright'; + } else if (this.dropleft) { + return 'dropleft'; + } + + return ''; + }, + boundaryClass: function boundaryClass() { + // Position `static` is needed to allow menu to "breakout" of the `scrollParent` + // boundaries when boundary is anything other than `scrollParent` + // See: https://github.com/twbs/bootstrap/issues/24251#issuecomment-341413786 + return this.boundary !== 'scrollParent' && !this.inNavbar ? 'position-static' : ''; + }, + hideDelay: function hideDelay() { + return this.inNavbar ? HAS_TOUCH_SUPPORT ? 300 : 50 : 0; + } + }, + watch: { + visible: function visible(newValue, oldValue) { + if (this.visibleChangePrevented) { + this.visibleChangePrevented = false; + return; + } + + if (newValue !== oldValue) { + var eventName = newValue ? EVENT_NAME_SHOW : EVENT_NAME_HIDE; + var bvEvent = new BvEvent(eventName, { + cancelable: true, + vueTarget: this, + target: this.$refs.menu, + relatedTarget: null, + componentId: this.safeId ? this.safeId() : this.id || null + }); + this.emitEvent(bvEvent); + + if (bvEvent.defaultPrevented) { + // Reset value and exit if canceled + this.visibleChangePrevented = true; + this.visible = oldValue; // Just in case a child element triggered `this.hide(true)` + + this.$off(EVENT_NAME_HIDDEN, this.focusToggler); + return; + } + + if (newValue) { + this.showMenu(); + } else { + this.hideMenu(); + } + } + }, + disabled: function disabled(newValue, oldValue) { + if (newValue !== oldValue && newValue && this.visible) { + // Hide dropdown if disabled changes to true + this.visible = false; + } + } + }, + created: function created() { + // Create private non-reactive props + this.$_popper = null; + this.$_hideTimeout = null; + }, + + /* istanbul ignore next */ + deactivated: function deactivated() { + // In case we are inside a `` + this.visible = false; + this.whileOpenListen(false); + this.destroyPopper(); + }, + mounted: function mounted() { + registerElementToInstance(this.$el, this); + }, + beforeDestroy: function beforeDestroy() { + this.visible = false; + this.whileOpenListen(false); + this.destroyPopper(); + this.clearHideTimeout(); + removeElementToInstance(this.$el); + }, + methods: { + // Event emitter + emitEvent: function emitEvent(bvEvent) { + var type = bvEvent.type; + this.emitOnRoot(getRootEventName(NAME_DROPDOWN, type), bvEvent); + this.$emit(type, bvEvent); + }, + showMenu: function showMenu() { + var _this2 = this; + + if (this.disabled) { + /* istanbul ignore next */ + return; + } // Only instantiate Popper.js when dropdown is not in `` + + + if (!this.inNavbar) { + if (typeof Popper === 'undefined') { + /* istanbul ignore next */ + warn('Popper.js not found. Falling back to CSS positioning', NAME_DROPDOWN); + } else { + // For dropup with alignment we use the parent element as popper container + var el = this.dropup && this.right || this.split ? this.$el : this.$refs.toggle; // Make sure we have a reference to an element, not a component! + + el = el.$el || el; // Instantiate Popper.js + + this.createPopper(el); + } + } // Ensure other menus are closed + + + this.emitOnRoot(ROOT_EVENT_NAME_SHOWN, this); // Enable listeners + + this.whileOpenListen(true); // Wrap in `$nextTick()` to ensure menu is fully rendered/shown + + this.$nextTick(function () { + // Focus on the menu container on show + _this2.focusMenu(); // Emit the shown event + + + _this2.$emit(EVENT_NAME_SHOWN); + }); + }, + hideMenu: function hideMenu() { + this.whileOpenListen(false); + this.emitOnRoot(ROOT_EVENT_NAME_HIDDEN, this); + this.$emit(EVENT_NAME_HIDDEN); + this.destroyPopper(); + }, + createPopper: function createPopper(element) { + this.destroyPopper(); + this.$_popper = new Popper(element, this.$refs.menu, this.getPopperConfig()); + }, + // Ensure popper event listeners are removed cleanly + destroyPopper: function destroyPopper() { + this.$_popper && this.$_popper.destroy(); + this.$_popper = null; + }, + // Instructs popper to re-computes the dropdown position + // useful if the content changes size + updatePopper: function updatePopper() { + try { + this.$_popper.scheduleUpdate(); + } catch (_unused) {} + }, + clearHideTimeout: function clearHideTimeout() { + clearTimeout(this.$_hideTimeout); + this.$_hideTimeout = null; + }, + getPopperConfig: function getPopperConfig() { + var placement = PLACEMENT_BOTTOM_START; + + if (this.dropup) { + placement = this.right ? PLACEMENT_TOP_END : PLACEMENT_TOP_START; + } else if (this.dropright) { + placement = PLACEMENT_RIGHT_START; + } else if (this.dropleft) { + placement = PLACEMENT_LEFT_START; + } else if (this.right) { + placement = PLACEMENT_BOTTOM_END; + } + + var popperConfig = { + placement: placement, + modifiers: { + offset: { + offset: this.offset || 0 + }, + flip: { + enabled: !this.noFlip + } + } + }; + var boundariesElement = this.boundary; + + if (boundariesElement) { + popperConfig.modifiers.preventOverflow = { + boundariesElement: boundariesElement + }; + } + + return mergeDeep(popperConfig, this.popperOpts || {}); + }, + // Turn listeners on/off while open + whileOpenListen: function whileOpenListen(isOpen) { + // Hide the dropdown when clicked outside + this.listenForClickOut = isOpen; // Hide the dropdown when it loses focus + + this.listenForFocusIn = isOpen; // Hide the dropdown when another dropdown is opened + + var method = isOpen ? 'listenOnRoot' : 'listenOffRoot'; + this[method](ROOT_EVENT_NAME_SHOWN, this.rootCloseListener); + }, + rootCloseListener: function rootCloseListener(vm) { + if (vm !== this) { + this.visible = false; + } + }, + // Public method to show dropdown + show: function show() { + var _this3 = this; + + if (this.disabled) { + return; + } // Wrap in a `requestAF()` to allow any previous + // click handling to occur first + + + requestAF(function () { + _this3.visible = true; + }); + }, + // Public method to hide dropdown + hide: function hide() { + var refocus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + /* istanbul ignore next */ + if (this.disabled) { + return; + } + + this.visible = false; + + if (refocus) { + // Child element is closing the dropdown on click + this.$once(EVENT_NAME_HIDDEN, this.focusToggler); + } + }, + // Called only by a button that toggles the menu + toggle: function toggle(event) { + event = event || {}; // Early exit when not a click event or ENTER, SPACE or DOWN were pressed + + var _event = event, + type = _event.type, + keyCode = _event.keyCode; + + if (type !== 'click' && !(type === 'keydown' && [CODE_ENTER, CODE_SPACE, CODE_DOWN].indexOf(keyCode) !== -1)) { + /* istanbul ignore next */ + return; + } + /* istanbul ignore next */ + + + if (this.disabled) { + this.visible = false; + return; + } + + this.$emit(EVENT_NAME_TOGGLE, event); + stopEvent(event); // Toggle visibility + + if (this.visible) { + this.hide(true); + } else { + this.show(); + } + }, + // Mousedown handler for the toggle + + /* istanbul ignore next */ + onMousedown: function onMousedown(event) { + // We prevent the 'mousedown' event for the toggle to stop the + // 'focusin' event from being fired + // The event would otherwise be picked up by the global 'focusin' + // listener and there is no cross-browser solution to detect it + // relates to the toggle click + // The 'click' event will still be fired and we handle closing + // other dropdowns there too + // See https://github.com/bootstrap-vue/bootstrap-vue/issues/4328 + stopEvent(event, { + propagation: false + }); + }, + // Called from dropdown menu context + onKeydown: function onKeydown(event) { + var keyCode = event.keyCode; + + if (keyCode === CODE_ESC) { + // Close on ESC + this.onEsc(event); + } else if (keyCode === CODE_DOWN) { + // Down Arrow + this.focusNext(event, false); + } else if (keyCode === CODE_UP) { + // Up Arrow + this.focusNext(event, true); + } + }, + // If user presses ESC, close the menu + onEsc: function onEsc(event) { + if (this.visible) { + this.visible = false; + stopEvent(event); // Return focus to original trigger button + + this.$once(EVENT_NAME_HIDDEN, this.focusToggler); + } + }, + // Called only in split button mode, for the split button + onSplitClick: function onSplitClick(event) { + /* istanbul ignore next */ + if (this.disabled) { + this.visible = false; + return; + } + + this.$emit(EVENT_NAME_CLICK, event); + }, + // Shared hide handler between click-out and focus-in events + hideHandler: function hideHandler(event) { + var _this4 = this; + + var target = event.target; + + if (this.visible && !contains(this.$refs.menu, target) && !contains(this.toggler, target)) { + this.clearHideTimeout(); + this.$_hideTimeout = setTimeout(function () { + return _this4.hide(); + }, this.hideDelay); + } + }, + // Document click-out listener + clickOutHandler: function clickOutHandler(event) { + this.hideHandler(event); + }, + // Document focus-in listener + focusInHandler: function focusInHandler(event) { + this.hideHandler(event); + }, + // Keyboard nav + focusNext: function focusNext(event, up) { + var _this5 = this; + + // Ignore key up/down on form elements + var target = event.target; + + if (!this.visible || event && closest(SELECTOR_FORM_CHILD, target)) { + /* istanbul ignore next: should never happen */ + return; + } + + stopEvent(event); + this.$nextTick(function () { + var items = _this5.getItems(); + + if (items.length < 1) { + /* istanbul ignore next: should never happen */ + return; + } + + var index = items.indexOf(target); + + if (up && index > 0) { + index--; + } else if (!up && index < items.length - 1) { + index++; + } + + if (index < 0) { + /* istanbul ignore next: should never happen */ + index = 0; + } + + _this5.focusItem(index, items); + }); + }, + focusItem: function focusItem(index, items) { + var el = items.find(function (el, i) { + return i === index; + }); + attemptFocus(el); + }, + getItems: function getItems() { + // Get all items + return filterVisibles(selectAll(SELECTOR_ITEM, this.$refs.menu)); + }, + focusMenu: function focusMenu() { + attemptFocus(this.$refs.menu); + }, + focusToggler: function focusToggler() { + var _this6 = this; + + this.$nextTick(function () { + attemptFocus(_this6.toggler); + }); + } + } + }); + + var props$1N = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3(_objectSpread2$3({}, props$25), props$1O), {}, { + block: makeProp(PROP_TYPE_BOOLEAN, false), + html: makeProp(PROP_TYPE_STRING), + // If `true`, only render menu contents when open + lazy: makeProp(PROP_TYPE_BOOLEAN, false), + menuClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), + noCaret: makeProp(PROP_TYPE_BOOLEAN, false), + role: makeProp(PROP_TYPE_STRING, 'menu'), + size: makeProp(PROP_TYPE_STRING), + split: makeProp(PROP_TYPE_BOOLEAN, false), + splitButtonType: makeProp(PROP_TYPE_STRING, 'button', function (value) { + return arrayIncludes(['button', 'submit', 'reset'], value); + }), + splitClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), + splitHref: makeProp(PROP_TYPE_STRING), + splitTo: makeProp(PROP_TYPE_OBJECT_STRING), + splitVariant: makeProp(PROP_TYPE_STRING), + text: makeProp(PROP_TYPE_STRING), + toggleAttrs: makeProp(PROP_TYPE_OBJECT, {}), + toggleClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), + toggleTag: makeProp(PROP_TYPE_STRING, 'button'), + // TODO: This really should be `toggleLabel` + toggleText: makeProp(PROP_TYPE_STRING, 'Toggle dropdown'), + variant: makeProp(PROP_TYPE_STRING, 'secondary') + })), NAME_DROPDOWN); // --- Main component --- + // @vue/component + + var BDropdown = /*#__PURE__*/extend({ + name: NAME_DROPDOWN, + mixins: [idMixin, dropdownMixin, normalizeSlotMixin], + props: props$1N, + computed: { + dropdownClasses: function dropdownClasses() { + var block = this.block, + split = this.split; + return [this.directionClass, this.boundaryClass, { + show: this.visible, + // The 'btn-group' class is required in `split` mode for button alignment + // It needs also to be applied when `block` is disabled to allow multiple + // dropdowns to be aligned one line + 'btn-group': split || !block, + // When `block` is enabled and we are in `split` mode the 'd-flex' class + // needs to be applied to allow the buttons to stretch to full width + 'd-flex': block && split + }]; + }, + menuClasses: function menuClasses() { + return [this.menuClass, { + 'dropdown-menu-right': this.right, + show: this.visible + }]; + }, + toggleClasses: function toggleClasses() { + var split = this.split; + return [this.toggleClass, { + 'dropdown-toggle-split': split, + 'dropdown-toggle-no-caret': this.noCaret && !split + }]; + } + }, + render: function render(h) { + var visible = this.visible, + variant = this.variant, + size = this.size, + block = this.block, + disabled = this.disabled, + split = this.split, + role = this.role, + hide = this.hide, + toggle = this.toggle; + var commonProps = { + variant: variant, + size: size, + block: block, + disabled: disabled + }; + var $buttonChildren = this.normalizeSlot(SLOT_NAME_BUTTON_CONTENT); + var buttonContentDomProps = this.hasNormalizedSlot(SLOT_NAME_BUTTON_CONTENT) ? {} : htmlOrText(this.html, this.text); + var $split = h(); + + if (split) { + var splitTo = this.splitTo, + splitHref = this.splitHref, + splitButtonType = this.splitButtonType; + + var btnProps = _objectSpread2$3(_objectSpread2$3({}, commonProps), {}, { + variant: this.splitVariant || variant + }); // We add these as needed due to issues with + // defined property with `undefined`/`null` values + + + if (splitTo) { + btnProps.to = splitTo; + } else if (splitHref) { + btnProps.href = splitHref; + } else if (splitButtonType) { + btnProps.type = splitButtonType; + } + + $split = h(BButton, { + class: this.splitClass, + attrs: { + id: this.safeId('_BV_button_') + }, + props: btnProps, + domProps: buttonContentDomProps, + on: { + click: this.onSplitClick + }, + ref: 'button' + }, $buttonChildren); // Overwrite button content for the toggle when in `split` mode + + $buttonChildren = [h('span', { + class: ['sr-only'] + }, [this.toggleText])]; + buttonContentDomProps = {}; + } + + var ariaHasPopupRoles = ['menu', 'listbox', 'tree', 'grid', 'dialog']; + var $toggle = h(BButton, { + staticClass: 'dropdown-toggle', + class: this.toggleClasses, + attrs: _objectSpread2$3(_objectSpread2$3({}, this.toggleAttrs), {}, { + // Must have attributes + id: this.safeId('_BV_toggle_'), + 'aria-haspopup': ariaHasPopupRoles.includes(role) ? role : 'false', + 'aria-expanded': toString(visible) + }), + props: _objectSpread2$3(_objectSpread2$3({}, commonProps), {}, { + tag: this.toggleTag, + block: block && !split + }), + domProps: buttonContentDomProps, + on: { + mousedown: this.onMousedown, + click: toggle, + keydown: toggle // Handle ENTER, SPACE and DOWN + + }, + ref: 'toggle' + }, $buttonChildren); + var $menu = h('ul', { + staticClass: 'dropdown-menu', + class: this.menuClasses, + attrs: { + role: role, + tabindex: '-1', + 'aria-labelledby': this.safeId(split ? '_BV_button_' : '_BV_toggle_') + }, + on: { + keydown: this.onKeydown // Handle UP, DOWN and ESC + + }, + ref: 'menu' + }, [!this.lazy || visible ? this.normalizeSlot(SLOT_NAME_DEFAULT, { + hide: hide + }) : h()]); + return h('div', { + staticClass: 'dropdown b-dropdown', + class: this.dropdownClasses, + attrs: { + id: this.safeId() + } + }, [$split, $toggle, $menu]); + } + }); + + var linkProps$4 = omit(props$2f, ['event', 'routerTag']); + var props$1M = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, linkProps$4), {}, { + linkClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), + variant: makeProp(PROP_TYPE_STRING) + })), NAME_DROPDOWN_ITEM); // --- Main component --- + // @vue/component + + var BDropdownItem = /*#__PURE__*/extend({ + name: NAME_DROPDOWN_ITEM, + mixins: [attrsMixin, normalizeSlotMixin], + inject: { + getBvDropdown: { + default: function _default() { + return function () { + return null; + }; + } + } + }, + inheritAttrs: false, + props: props$1M, + computed: { + bvDropdown: function bvDropdown() { + return this.getBvDropdown(); + }, + computedAttrs: function computedAttrs() { + return _objectSpread2$3(_objectSpread2$3({}, this.bvAttrs), {}, { + role: 'menuitem' + }); + } + }, + methods: { + closeDropdown: function closeDropdown() { + var _this = this; + + // Close on next animation frame to allow time to process + requestAF(function () { + if (_this.bvDropdown) { + _this.bvDropdown.hide(true); + } + }); + }, + onClick: function onClick(event) { + this.$emit(EVENT_NAME_CLICK, event); + this.closeDropdown(); + } + }, + render: function render(h) { + var linkClass = this.linkClass, + variant = this.variant, + active = this.active, + disabled = this.disabled, + onClick = this.onClick, + bvAttrs = this.bvAttrs; + return h('li', { + class: bvAttrs.class, + style: bvAttrs.style, + attrs: { + role: 'presentation' + } + }, [h(BLink, { + staticClass: 'dropdown-item', + class: [linkClass, _defineProperty({}, "text-".concat(variant), variant && !(active || disabled))], + props: pluckProps(linkProps$4, this.$props), + attrs: this.computedAttrs, + on: { + click: onClick + }, + ref: 'item' + }, this.normalizeSlot())]); + } + }); + + var props$1L = makePropsConfigurable({ + active: makeProp(PROP_TYPE_BOOLEAN, false), + activeClass: makeProp(PROP_TYPE_STRING, 'active'), + buttonClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), + disabled: makeProp(PROP_TYPE_BOOLEAN, false), + variant: makeProp(PROP_TYPE_STRING) + }, NAME_DROPDOWN_ITEM_BUTTON); // --- Main component --- + // @vue/component + + var BDropdownItemButton = /*#__PURE__*/extend({ + name: NAME_DROPDOWN_ITEM_BUTTON, + mixins: [attrsMixin, normalizeSlotMixin], + inject: { + getBvDropdown: { + default: function _default() { + return function () { + return null; + }; + } + } + }, + inheritAttrs: false, + props: props$1L, + computed: { + bvDropdown: function bvDropdown() { + return this.getBvDropdown(); + }, + computedAttrs: function computedAttrs() { + return _objectSpread2$3(_objectSpread2$3({}, this.bvAttrs), {}, { + role: 'menuitem', + type: 'button', + disabled: this.disabled + }); + } + }, + methods: { + closeDropdown: function closeDropdown() { + if (this.bvDropdown) { + this.bvDropdown.hide(true); + } + }, + onClick: function onClick(event) { + this.$emit(EVENT_NAME_CLICK, event); + this.closeDropdown(); + } + }, + render: function render(h) { + var _ref; + + var active = this.active, + variant = this.variant, + bvAttrs = this.bvAttrs; + return h('li', { + class: bvAttrs.class, + style: bvAttrs.style, + attrs: { + role: 'presentation' + } + }, [h('button', { + staticClass: 'dropdown-item', + class: [this.buttonClass, (_ref = {}, _defineProperty(_ref, this.activeClass, active), _defineProperty(_ref, "text-".concat(variant), variant && !(active || this.disabled)), _ref)], + attrs: this.computedAttrs, + on: { + click: this.onClick + }, + ref: 'button' + }, this.normalizeSlot())]); + } + }); + + var props$1K = makePropsConfigurable({ + id: makeProp(PROP_TYPE_STRING), + tag: makeProp(PROP_TYPE_STRING, 'header'), + variant: makeProp(PROP_TYPE_STRING) + }, NAME_DROPDOWN_HEADER); // --- Main component --- + // @vue/component + + var BDropdownHeader = /*#__PURE__*/extend({ + name: NAME_DROPDOWN_HEADER, + functional: true, + props: props$1K, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + var tag = props.tag, + variant = props.variant; + return h('li', a(omit(data, ['attrs']), { + attrs: { + role: 'presentation' + } + }), [h(tag, { + staticClass: 'dropdown-header', + class: _defineProperty({}, "text-".concat(variant), variant), + attrs: _objectSpread2$3(_objectSpread2$3({}, data.attrs || {}), {}, { + id: props.id || null, + role: isTag(tag, 'header') ? null : 'heading' + }), + ref: 'header' + }, children)]); + } + }); + + var props$1J = makePropsConfigurable({ + tag: makeProp(PROP_TYPE_STRING, 'hr') + }, NAME_DROPDOWN_DIVIDER); // --- Main component --- + // @vue/component + + var BDropdownDivider = /*#__PURE__*/extend({ + name: NAME_DROPDOWN_DIVIDER, + functional: true, + props: props$1J, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data; + return h('li', a(omit(data, ['attrs']), { + attrs: { + role: 'presentation' + } + }), [h(props.tag, { + staticClass: 'dropdown-divider', + attrs: _objectSpread2$3(_objectSpread2$3({}, data.attrs || {}), {}, { + role: 'separator', + 'aria-orientation': 'horizontal' + }), + ref: 'divider' + })]); + } + }); + + var props$1I = makePropsConfigurable({ + id: makeProp(PROP_TYPE_STRING), + inline: makeProp(PROP_TYPE_BOOLEAN, false), + novalidate: makeProp(PROP_TYPE_BOOLEAN, false), + validated: makeProp(PROP_TYPE_BOOLEAN, false) + }, NAME_FORM); // --- Main component --- + // @vue/component + + var BForm = /*#__PURE__*/extend({ + name: NAME_FORM, + functional: true, + props: props$1I, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + return h('form', a(data, { + class: { + 'form-inline': props.inline, + 'was-validated': props.validated + }, + attrs: { + id: props.id, + novalidate: props.novalidate + } + }), children); + } + }); + + var props$1H = makePropsConfigurable(sortKeys(_objectSpread2$3(_objectSpread2$3({}, props$1I), {}, { + disabled: makeProp(PROP_TYPE_BOOLEAN, false), + formClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING) + })), NAME_DROPDOWN_FORM); // --- Main component --- + // @vue/component + + var BDropdownForm = /*#__PURE__*/extend({ + name: NAME_DROPDOWN_FORM, + functional: true, + props: props$1H, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + listeners = _ref.listeners, + children = _ref.children; + return h('li', a(omit(data, ['attrs', 'on']), { + attrs: { + role: 'presentation' + } + }), [h(BForm, { + staticClass: 'b-dropdown-form', + class: [props.formClass, { + disabled: props.disabled + }], + props: props, + attrs: _objectSpread2$3(_objectSpread2$3({}, data.attrs || {}), {}, { + disabled: props.disabled, + // Tab index of -1 for keyboard navigation + tabindex: props.disabled ? null : '-1' + }), + on: listeners, + ref: 'form' + }, children)]); + } + }); + + var props$1G = makePropsConfigurable({ + tag: makeProp(PROP_TYPE_STRING, 'p'), + textClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), + variant: makeProp(PROP_TYPE_STRING) + }, NAME_DROPDOWN_TEXT); // --- Main component --- + // @vue/component + + var BDropdownText = /*#__PURE__*/extend({ + name: NAME_DROPDOWN_TEXT, + functional: true, + props: props$1G, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + var tag = props.tag, + textClass = props.textClass, + variant = props.variant; + return h('li', a(omit(data, ['attrs']), { + attrs: { + role: 'presentation' + } + }), [h(tag, { + staticClass: 'b-dropdown-text', + class: [textClass, _defineProperty({}, "text-".concat(variant), variant)], + props: props, + attrs: data.attrs || {}, + ref: 'text' + }, children)]); + } + }); + + var props$1F = makePropsConfigurable({ + ariaDescribedby: makeProp(PROP_TYPE_STRING), + header: makeProp(PROP_TYPE_STRING), + headerClasses: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING), + headerTag: makeProp(PROP_TYPE_STRING, 'header'), + headerVariant: makeProp(PROP_TYPE_STRING), + id: makeProp(PROP_TYPE_STRING) + }, NAME_DROPDOWN_GROUP); // --- Main component --- + // @vue/component + + var BDropdownGroup = /*#__PURE__*/extend({ + name: NAME_DROPDOWN_GROUP, + functional: true, + props: props$1F, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + slots = _ref.slots, + scopedSlots = _ref.scopedSlots; + var id = props.id, + variant = props.variant, + header = props.header, + headerTag = props.headerTag; + var $slots = slots(); + var $scopedSlots = scopedSlots || {}; + var slotScope = {}; + var headerId = id ? "_bv_".concat(id, "_group_dd_header") : null; + var $header = h(); + + if (hasNormalizedSlot(SLOT_NAME_HEADER, $scopedSlots, $slots) || header) { + $header = h(headerTag, { + staticClass: 'dropdown-header', + class: [props.headerClasses, _defineProperty({}, "text-".concat(variant), variant)], + attrs: { + id: headerId, + role: isTag(headerTag, 'header') ? null : 'heading' + } + }, normalizeSlot(SLOT_NAME_HEADER, slotScope, $scopedSlots, $slots) || header); + } + + return h('li', a(omit(data, ['attrs']), { + attrs: { + role: 'presentation' + } + }), [$header, h('ul', { + staticClass: 'list-unstyled', + attrs: _objectSpread2$3(_objectSpread2$3({}, data.attrs || {}), {}, { + id: id, + role: 'group', + 'aria-describedby': [headerId, props.ariaDescribedBy].filter(identity).join(' ').trim() || null + }) + }, normalizeSlot(SLOT_NAME_DEFAULT, slotScope, $scopedSlots, $slots))]); + } + }); + + var DropdownPlugin = /*#__PURE__*/pluginFactory({ + components: { + BDropdown: BDropdown, + BDd: BDropdown, + BDropdownItem: BDropdownItem, + BDdItem: BDropdownItem, + BDropdownItemButton: BDropdownItemButton, + BDropdownItemBtn: BDropdownItemButton, + BDdItemButton: BDropdownItemButton, + BDdItemBtn: BDropdownItemButton, + BDropdownHeader: BDropdownHeader, + BDdHeader: BDropdownHeader, + BDropdownDivider: BDropdownDivider, + BDdDivider: BDropdownDivider, + BDropdownForm: BDropdownForm, + BDdForm: BDropdownForm, + BDropdownText: BDropdownText, + BDdText: BDropdownText, + BDropdownGroup: BDropdownGroup, + BDdGroup: BDropdownGroup + } + }); + + var TYPES$2 = ['iframe', 'embed', 'video', 'object', 'img', 'b-img', 'b-img-lazy']; // --- Props --- + + var props$1E = makePropsConfigurable({ + aspect: makeProp(PROP_TYPE_STRING, '16by9'), + tag: makeProp(PROP_TYPE_STRING, 'div'), + type: makeProp(PROP_TYPE_STRING, 'iframe', function (value) { + return arrayIncludes(TYPES$2, value); + }) + }, NAME_EMBED); // --- Main component --- + // @vue/component + + var BEmbed = /*#__PURE__*/extend({ + name: NAME_EMBED, + functional: true, + props: props$1E, + render: function render(h, _ref) { + var props = _ref.props, + data = _ref.data, + children = _ref.children; + var aspect = props.aspect; + return h(props.tag, { + staticClass: 'embed-responsive', + class: _defineProperty({}, "embed-responsive-".concat(aspect), aspect), + ref: data.ref + }, [h(props.type, a(omit(data, ['ref']), { + staticClass: 'embed-responsive-item' + }), children)]); + } + }); + + var EmbedPlugin = /*#__PURE__*/pluginFactory({ + components: { + BEmbed: BEmbed + } + }); + + var OPTIONS_OBJECT_DEPRECATED_MSG = 'Setting prop "options" to an object is deprecated. Use the array format instead.'; // --- Props --- + + var props$1D = makePropsConfigurable({ + disabledField: makeProp(PROP_TYPE_STRING, 'disabled'), + htmlField: makeProp(PROP_TYPE_STRING, 'html'), + options: makeProp(PROP_TYPE_ARRAY_OBJECT, []), + textField: makeProp(PROP_TYPE_STRING, 'text'), + valueField: makeProp(PROP_TYPE_STRING, 'value') + }, 'formOptionControls'); // --- Mixin --- + // @vue/component + + var formOptionsMixin = extend({ + props: props$1D, + computed: { + formOptions: function formOptions() { + return this.normalizeOptions(this.options); + } + }, + methods: { + normalizeOption: function normalizeOption(option) { + var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + // When the option is an object, normalize it + if (isPlainObject(option)) { + var value = get(option, this.valueField); + var text = get(option, this.textField); + return { + value: isUndefined(value) ? key || text : value, + text: stripTags(String(isUndefined(text) ? key : text)), + html: get(option, this.htmlField), + disabled: Boolean(get(option, this.disabledField)) + }; + } // Otherwise create an `