diff --git a/benchmark.md b/benchmark.md index f2273ce96..e66f87b71 100644 --- a/benchmark.md +++ b/benchmark.md @@ -1,36 +1,38 @@ # System informations - {"cpuName":"Apple M1","freeRam":163.59375,"totalRam":8192} + {"cpuName":"Apple M1","freeRam":202.546875,"totalRam":8192} _________ | filename | Size (mb) | Time to open model (ms) | Time to execute all (ms) | Total ifc entities | Total meshes | Total geometries | total errors | |-------|-------|-------|-------|-------|-------|-------|-------| -| tests/ifcfiles/public/AC20-FZK-Haus.ifc | 2 | 32 | 243 | 44249 | 83 | 103 | 0 | - tests/ifcfiles/public/C20-Institute-Var-2.ifc | 10 | 80 | 612 | 147712 | 702 | 821 | 0 | - tests/ifcfiles/public/FM_ARC_DigitalHub.ifc | 14 | 121 | 1140 | 266483 | 705 | 725 | 0 | - tests/ifcfiles/public/ISSUE_005_haus.ifc | 2 | 21 | 212 | 44249 | 83 | 103 | 0 | - tests/ifcfiles/public/ISSUE_021_Mini Project.ifc | 3 | 22 | 699 | 49044 | 2636 | 3697 | 0 | - tests/ifcfiles/public/ISSUE_034_HouseZ.ifc | 5 | 34 | 155 | 81806 | 228 | 239 | 0 | - tests/ifcfiles/public/ISSUE_044_test_IFCCOMPOSITEPROFILEDEF.ifc | 0 | 1 | 0 | 435 | 7 | 11 | 0 | - tests/ifcfiles/public/ISSUE_053_20181220Holter_Tower_10.ifczip | 29 | 1740 | 5648 | 2807815 | 60285 | 60847 | 0 | - tests/ifcfiles/public/ISSUE_068_ARK_NUS_skolebygg.ifc | 55 | 584 | 2239 | 945194 | 4459 | 4542 | 0 | - tests/ifcfiles/public/ISSUE_102_M3D-CON-CD.ifc | 26 | 238 | 2340 | 503608 | 1616 | 1635 | 0 | - tests/ifcfiles/public/ISSUE_102_M3D-CON.ifc | 6 | 47 | 219 | 123282 | 138 | 143 | 0 | - tests/ifcfiles/public/ISSUE_126_model.ifc | 4 | 33 | 130 | 88876 | 257 | 288 | 0 | - tests/ifcfiles/public/ISSUE_129_N1540_17_EXE_MOD_448200_02_09_11SMC_IGC_V17.ifc | 12 | 91 | 667 | 202661 | 959 | 981 | 0 | - tests/ifcfiles/public/ISSUE_159_kleine_Wohnung_R22.ifc | 10 | 88 | 732 | 189788 | 425 | 457 | 0 | - tests/ifcfiles/public/ISSUE_171_IfcSurfaceCurveSweptAreaSolid.ifc | 0 | 2 | 20 | 4327 | 60 | 141 | 0 | +| tests/ifcfiles/public/AC20-FZK-Haus.ifc | 2 | 28 | 195 | 44249 | 83 | 103 | 0 | + tests/ifcfiles/public/C20-Institute-Var-2.ifc | 10 | 78 | 547 | 147712 | 702 | 821 | 0 | + tests/ifcfiles/public/FM_ARC_DigitalHub.ifc | 14 | 92 | 859 | 266483 | 705 | 725 | 0 | + tests/ifcfiles/public/ISSUE_005_haus.ifc | 2 | 17 | 177 | 44249 | 83 | 103 | 0 | + tests/ifcfiles/public/ISSUE_021_Mini Project.ifc | 3 | 21 | 623 | 49044 | 2636 | 3697 | 0 | + tests/ifcfiles/public/ISSUE_034_HouseZ.ifc | 5 | 33 | 140 | 81806 | 228 | 239 | 0 | + tests/ifcfiles/public/ISSUE_044_test_IFCCOMPOSITEPROFILEDEF.ifc | 0 | 0 | 0 | 435 | 7 | 11 | 0 | + tests/ifcfiles/public/ISSUE_053_20181220Holter_Tower_10.ifczip | 29 | 1301 | 4471 | 2807815 | 60285 | 60847 | 0 | + tests/ifcfiles/public/ISSUE_068_ARK_NUS_skolebygg.ifc | 55 | 413 | 1931 | 945194 | 4459 | 4542 | 0 | + tests/ifcfiles/public/ISSUE_098_R8_F1_MAB_AR_M3_XX_XXX_MO_7000.ifc | 70 | 492 | 5098 | 1139622 | 11124 | 11338 | 0 | + tests/ifcfiles/public/ISSUE_102_M3D-CON-CD.ifc | 26 | 224 | 2119 | 503608 | 1616 | 1635 | 0 | + tests/ifcfiles/public/ISSUE_102_M3D-CON.ifc | 6 | 45 | 178 | 123282 | 138 | 143 | 0 | + tests/ifcfiles/public/ISSUE_126_model.ifc | 4 | 31 | 98 | 88876 | 257 | 288 | 0 | + tests/ifcfiles/public/ISSUE_129_N1540_17_EXE_MOD_448200_02_09_11SMC_IGC_V17.ifc | 12 | 82 | 580 | 202661 | 959 | 981 | 0 | + tests/ifcfiles/public/ISSUE_159_kleine_Wohnung_R22.ifc | 10 | 71 | 575 | 189788 | 425 | 457 | 0 | + tests/ifcfiles/public/ISSUE_171_IfcSurfaceCurveSweptAreaSolid.ifc | 0 | 2 | 18 | 4327 | 60 | 141 | 0 | tests/ifcfiles/public/IfcOpenHouse_IFC4.ifc | 0 | 1 | 6 | 2885 | 35 | 43 | 0 | - tests/ifcfiles/public/KIT-Simple-Road-Test-Web-IFC4x3_RC2.ifc | 0 | 3 | 4 | 6500 | 66 | 119 | 0 | - tests/ifcfiles/public/Office_A_20110811.ifc | 4 | 27 | 280 | 62930 | 803 | 810 | 0 | - tests/ifcfiles/public/S_Office_Integrated Design Archi.ifc | 30 | 304 | 6086 | 551442 | 3417 | 3873 | 0 | - tests/ifcfiles/public/Sample_entities.ifc | 0 | 0 | 1 | 466 | 2 | 10 | 0 | - tests/ifcfiles/public/Viadotto Acerno.ifc | 32 | 225 | 3732 | 253318 | 6546 | 7051 | 0 | - tests/ifcfiles/public/advanced_model.ifc | 34 | 379 | 2387 | 594374 | 6401 | 14120 | 0 | - tests/ifcfiles/public/dental_clinic.ifc | 12 | 200 | 431 | 209259 | 2586 | 2626 | 0 | - tests/ifcfiles/public/duplex.ifc | 2 | 16 | 65 | 38898 | 215 | 224 | 0 | + tests/ifcfiles/public/KIT-Simple-Road-Test-Web-IFC4x3_RC2.ifc | 0 | 2 | 4 | 6500 | 66 | 119 | 0 | + tests/ifcfiles/public/LTU_A-House_redesign.ifczip | 34 | 1312 | 6512 | 3359234 | 6928 | 6945 | 0 | + tests/ifcfiles/public/Office_A_20110811.ifc | 4 | 27 | 180 | 62930 | 803 | 810 | 0 | + tests/ifcfiles/public/S_Office_Integrated Design Archi.ifc | 30 | 244 | 5399 | 551442 | 3417 | 3873 | 0 | + tests/ifcfiles/public/Sample_entities.ifc | 0 | 0 | 0 | 466 | 2 | 10 | 0 | + tests/ifcfiles/public/Viadotto Acerno.ifc | 32 | 225 | 3216 | 253318 | 6546 | 7051 | 0 | + tests/ifcfiles/public/advanced_model.ifc | 34 | 275 | 1563 | 594374 | 6401 | 14120 | 0 | + tests/ifcfiles/public/dental_clinic.ifc | 12 | 83 | 398 | 209259 | 2586 | 2626 | 0 | + tests/ifcfiles/public/duplex.ifc | 2 | 15 | 60 | 38898 | 215 | 224 | 0 | tests/ifcfiles/public/example.ifc | 0 | 3 | 8 | 6488 | 115 | 119 | 0 | - tests/ifcfiles/public/ifcbridge-model01.ifc | 14 | 116 | 492 | 296968 | 165 | 168 | 0 | - tests/ifcfiles/public/schependomlaan.ifc | 47 | 424 | 612 | 714485 | 3569 | 3643 | 0 | - tests/ifcfiles/public/tested_sample_project.ifc | 1 | 5 | 98 | 14119 | 93 | 98 | 0 | + tests/ifcfiles/public/ifcbridge-model01.ifc | 14 | 109 | 302 | 296968 | 165 | 168 | 0 | + tests/ifcfiles/public/schependomlaan.ifc | 47 | 337 | 501 | 714485 | 3569 | 3643 | 0 | + tests/ifcfiles/public/tested_sample_project.ifc | 1 | 5 | 75 | 14119 | 93 | 98 | 0 | #Totals -*Total Time to Open*:4837 -*Total Time*:29258 +*Total Time to Open*:5568 +*Total Time*:35833 diff --git a/src/cpp/web-ifc/parsing/IfcFileStream.cpp b/src/cpp/web-ifc/parsing/IfcFileStream.cpp index 3a2719be9..168b2e446 100644 --- a/src/cpp/web-ifc/parsing/IfcFileStream.cpp +++ b/src/cpp/web-ifc/parsing/IfcFileStream.cpp @@ -8,8 +8,17 @@ IfcTokenStream::IfcFileStream::IfcFileStream(const std::function &requestData, uint32_t size) : _dataSource(requestData), _size(size) { - _buffer = nullptr; - load(); + + char * countBuffer = new char[_size]; + size_t countSize = 0; + size_t startCountRef =0; + while ((countSize = _dataSource(countBuffer, startCountRef, _size)) != 0) { + for (size_t i=0; i < countSize;i++) if (countBuffer[i]=='\n') noLines++; + startCountRef+=countSize; + } + delete[] countBuffer; + _buffer = nullptr; + load(); } IfcTokenStream::IfcFileStream::~IfcFileStream() @@ -19,6 +28,10 @@ _buffer = nullptr; } } + + size_t IfcTokenStream::IfcFileStream::GetNoLines() { + return noLines; + } void IfcTokenStream::IfcFileStream::load() { diff --git a/src/cpp/web-ifc/parsing/IfcLoader.cpp b/src/cpp/web-ifc/parsing/IfcLoader.cpp index ae5927757..3c7c1b262 100644 --- a/src/cpp/web-ifc/parsing/IfcLoader.cpp +++ b/src/cpp/web-ifc/parsing/IfcLoader.cpp @@ -227,7 +227,8 @@ namespace webifc::parsing { void IfcLoader::ParseLines() { - uint32_t currentIfcType = 0; + _lines.reserve(_tokenStream->GetNoLines()); + uint32_t currentIfcType = 0; uint32_t currentExpressID = 0; uint32_t currentTapeOffset = 0; while (!_tokenStream->IsAtEnd()) diff --git a/src/cpp/web-ifc/parsing/IfcLoader.h b/src/cpp/web-ifc/parsing/IfcLoader.h index cc906fd89..586a5ebca 100644 --- a/src/cpp/web-ifc/parsing/IfcLoader.h +++ b/src/cpp/web-ifc/parsing/IfcLoader.h @@ -65,7 +65,6 @@ namespace webifc::parsing void PushInt(int input); std::string GenerateUUID() const; IfcLoader* Clone(); - uint32_t GetNextExpressID(uint32_t expressId) const; template void Push(T input) { diff --git a/src/cpp/web-ifc/parsing/IfcTokenStream.cpp b/src/cpp/web-ifc/parsing/IfcTokenStream.cpp index 5e92b8c21..99fc073e1 100644 --- a/src/cpp/web-ifc/parsing/IfcTokenStream.cpp +++ b/src/cpp/web-ifc/parsing/IfcTokenStream.cpp @@ -24,6 +24,11 @@ namespace webifc::parsing delete _fileStream; } + size_t IfcTokenStream::GetNoLines() { + if (_fileStream != nullptr) return _fileStream->GetNoLines(); + return 0; + } + void IfcTokenStream::SetTokenSource(const std::function &requestData) { _fileStream = new IfcFileStream(requestData,_chunkSize); diff --git a/src/cpp/web-ifc/parsing/IfcTokenStream.h b/src/cpp/web-ifc/parsing/IfcTokenStream.h index a351f4826..01d4db259 100644 --- a/src/cpp/web-ifc/parsing/IfcTokenStream.h +++ b/src/cpp/web-ifc/parsing/IfcTokenStream.h @@ -61,6 +61,7 @@ namespace webifc::parsing size_t GetReadOffset(); size_t GetTotalSize(); IfcTokenStream * Clone(); + size_t GetNoLines(); private: void checkMemory(); @@ -83,6 +84,7 @@ namespace webifc::parsing bool IsAtEnd(); char Get(); void Clear(); + size_t GetNoLines(); IfcFileStream * Clone(); private: void load(); @@ -92,7 +94,8 @@ namespace webifc::parsing char prev; size_t _currentSize=0; size_t _startRef=0; - char * _buffer; + char * _buffer; + size_t noLines=0; }; class IfcTokenChunk { diff --git a/tests/ifcfiles/public/ISSUE_098_R8_F1_MAB_AR_M3_XX_XXX_MO_7000.IFC b/tests/ifcfiles/public/ISSUE_098_R8_F1_MAB_AR_M3_XX_XXX_MO_7000.ifc similarity index 100% rename from tests/ifcfiles/public/ISSUE_098_R8_F1_MAB_AR_M3_XX_XXX_MO_7000.IFC rename to tests/ifcfiles/public/ISSUE_098_R8_F1_MAB_AR_M3_XX_XXX_MO_7000.ifc diff --git a/tests/ifcfiles/public/LTU_A-House_redesign.ifczip b/tests/ifcfiles/public/LTU_A-House_redesign.ifczip new file mode 100644 index 000000000..50de22571 Binary files /dev/null and b/tests/ifcfiles/public/LTU_A-House_redesign.ifczip differ diff --git a/tests/regression/results.json b/tests/regression/results.json index 086d12764..5bb7414df 100644 --- a/tests/regression/results.json +++ b/tests/regression/results.json @@ -1 +1 @@ -{"tests/ifcfiles/public/AC20-FZK-Haus.ifc":"7cd881f70ccc462cc607ef88953ad3f1e3948fb3c03f2f6f114458464232bcf0","tests/ifcfiles/public/C20-Institute-Var-2.ifc":"a27066e11fec68b71cbd6f60b9651872934dfcae672be30e9385f7cffe990e10","tests/ifcfiles/public/FM_ARC_DigitalHub.ifc":"816a85f189a89ed4636727235965204178f17df362180e843a31a63321b2ae43","tests/ifcfiles/public/ISSUE_005_haus.ifc":"7cd881f70ccc462cc607ef88953ad3f1e3948fb3c03f2f6f114458464232bcf0","tests/ifcfiles/public/ISSUE_021_Mini Project.ifc":"96b8a44c490fcb171416bc4b1a6f5f8e629c654e5c4e32048ae7b970491c57d9","tests/ifcfiles/public/ISSUE_034_HouseZ.ifc":"c32124dd0c791389725630e3394ee609ad3374c0a6d6e93e66bf210eddbac4c6","tests/ifcfiles/public/ISSUE_044_test_IFCCOMPOSITEPROFILEDEF.ifc":"837885c8f8091aeaeb9ec3c3f85a6ff470a415e610b8ba3e49f9b33c9cf9d619","tests/ifcfiles/public/ISSUE_053_20181220Holter_Tower_10.ifczip":"7607812a43118b96f1134abdeb0dba9d604e43fa39ed161dc4c143e5f62f3142","tests/ifcfiles/public/ISSUE_068_ARK_NUS_skolebygg.ifc":"6cd39fcebf1bae8ddeceeb72208633dadaa93a99f0148b48e4eb60f652113401","tests/ifcfiles/public/ISSUE_102_M3D-CON-CD.ifc":"5a95c72bfe2ce9e1039613d39293c0cc996113038b46cd41ed8ec30ec2663594","tests/ifcfiles/public/ISSUE_102_M3D-CON.ifc":"486a8212c0d6860840d883981ca52daaad3bf3b2ab5be56cdc47ed9b42daba22","tests/ifcfiles/public/ISSUE_126_model.ifc":"672e021f10489f8784eea6b3d11cda34d4785ee54af1171122d87182172a4a44","tests/ifcfiles/public/ISSUE_129_N1540_17_EXE_MOD_448200_02_09_11SMC_IGC_V17.ifc":"1f78b11a03c231498f7f0040f0f556b970b2233ac0f419b36869eec00087afbd","tests/ifcfiles/public/ISSUE_159_kleine_Wohnung_R22.ifc":"2f47ffe37c6dff1cd59018ac373cd6fbbe1673d68d76b23ce19011f8cae470f5","tests/ifcfiles/public/ISSUE_171_IfcSurfaceCurveSweptAreaSolid.ifc":"9c56f48ae9bafd205262034bfcc2232b2c63348cb723d681ec39f13409f990cc","tests/ifcfiles/public/IfcOpenHouse_IFC4.ifc":"9e1736c43d19118e6ce4302118af337109491ecc52757dfb949bad6a7940b0c2","tests/ifcfiles/public/KIT-Simple-Road-Test-Web-IFC4x3_RC2.ifc":"efbb03b7a7f6fd3c29391d4d0281e1830a85caadd831c3f04716faca4107a42e","tests/ifcfiles/public/Office_A_20110811.ifc":"c4b102addbcc7d44d4245d2250fd097e838a57e6d4e8e29d93e3b93c9a0add8f","tests/ifcfiles/public/S_Office_Integrated Design Archi.ifc":"5109480b67a82a9daa22919b71265d5697f214942074b09d474addc2e85f2b54","tests/ifcfiles/public/Sample_entities.ifc":"15ec7bf0b50732b49f8228e07d24365338f9e3ab994b00af08e5a3bffe55fd8b","tests/ifcfiles/public/Viadotto Acerno.ifc":"5ab5f1ac57d0f455f66623e7d07ee271f63a08d0373c39c793ddfa51e4e1089c","tests/ifcfiles/public/advanced_model.ifc":"662bf47566f6dfdcce745b2089fc89676f74bce8b76724cefbcfcb76ff39cdfd","tests/ifcfiles/public/dental_clinic.ifc":"c7e363455f4f22e2d4302f77d770edca28f99ecd8a94f31d4b7ec29eb6314dcf","tests/ifcfiles/public/duplex.ifc":"e6ff459ebc86a128b3e37b46d41efd52eedbe5c955acf3d20dfbf99a33fb2557","tests/ifcfiles/public/example.ifc":"f616b0d54e78571a9611f343c9f8e022e859e920381ab0e4d3da01e193a7bd7e","tests/ifcfiles/public/ifcbridge-model01.ifc":"1eca0d8cd72459f79f29c3304378ba665589d329aedae4ed7fa9f94f9606bc8c","tests/ifcfiles/public/schependomlaan.ifc":"93a8587d138dd9f50b0d282348e7601c45859c4e0de678c9e62469689e9e6370","tests/ifcfiles/public/tested_sample_project.ifc":"6929dc871287c5e3a2d9e99399f4bf688c63dc15b1a627e6cc8da68b423a028c"} \ No newline at end of file +{"tests/ifcfiles/public/AC20-FZK-Haus.ifc":"7cd881f70ccc462cc607ef88953ad3f1e3948fb3c03f2f6f114458464232bcf0","tests/ifcfiles/public/C20-Institute-Var-2.ifc":"a27066e11fec68b71cbd6f60b9651872934dfcae672be30e9385f7cffe990e10","tests/ifcfiles/public/FM_ARC_DigitalHub.ifc":"816a85f189a89ed4636727235965204178f17df362180e843a31a63321b2ae43","tests/ifcfiles/public/ISSUE_005_haus.ifc":"7cd881f70ccc462cc607ef88953ad3f1e3948fb3c03f2f6f114458464232bcf0","tests/ifcfiles/public/ISSUE_021_Mini Project.ifc":"96b8a44c490fcb171416bc4b1a6f5f8e629c654e5c4e32048ae7b970491c57d9","tests/ifcfiles/public/ISSUE_034_HouseZ.ifc":"c32124dd0c791389725630e3394ee609ad3374c0a6d6e93e66bf210eddbac4c6","tests/ifcfiles/public/ISSUE_044_test_IFCCOMPOSITEPROFILEDEF.ifc":"837885c8f8091aeaeb9ec3c3f85a6ff470a415e610b8ba3e49f9b33c9cf9d619","tests/ifcfiles/public/ISSUE_053_20181220Holter_Tower_10.ifczip":"7607812a43118b96f1134abdeb0dba9d604e43fa39ed161dc4c143e5f62f3142","tests/ifcfiles/public/ISSUE_068_ARK_NUS_skolebygg.ifc":"6cd39fcebf1bae8ddeceeb72208633dadaa93a99f0148b48e4eb60f652113401","tests/ifcfiles/public/ISSUE_098_R8_F1_MAB_AR_M3_XX_XXX_MO_7000.ifc":"9abcf4cb15101297fc60012669f02606976ea9053ec09538b949d012a7852638","tests/ifcfiles/public/ISSUE_102_M3D-CON-CD.ifc":"5a95c72bfe2ce9e1039613d39293c0cc996113038b46cd41ed8ec30ec2663594","tests/ifcfiles/public/ISSUE_102_M3D-CON.ifc":"486a8212c0d6860840d883981ca52daaad3bf3b2ab5be56cdc47ed9b42daba22","tests/ifcfiles/public/ISSUE_126_model.ifc":"672e021f10489f8784eea6b3d11cda34d4785ee54af1171122d87182172a4a44","tests/ifcfiles/public/ISSUE_129_N1540_17_EXE_MOD_448200_02_09_11SMC_IGC_V17.ifc":"1f78b11a03c231498f7f0040f0f556b970b2233ac0f419b36869eec00087afbd","tests/ifcfiles/public/ISSUE_159_kleine_Wohnung_R22.ifc":"2f47ffe37c6dff1cd59018ac373cd6fbbe1673d68d76b23ce19011f8cae470f5","tests/ifcfiles/public/ISSUE_171_IfcSurfaceCurveSweptAreaSolid.ifc":"9c56f48ae9bafd205262034bfcc2232b2c63348cb723d681ec39f13409f990cc","tests/ifcfiles/public/IfcOpenHouse_IFC4.ifc":"9e1736c43d19118e6ce4302118af337109491ecc52757dfb949bad6a7940b0c2","tests/ifcfiles/public/KIT-Simple-Road-Test-Web-IFC4x3_RC2.ifc":"efbb03b7a7f6fd3c29391d4d0281e1830a85caadd831c3f04716faca4107a42e","tests/ifcfiles/public/LTU_A-House_redesign.ifczip":"678b7cfe9ecd128619ae4ce8c8cd9c43be4d046db01d8218c7f10a3a09057da0","tests/ifcfiles/public/Office_A_20110811.ifc":"c4b102addbcc7d44d4245d2250fd097e838a57e6d4e8e29d93e3b93c9a0add8f","tests/ifcfiles/public/S_Office_Integrated Design Archi.ifc":"5109480b67a82a9daa22919b71265d5697f214942074b09d474addc2e85f2b54","tests/ifcfiles/public/Sample_entities.ifc":"15ec7bf0b50732b49f8228e07d24365338f9e3ab994b00af08e5a3bffe55fd8b","tests/ifcfiles/public/Viadotto Acerno.ifc":"5ab5f1ac57d0f455f66623e7d07ee271f63a08d0373c39c793ddfa51e4e1089c","tests/ifcfiles/public/advanced_model.ifc":"662bf47566f6dfdcce745b2089fc89676f74bce8b76724cefbcfcb76ff39cdfd","tests/ifcfiles/public/dental_clinic.ifc":"c7e363455f4f22e2d4302f77d770edca28f99ecd8a94f31d4b7ec29eb6314dcf","tests/ifcfiles/public/duplex.ifc":"e6ff459ebc86a128b3e37b46d41efd52eedbe5c955acf3d20dfbf99a33fb2557","tests/ifcfiles/public/example.ifc":"f616b0d54e78571a9611f343c9f8e022e859e920381ab0e4d3da01e193a7bd7e","tests/ifcfiles/public/ifcbridge-model01.ifc":"1eca0d8cd72459f79f29c3304378ba665589d329aedae4ed7fa9f94f9606bc8c","tests/ifcfiles/public/schependomlaan.ifc":"93a8587d138dd9f50b0d282348e7601c45859c4e0de678c9e62469689e9e6370","tests/ifcfiles/public/tested_sample_project.ifc":"6929dc871287c5e3a2d9e99399f4bf688c63dc15b1a627e6cc8da68b423a028c"} \ No newline at end of file