Skip to content

Commit 3393cc4

Browse files
Merge pull request #356 from F2I-Consulting/dev
v2.12.2.0
2 parents f2099a5 + e7050c7 commit 3393cc4

6 files changed

Lines changed: 133 additions & 73 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
- build
88
- fesapi (Git clone this repository into this folder "fesapi". You should then have a path fesapiEnv/fesapi/src)
99
- dependencies
10-
- The following compilers are known to work
10+
- The following compilers (C++17 is needed) are known to work
1111
- gcc from version 8
1212
- visual studio from version 2019
1313
- clang from version 5.0

src/resqml2_0_1/TriangulatedSetRepresentation.cpp

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,18 @@ TriangulatedSetRepresentation::TriangulatedSetRepresentation(RESQML2_NS::Abstrac
6363

6464
COMMON_NS::DataObjectReference TriangulatedSetRepresentation::getHdfProxyDor() const
6565
{
66-
resqml20__TrianglePatch* patch = static_cast<_resqml20__TriangulatedSetRepresentation*>(gsoapProxy2_0_1)->TrianglePatch[0];
66+
resqml20__TrianglePatch const* patch = static_cast<_resqml20__TriangulatedSetRepresentation const*>(gsoapProxy2_0_1)->TrianglePatch[0];
6767
if (patch->Triangles->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array)
6868
{
69-
return COMMON_NS::DataObjectReference(static_cast<resqml20__IntegerHdf5Array*>(patch->Triangles)->Values->HdfProxy);
69+
return COMMON_NS::DataObjectReference(static_cast<resqml20__IntegerHdf5Array const*>(patch->Triangles)->Values->HdfProxy);
7070
}
7171

7272
return getHdfProxyDorFromPointGeometryPatch(getPointGeometry2_0_1(0));
7373
}
7474

7575
resqml20__PointGeometry* TriangulatedSetRepresentation::getPointGeometry2_0_1(uint64_t patchIndex) const
7676
{
77-
return static_cast<_resqml20__TriangulatedSetRepresentation*>(gsoapProxy2_0_1)->TrianglePatch.at(patchIndex)->Geometry;
77+
return static_cast<_resqml20__TriangulatedSetRepresentation const*>(gsoapProxy2_0_1)->TrianglePatch.at(patchIndex)->Geometry;
7878
}
7979

8080
void TriangulatedSetRepresentation::pushBackTrianglePatch(
@@ -101,7 +101,7 @@ void TriangulatedSetRepresentation::pushBackTrianglePatch(
101101
patch->PatchIndex = triRep->TrianglePatch.size();
102102
triRep->TrianglePatch.push_back(patch);
103103

104-
uint64_t pointCountDims[2] = { nodeCount, 3 };
104+
const uint64_t pointCountDims[2] = { nodeCount, 3 };
105105
patch->NodeCount = nodeCount;
106106
patch->Geometry = createPointGeometryPatch2_0_1(patch->PatchIndex, nodes, localCrs, pointCountDims, 2, proxy);
107107
getRepository()->addRelationship(this, localCrs);
@@ -118,7 +118,7 @@ void TriangulatedSetRepresentation::pushBackTrianglePatch(
118118
ossForHdf << "triangles_patch" << patch->PatchIndex;
119119
hdfTriangles->Values->PathInHdfFile = getHdfGroup() + "/" + ossForHdf.str();
120120
// ************ HDF *************
121-
uint64_t dim[2] = {triangleCount, 3};
121+
const uint64_t dim[2] = {triangleCount, 3};
122122
proxy->writeArrayNd(getHdfGroup(),
123123
ossForHdf.str(), COMMON_NS::AbstractObject::numericalDatatypeEnum::UINT32,
124124
triangleNodeIndices,
@@ -127,19 +127,16 @@ void TriangulatedSetRepresentation::pushBackTrianglePatch(
127127

128128
uint64_t TriangulatedSetRepresentation::getXyzPointCountOfPatch(unsigned int patchIndex) const
129129
{
130-
return static_cast<_resqml20__TriangulatedSetRepresentation*>(gsoapProxy2_0_1)->TrianglePatch.at(patchIndex)->NodeCount;
130+
return static_cast<_resqml20__TriangulatedSetRepresentation const*>(gsoapProxy2_0_1)->TrianglePatch.at(patchIndex)->NodeCount;
131131
}
132132

133133
void TriangulatedSetRepresentation::getXyzPointsOfPatch(unsigned int patchIndex, double* xyzPoints) const
134134
{
135-
if (patchIndex >= getPatchCount())
136-
throw range_error("The index of the patch is not in the allowed range of patch.");
137-
138-
resqml20__PointGeometry* pointGeom = getPointGeometry2_0_1(patchIndex);
135+
resqml20__PointGeometry const* pointGeom = getPointGeometry2_0_1(patchIndex);
139136
if (pointGeom != nullptr && pointGeom->Points->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__Point3dHdf5Array)
140137
{
141-
eml20__Hdf5Dataset const * dataset = static_cast<resqml20__Point3dHdf5Array*>(pointGeom->Points)->Coordinates;
142-
EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset);
138+
eml20__Hdf5Dataset const* dataset = static_cast<resqml20__Point3dHdf5Array const*>(pointGeom->Points)->Coordinates;
139+
EML2_NS::AbstractHdfProxy* hdfProxy = getHdfProxyFromDataset(dataset);
143140
hdfProxy->readArrayNdOfDoubleValues(dataset->PathInHdfFile, xyzPoints);
144141
}
145142
else
@@ -148,36 +145,29 @@ void TriangulatedSetRepresentation::getXyzPointsOfPatch(unsigned int patchIndex,
148145

149146
uint64_t TriangulatedSetRepresentation::getTriangleCountOfPatch(unsigned int patchIndex) const
150147
{
151-
return static_cast<_resqml20__TriangulatedSetRepresentation*>(gsoapProxy2_0_1)->TrianglePatch.at(patchIndex)->Count;
148+
return static_cast<_resqml20__TriangulatedSetRepresentation const*>(gsoapProxy2_0_1)->TrianglePatch.at(patchIndex)->Count;
152149
}
153150

154151
uint64_t TriangulatedSetRepresentation::getTriangleCountOfAllPatches() const
155152
{
156153
return std::accumulate(
157-
static_cast<_resqml20__TriangulatedSetRepresentation*>(gsoapProxy2_0_1)->TrianglePatch.begin(),
158-
static_cast<_resqml20__TriangulatedSetRepresentation*>(gsoapProxy2_0_1)->TrianglePatch.end(),
159-
1,
160-
[](int a, resqml20__TrianglePatch const* b) {
154+
static_cast<_resqml20__TriangulatedSetRepresentation const*>(gsoapProxy2_0_1)->TrianglePatch.begin(),
155+
static_cast<_resqml20__TriangulatedSetRepresentation const*>(gsoapProxy2_0_1)->TrianglePatch.end(),
156+
0,
157+
[](uint64_t a, resqml20__TrianglePatch const* b) {
161158
return a + b->Count;
162159
}
163160
);
164161
}
165162

166163
void TriangulatedSetRepresentation::getTriangleNodeIndicesOfPatch(unsigned int patchIndex, unsigned int* triangleNodeIndices) const
167164
{
168-
_resqml20__TriangulatedSetRepresentation* triRep = static_cast<_resqml20__TriangulatedSetRepresentation*>(gsoapProxy2_0_1);
169-
170-
if (patchIndex >= triRep->TrianglePatch.size()) {
171-
throw out_of_range("The patchIndex is out of range");
172-
}
173-
174-
readArrayNdOfUInt32Values(triRep->TrianglePatch[patchIndex]->Triangles, triangleNodeIndices);
165+
readArrayNdOfUInt32Values(static_cast<_resqml20__TriangulatedSetRepresentation const*>(gsoapProxy2_0_1)->TrianglePatch.at(patchIndex)->Triangles, triangleNodeIndices);
175166
}
176167

177168
void TriangulatedSetRepresentation::getTriangleNodeIndicesOfAllPatches(unsigned int* triangleNodeIndices) const
178169
{
179-
_resqml20__TriangulatedSetRepresentation* triRep = static_cast<_resqml20__TriangulatedSetRepresentation*>(gsoapProxy2_0_1);
180-
size_t patchCount = triRep->TrianglePatch.size();
170+
const size_t patchCount = static_cast<_resqml20__TriangulatedSetRepresentation const*>(gsoapProxy2_0_1)->TrianglePatch.size();
181171
for (size_t patchIndex = 0; patchIndex < patchCount; patchIndex++)
182172
{
183173
getTriangleNodeIndicesOfPatch(patchIndex, triangleNodeIndices);
@@ -187,5 +177,5 @@ void TriangulatedSetRepresentation::getTriangleNodeIndicesOfAllPatches(unsigned
187177

188178
uint64_t TriangulatedSetRepresentation::getPatchCount() const
189179
{
190-
return static_cast<_resqml20__TriangulatedSetRepresentation*>(gsoapProxy2_0_1)->TrianglePatch.size();
180+
return static_cast<_resqml20__TriangulatedSetRepresentation const*>(gsoapProxy2_0_1)->TrianglePatch.size();
191181
}

test/resqml2_test/FaultMultiPatchTriangulatedSetRepresentationTest.cpp

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,33 +40,54 @@ void FaultMultiPatchTriangulatedSetRepresentationTest::initRepo()
4040
TriangulatedSetRepresentation* rep = repo->createTriangulatedSetRepresentation(interp, defaultUuid, defaultTitle);
4141
REQUIRE( rep != nullptr );
4242

43-
// Patch 0
44-
double explicitPointsFault1Patch0[18] = {150, 0, 200, 150, 100, 200, 150, 200, 200,
45-
250, 0, 300, 250, 100, 300, 250, 200, 300};
46-
unsigned int triangleNodeIndexFaultPatch0[12] = {0,4,3, 0,1,4, 1,2,4, 2,5,4};
4743
rep->pushBackTrianglePatch(6, explicitPointsFault1Patch0, 4, triangleNodeIndexFaultPatch0, repo->getHdfProxySet()[0]);
48-
// Patch 1
49-
double explicitPointsFault1Patch1[18] = {250, 0, 300, 250, 100, 300, 250, 200, 300,
50-
300, 0, 350, 300, 100, 350, 300, 200, 350};
51-
unsigned int triangleNodeIndexFaultPatch1[12] = {6,10,9, 6,7,10, 7,8,10, 8,11,10};
5244
rep->pushBackTrianglePatch(6, explicitPointsFault1Patch1, 4, triangleNodeIndexFaultPatch1, repo->getHdfProxySet()[0]);
53-
// Patch 2
54-
double explicitPointsFault1Patch2[18] = {300, 0, 350, 300, 100, 350, 300, 200, 350,
55-
450, 0, 500, 450, 100, 500, 450, 200, 500};
56-
unsigned int triangleNodeIndexFaultPatch2[12] = {12,16,15, 12,13,16, 13,14,16, 14,17,16};
5745
rep->pushBackTrianglePatch(6, explicitPointsFault1Patch2, 4, triangleNodeIndexFaultPatch2, repo->getHdfProxySet()[0]);
58-
// Patch 3
59-
double explicitPointsFault1Patch3[18] = {450, 0, 500, 450, 100, 500, 450, 200, 500,
60-
500, 0, 550, 500, 100, 550 ,500, 200, 550};
61-
unsigned int triangleNodeIndexFaultPatch3[12] = {18,22,21, 18,19,22, 19,20,22, 20,23,22};
6246
rep->pushBackTrianglePatch(6, explicitPointsFault1Patch3, 4, triangleNodeIndexFaultPatch3, repo->getHdfProxySet()[0]);
63-
// Patch 4
64-
double explicitPointsFault1Patch4[18] = {500, 0, 550, 500, 100, 550 ,500, 200, 550,
65-
600, 0, 650, 600, 100, 650, 600, 200, 650};
66-
unsigned int triangleNodeIndexFaultPatch4[12] = {24,28,27, 24,25,28, 25,26,28, 26,29,28};
6747
rep->pushBackTrianglePatch(6, explicitPointsFault1Patch4, 4, triangleNodeIndexFaultPatch4, repo->getHdfProxySet()[0]);
6848
}
6949

7050
void FaultMultiPatchTriangulatedSetRepresentationTest::readRepo()
7151
{
52+
RESQML2_NS::TriangulatedSetRepresentation* rep = repo->getDataObjectByUuid<RESQML2_NS::TriangulatedSetRepresentation>(defaultUuid);
53+
REQUIRE(rep->getSeismicSupportOfPatch(0) == nullptr);
54+
REQUIRE(rep->getPatchCount() == 5);
55+
REQUIRE(rep->getRepresentationSetRepresentationCount() == 0);
56+
REQUIRE(rep->getPropertySet().empty());
57+
REQUIRE(rep->getPointsPropertyCount() == 0);
58+
REQUIRE(rep->getSubRepresentationCount() == 0);
59+
REQUIRE(rep->getValuesPropertyCount() == 0);
60+
REQUIRE(rep->getTimeSeries() == nullptr);
61+
REQUIRE(rep->getTitle() == defaultTitle);
62+
REQUIRE(rep->getUuid() == defaultUuid);
63+
for (size_t patchIdx = 0; patchIdx < 5; ++patchIdx) {
64+
REQUIRE(rep->getTriangleCountOfPatch(patchIdx) == 4);
65+
REQUIRE(rep->getXyzPointCountOfPatch(0) == 6);
66+
}
67+
REQUIRE(rep->getTriangleCountOfAllPatches() == 20);
68+
REQUIRE(rep->getXyzPointCountOfAllPatches() == 30);
69+
70+
uint32_t triangleNodeIndexFaultPatch[12];
71+
rep->getTriangleNodeIndicesOfPatch(0, triangleNodeIndexFaultPatch);
72+
REQUIRE(std::equal(begin(triangleNodeIndexFaultPatch0), end(triangleNodeIndexFaultPatch0), begin(triangleNodeIndexFaultPatch)));
73+
rep->getTriangleNodeIndicesOfPatch(1, triangleNodeIndexFaultPatch);
74+
REQUIRE(std::equal(begin(triangleNodeIndexFaultPatch1), end(triangleNodeIndexFaultPatch1), begin(triangleNodeIndexFaultPatch)));
75+
rep->getTriangleNodeIndicesOfPatch(2, triangleNodeIndexFaultPatch);
76+
REQUIRE(std::equal(begin(triangleNodeIndexFaultPatch2), end(triangleNodeIndexFaultPatch2), begin(triangleNodeIndexFaultPatch)));
77+
rep->getTriangleNodeIndicesOfPatch(3, triangleNodeIndexFaultPatch);
78+
REQUIRE(std::equal(begin(triangleNodeIndexFaultPatch3), end(triangleNodeIndexFaultPatch3), begin(triangleNodeIndexFaultPatch)));
79+
rep->getTriangleNodeIndicesOfPatch(4, triangleNodeIndexFaultPatch);
80+
REQUIRE(std::equal(begin(triangleNodeIndexFaultPatch4), end(triangleNodeIndexFaultPatch4), begin(triangleNodeIndexFaultPatch)));
81+
82+
double explicitPointsFault[18];
83+
rep->getXyzPointsOfPatch(0, explicitPointsFault);
84+
REQUIRE(std::equal(begin(explicitPointsFault1Patch0), end(explicitPointsFault1Patch0), begin(explicitPointsFault)));
85+
rep->getXyzPointsOfPatch(1, explicitPointsFault);
86+
REQUIRE(std::equal(begin(explicitPointsFault1Patch1), end(explicitPointsFault1Patch1), begin(explicitPointsFault)));
87+
rep->getXyzPointsOfPatch(2, explicitPointsFault);
88+
REQUIRE(std::equal(begin(explicitPointsFault1Patch2), end(explicitPointsFault1Patch2), begin(explicitPointsFault)));
89+
rep->getXyzPointsOfPatch(3, explicitPointsFault);
90+
REQUIRE(std::equal(begin(explicitPointsFault1Patch3), end(explicitPointsFault1Patch3), begin(explicitPointsFault)));
91+
rep->getXyzPointsOfPatch(4, explicitPointsFault);
92+
REQUIRE(std::equal(begin(explicitPointsFault1Patch4), end(explicitPointsFault1Patch4), begin(explicitPointsFault)));
7293
}

test/resqml2_test/FaultMultiPatchTriangulatedSetRepresentationTest.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,27 @@ namespace resqml2_test {
4141
protected:
4242
void initRepo();
4343
void readRepo();
44+
45+
private:
46+
// Patch 0
47+
static constexpr double explicitPointsFault1Patch0[18] = { 150, 0, 200, 150, 100, 200, 150, 200, 200,
48+
250, 0, 300, 250, 100, 300, 250, 200, 300 };
49+
static constexpr uint32_t triangleNodeIndexFaultPatch0[12] = { 0,4,3, 0,1,4, 1,2,4, 2,5,4 };
50+
// Patch 1
51+
static constexpr double explicitPointsFault1Patch1[18] = { 250, 0, 300, 250, 100, 300, 250, 200, 300,
52+
300, 0, 350, 300, 100, 350, 300, 200, 350 };
53+
static constexpr uint32_t triangleNodeIndexFaultPatch1[12] = { 6,10,9, 6,7,10, 7,8,10, 8,11,10 };
54+
// Patch 2
55+
static constexpr double explicitPointsFault1Patch2[18] = { 300, 0, 350, 300, 100, 350, 300, 200, 350,
56+
450, 0, 500, 450, 100, 500, 450, 200, 500 };
57+
static constexpr uint32_t triangleNodeIndexFaultPatch2[12] = { 12,16,15, 12,13,16, 13,14,16, 14,17,16 };
58+
// Patch 3
59+
static constexpr double explicitPointsFault1Patch3[18] = { 450, 0, 500, 450, 100, 500, 450, 200, 500,
60+
500, 0, 550, 500, 100, 550 ,500, 200, 550 };
61+
static constexpr uint32_t triangleNodeIndexFaultPatch3[12] = { 18,22,21, 18,19,22, 19,20,22, 20,23,22 };
62+
// Patch 4
63+
static constexpr double explicitPointsFault1Patch4[18] = { 500, 0, 550, 500, 100, 550 ,500, 200, 550,
64+
600, 0, 650, 600, 100, 650, 600, 200, 650 };
65+
static constexpr uint32_t triangleNodeIndexFaultPatch4[12] = { 24,28,27, 24,25,28, 25,26,28, 26,29,28 };
4466
};
4567
}

test/resqml2_test/FaultSinglePatchTriangulatedSetRepresentationTest.cpp

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,41 +35,42 @@ FaultSinglePatchTriangulatedSetRepresentationTest::FaultSinglePatchTriangulatedS
3535

3636
void FaultSinglePatchTriangulatedSetRepresentationTest::initRepo()
3737
{
38-
FaultInterpretation * interp = repo->getDataObjectByUuid<FaultInterpretation>(FaultInterpretationTest::defaultUuid);
38+
FaultInterpretation* interp = repo->getDataObjectByUuid<FaultInterpretation>(FaultInterpretationTest::defaultUuid);
3939
if (interp == nullptr) {
4040
interp = repo->createPartial<RESQML2_0_1_NS::FaultInterpretation>(FaultInterpretationTest::defaultUuid, "");
4141
}
4242

4343
TriangulatedSetRepresentation* rep = repo->createTriangulatedSetRepresentation(interp, defaultUuid, defaultTitle);
4444
REQUIRE( rep != nullptr );
4545

46-
double nodesFaultSinglePatchTriangulatedSetRepresentation[] = {
47-
150, 0, 200,
48-
150, 100, 200,
49-
150, 200, 200,
50-
250, 0, 300,
51-
250, 100, 300,
52-
250, 200, 300,
53-
300, 0, 350,
54-
300, 100, 350,
55-
300, 200, 350,
56-
450, 0, 500,
57-
450, 100, 500,
58-
450, 200, 500,
59-
500, 0, 550,
60-
500, 100, 550,
61-
500, 200, 550,
62-
600, 0, 650,
63-
600, 100, 650,
64-
600, 200, 650 };
65-
unsigned int triangleNodeIndexFault[60] = {0,4,3, 0,1,4, 1,2,4, 2,5,4,
66-
3,7,6, 3,4,7, 4,5,7, 5,8,7,
67-
6,10,9, 6,7,10, 7,8,10, 8,11,10,
68-
9,13,12, 9,10,13, 10,11,13, 11,14,13,
69-
12,16,15, 12,13,16, 13,14,16, 14,17,16 };
7046
rep->pushBackTrianglePatch(18, nodesFaultSinglePatchTriangulatedSetRepresentation, 20, triangleNodeIndexFault, repo->getHdfProxySet()[0]);
7147
}
7248

7349
void FaultSinglePatchTriangulatedSetRepresentationTest::readRepo()
7450
{
51+
RESQML2_NS::TriangulatedSetRepresentation* rep = repo->getDataObjectByUuid<RESQML2_NS::TriangulatedSetRepresentation>(defaultUuid);
52+
REQUIRE(rep->getSeismicSupportOfPatch(0) == nullptr);
53+
REQUIRE(rep->getPatchCount() == 1);
54+
REQUIRE(rep->getRepresentationSetRepresentationCount() == 0);
55+
REQUIRE(rep->getPropertySet().empty());
56+
REQUIRE(rep->getPointsPropertyCount() == 0);
57+
REQUIRE(rep->getSubRepresentationCount() == 0);
58+
REQUIRE(rep->getValuesPropertyCount() == 0);
59+
REQUIRE(rep->getTimeSeries() == nullptr);
60+
REQUIRE(rep->getTitle() == defaultTitle);
61+
REQUIRE(rep->getUuid() == defaultUuid);
62+
REQUIRE(rep->getTriangleCountOfPatch(0) == 20);
63+
REQUIRE_THROWS(rep->getTriangleCountOfPatch(1) == 20);
64+
REQUIRE(rep->getTriangleCountOfAllPatches() == 20);
65+
REQUIRE(rep->getXyzPointCountOfPatch(0) == 18);
66+
REQUIRE_THROWS(rep->getXyzPointCountOfPatch(1) == 18);
67+
REQUIRE(rep->getXyzPointCountOfAllPatches() == 18);
68+
69+
uint32_t triangleNodeIndexFault2[60];
70+
rep->getTriangleNodeIndicesOfPatch(0, triangleNodeIndexFault2);
71+
REQUIRE(std::equal(begin(triangleNodeIndexFault), end(triangleNodeIndexFault), begin(triangleNodeIndexFault2)));
72+
73+
double nodesFaultSinglePatchTriangulatedSetRepresentation2[54];
74+
rep->getXyzPointsOfPatch(0, nodesFaultSinglePatchTriangulatedSetRepresentation2);
75+
REQUIRE(std::equal(begin(nodesFaultSinglePatchTriangulatedSetRepresentation), end(nodesFaultSinglePatchTriangulatedSetRepresentation), begin(nodesFaultSinglePatchTriangulatedSetRepresentation2)));
7576
}

test/resqml2_test/FaultSinglePatchTriangulatedSetRepresentationTest.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,31 @@ namespace resqml2_test {
3737
protected:
3838
void initRepo();
3939
void readRepo();
40+
41+
private:
42+
static constexpr double nodesFaultSinglePatchTriangulatedSetRepresentation[] = {
43+
150, 0, 200,
44+
150, 100, 200,
45+
150, 200, 200,
46+
250, 0, 300,
47+
250, 100, 300,
48+
250, 200, 300,
49+
300, 0, 350,
50+
300, 100, 350,
51+
300, 200, 350,
52+
450, 0, 500,
53+
450, 100, 500,
54+
450, 200, 500,
55+
500, 0, 550,
56+
500, 100, 550,
57+
500, 200, 550,
58+
600, 0, 650,
59+
600, 100, 650,
60+
600, 200, 650 };
61+
static constexpr uint32_t triangleNodeIndexFault[60] = { 0,4,3, 0,1,4, 1,2,4, 2,5,4,
62+
3,7,6, 3,4,7, 4,5,7, 5,8,7,
63+
6,10,9, 6,7,10, 7,8,10, 8,11,10,
64+
9,13,12, 9,10,13, 10,11,13, 11,14,13,
65+
12,16,15, 12,13,16, 13,14,16, 14,17,16 };
4066
};
4167
}

0 commit comments

Comments
 (0)