vchain_client 1.0.21 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/vchain_client.rb +244 -240
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65340391974700636c2d48e309226cae1e472797
|
4
|
+
data.tar.gz: 132f978b2d7e25377f9efdbc108e4f744a0d74a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 110cf09f708a3b23d8de059a9cbb9d14fbfbc48f7dbd4ef7a1f1a3097cb42345fc2b6ed62116fecd60553ad1f2e9a9779914991f0a9bc6602469a6205a4683f1
|
7
|
+
data.tar.gz: 959022c40a2975fb038ac62599bcdb320d4101d318fbe82565e3d470770171e8905fd9603356cd6836879b2bd8b717dc09ed90735d1d382967c9bff696bba78c
|
data/lib/vchain_client.rb
CHANGED
@@ -37,10 +37,12 @@ module VChainClient
|
|
37
37
|
|
38
38
|
def hash(arr)
|
39
39
|
arr.each { |k, v|
|
40
|
-
if k != "
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
if k != "names_parts"
|
41
|
+
if k != "surname" && k != "given_names"
|
42
|
+
arr[k] = Digest::SHA512.hexdigest(v.downcase)
|
43
|
+
else
|
44
|
+
arr[k] = Digest::SHA512.hexdigest(v)
|
45
|
+
end
|
44
46
|
end
|
45
47
|
}
|
46
48
|
end
|
@@ -49,10 +51,12 @@ module VChainClient
|
|
49
51
|
output = {}
|
50
52
|
|
51
53
|
arr.each { |k, v|
|
52
|
-
if k != "
|
53
|
-
|
54
|
-
|
55
|
-
|
54
|
+
if k != "names_parts"
|
55
|
+
if k != "doc_hash"
|
56
|
+
output[Digest::SHA512.hexdigest(k)] = Digest::SHA512.hexdigest(v)
|
57
|
+
else
|
58
|
+
output[k] = Digest::SHA512.hexdigest(v)
|
59
|
+
end
|
56
60
|
end
|
57
61
|
}
|
58
62
|
|
@@ -220,7 +224,7 @@ module VChainClient
|
|
220
224
|
def add_data_point(point_type, input, weight = 1)
|
221
225
|
|
222
226
|
client_id = @config["client_id"]
|
223
|
-
api_url = @config["api"]["url"] + "v0.
|
227
|
+
api_url = @config["api"]["url"] + "v0.2/addDataPoint/"
|
224
228
|
|
225
229
|
time = Time.now.getutc
|
226
230
|
timestamp = time.to_i
|
@@ -439,7 +443,7 @@ module VChainClient
|
|
439
443
|
|
440
444
|
client_id = @config["client_id"]
|
441
445
|
|
442
|
-
api_url = @config["api"]["url"] + "v0.
|
446
|
+
api_url = @config["api"]["url"] + "v0.2/check/";
|
443
447
|
|
444
448
|
document = input
|
445
449
|
|
@@ -455,10 +459,14 @@ module VChainClient
|
|
455
459
|
|
456
460
|
document = self.cut(document)
|
457
461
|
|
462
|
+
names_index = {}
|
463
|
+
|
458
464
|
if document["type"] == FIELD_TYPE_TRAVEL_DOCUMENT_HASHED
|
459
465
|
document["names"] = []
|
460
466
|
names.each { |name|
|
461
|
-
|
467
|
+
name_hash = Digest::SHA512.hexdigest(name.downcase)
|
468
|
+
names_index[name_hash] = name
|
469
|
+
document["names"].push(name_hash)
|
462
470
|
}
|
463
471
|
end
|
464
472
|
|
@@ -528,38 +536,6 @@ module VChainClient
|
|
528
536
|
|
529
537
|
# success result
|
530
538
|
|
531
|
-
if sent_document.key?("names")
|
532
|
-
|
533
|
-
real_surname = ""
|
534
|
-
|
535
|
-
real_given_name = ""
|
536
|
-
|
537
|
-
if res.key?("names") && res["names"].is_a?(Hash)
|
538
|
-
|
539
|
-
if res["names"].key?("given_names")
|
540
|
-
sep = "";
|
541
|
-
res["names"]["given_names"].each { |found_given_name|
|
542
|
-
real_given_name += sep + found_given_name
|
543
|
-
sep = " "
|
544
|
-
}
|
545
|
-
end
|
546
|
-
|
547
|
-
if res["names"].key?("surname")
|
548
|
-
sep = "";
|
549
|
-
res["names"]["surname"].each { |found_surname|
|
550
|
-
real_surname += sep + found_surname
|
551
|
-
sep = " "
|
552
|
-
}
|
553
|
-
end
|
554
|
-
|
555
|
-
end
|
556
|
-
|
557
|
-
sent_document["given_names"] = Digest::SHA512.hexdigest(real_given_name)
|
558
|
-
sent_document["surname"] = Digest::SHA512.hexdigest(real_surname)
|
559
|
-
|
560
|
-
sent_document.delete("names")
|
561
|
-
end
|
562
|
-
|
563
539
|
validated_data_points = self.validate_data_points(res["data_points"], res["docs"])
|
564
540
|
|
565
541
|
if validated_data_points.length == 0
|
@@ -573,289 +549,317 @@ module VChainClient
|
|
573
549
|
}
|
574
550
|
|
575
551
|
return {
|
576
|
-
"status"
|
577
|
-
"validated"
|
552
|
+
"status" => "success",
|
553
|
+
"validated" => result,
|
554
|
+
"hashed_input" => sent_document
|
578
555
|
}
|
579
556
|
|
580
557
|
end
|
581
558
|
|
559
|
+
#
|
582
560
|
# analyse
|
561
|
+
#
|
583
562
|
|
584
|
-
|
585
|
-
|
586
|
-
res_docs_index = {}
|
587
|
-
|
588
|
-
# cut and index
|
589
|
-
res["docs"].each { |res_doc|
|
590
|
-
|
591
|
-
full_doc_hash = self.get_doc_hash(res_doc)
|
592
|
-
|
593
|
-
play_doc = {}
|
594
|
-
res_doc.each { |field, value|
|
595
|
-
if sent_document.key?(field)
|
596
|
-
play_doc[field] = value
|
597
|
-
end
|
598
|
-
}
|
599
|
-
|
600
|
-
res_doc_credentials_hash = self.get_credentials_hash(play_doc)
|
601
|
-
|
602
|
-
if !res_docs_index.key?(res_doc_credentials_hash)
|
603
|
-
res_docs_index[res_doc_credentials_hash] = []
|
604
|
-
end
|
605
|
-
|
606
|
-
play_doc["doc_hash"] = self.get_doc_hash(play_doc)
|
607
|
-
|
608
|
-
play_doc["full_doc_hash"] = full_doc_hash
|
609
|
-
|
610
|
-
res_docs_index[res_doc_credentials_hash].push(play_doc)
|
611
|
-
|
612
|
-
new_res_docs.push(play_doc)
|
613
|
-
}
|
614
|
-
|
615
|
-
res["docs"] = new_res_docs
|
616
|
-
|
563
|
+
sent_type_credentials_fields = self.get_credentials_fields(sent_document["type"])
|
617
564
|
|
618
|
-
sent_doc_hash = self.get_doc_hash(sent_document)
|
619
565
|
|
620
|
-
|
566
|
+
# 1. cut non-input fields, rebuild doc_hashes
|
567
|
+
# 2. build vectors out of cut documents
|
621
568
|
|
622
|
-
|
569
|
+
cut_res_docs = []
|
623
570
|
|
624
|
-
|
571
|
+
vectors = []
|
625
572
|
|
626
|
-
|
627
|
-
|
628
|
-
if validated_data_points.key?(hashed_sent_doc_hash)
|
629
|
-
|
630
|
-
# exact match found by doc_hash
|
631
|
-
|
632
|
-
result = {}
|
633
|
-
|
634
|
-
exact_match = validated_data_points[hashed_sent_doc_hash]
|
635
|
-
|
636
|
-
sent_document.each { |field, value|
|
637
|
-
|
638
|
-
hashed_field = Digest::SHA512.hexdigest(field)
|
573
|
+
res["docs"].each { |res_doc|
|
639
574
|
|
640
|
-
|
575
|
+
cut_doc = {}
|
576
|
+
vector = {}
|
641
577
|
|
642
|
-
|
578
|
+
names_parts = {}
|
579
|
+
if res_doc.key?("names_parts")
|
580
|
+
names_parts = res_doc["names_parts"]
|
643
581
|
|
644
|
-
|
582
|
+
res_doc.delete("names_parts")
|
583
|
+
end
|
645
584
|
|
646
|
-
|
585
|
+
full_doc_hash = self.get_doc_hash(res_doc)
|
647
586
|
|
587
|
+
res_doc.each { |res_doc_field, res_doc_value|
|
588
|
+
if sent_document.key?(res_doc_field) || sent_type_credentials_fields.include?(res_doc_field)
|
589
|
+
cut_doc[res_doc_field] = res_doc_value
|
590
|
+
|
591
|
+
vector[Digest::SHA512.hexdigest(res_doc_field)] = [res_doc_value, res_doc_field, 0]
|
648
592
|
end
|
649
|
-
|
650
|
-
}
|
651
|
-
|
652
|
-
return {
|
653
|
-
"status" => "success",
|
654
|
-
"validated" => result
|
655
593
|
}
|
656
594
|
|
657
|
-
|
658
|
-
|
659
|
-
# search by credentials_hash
|
660
|
-
|
661
|
-
found_docs = []
|
662
|
-
if res_docs_index.key?(sent_credentials_hash)
|
663
|
-
found_docs = res_docs_index[sent_credentials_hash]
|
664
|
-
end
|
665
|
-
|
666
|
-
if found_docs.length > 0
|
595
|
+
cut_doc["doc_hash"] = self.get_doc_hash(cut_doc)
|
667
596
|
|
668
|
-
|
597
|
+
cut_doc["full_doc_hash"] = full_doc_hash
|
669
598
|
|
670
|
-
|
599
|
+
hashed_full_doc_hash = Digest::SHA512.hexdigest(full_doc_hash);
|
671
600
|
|
672
|
-
|
601
|
+
if validated_data_points.key?(hashed_full_doc_hash)
|
602
|
+
data_points = validated_data_points[hashed_full_doc_hash]
|
673
603
|
|
674
|
-
|
604
|
+
data_points.each { |data_point_field, data_point_value|
|
605
|
+
if vector.key?(data_point_field)
|
606
|
+
vector[data_point_field][2] += data_point_value
|
607
|
+
end
|
608
|
+
}
|
609
|
+
end
|
675
610
|
|
676
|
-
|
611
|
+
if !names_parts.empty?
|
612
|
+
cut_doc["names_parts"] = names_parts
|
613
|
+
vector["names_parts"] = names_parts
|
614
|
+
end
|
677
615
|
|
678
|
-
|
616
|
+
vectors.push(vector)
|
679
617
|
|
680
|
-
|
681
|
-
|
618
|
+
cut_res_docs.push(cut_doc)
|
619
|
+
}
|
682
620
|
|
683
|
-
|
621
|
+
res["docs"] = cut_res_docs
|
684
622
|
|
685
|
-
# fill credential fields
|
686
|
-
cred_fields.each { |cred_field|
|
687
623
|
|
688
|
-
|
624
|
+
# 3. combine vectors part 1 - marking => absorb smaller, merge equal
|
625
|
+
for i in 0..(vectors.length - 1)
|
689
626
|
|
690
|
-
|
691
|
-
|
692
|
-
|
627
|
+
vector_i = vectors[i]
|
628
|
+
|
629
|
+
for j in i+1..(vectors.length - 1)
|
693
630
|
|
694
|
-
|
695
|
-
|
696
|
-
|
631
|
+
if j >= vectors.length
|
632
|
+
break
|
633
|
+
end
|
697
634
|
|
698
|
-
|
635
|
+
vector_j = vectors[j]
|
699
636
|
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
if !cred_fields.include?(field) && field != "doc_hash"
|
637
|
+
i_is_less_j = false
|
638
|
+
j_is_less_i = false
|
704
639
|
|
705
|
-
|
706
|
-
|
707
|
-
if !non_cred_fields_index.key?(field)
|
708
|
-
non_cred_fields_index[field] = {}
|
709
|
-
end
|
640
|
+
need_to_combine = true
|
710
641
|
|
711
|
-
|
712
|
-
|
642
|
+
vector_i.each { |vector_i_hashed_field, vector_i_values|
|
643
|
+
if vector_i_hashed_field != "names_parts" && vector_i_hashed_field != "resolutions"
|
644
|
+
if !vector_j.key?(vector_i_hashed_field)
|
645
|
+
j_is_less_i = true
|
646
|
+
else
|
647
|
+
vector_j_values = vector_j[vector_i_hashed_field]
|
648
|
+
if vector_i_values[0] != vector_j_values[0]
|
649
|
+
need_to_combine = false
|
650
|
+
break
|
713
651
|
end
|
652
|
+
end
|
653
|
+
end
|
654
|
+
}
|
714
655
|
|
715
|
-
|
716
|
-
|
656
|
+
vector_j.each { |vector_j_hashed_field, vector_j_values|
|
657
|
+
if vector_j_hashed_field != "names_parts" && vector_j_hashed_field != "resolutions"
|
658
|
+
if !vector_i.key?(vector_j_hashed_field)
|
659
|
+
i_is_less_j = true
|
660
|
+
else
|
661
|
+
vector_i_values = vector_i[vector_j_hashed_field]
|
662
|
+
if vector_j_values[0] != vector_i_values[0]
|
663
|
+
need_to_combine = false
|
664
|
+
break
|
717
665
|
end
|
718
|
-
|
719
666
|
end
|
720
|
-
|
721
|
-
}
|
722
|
-
|
667
|
+
end
|
723
668
|
}
|
724
669
|
|
725
|
-
|
726
|
-
|
727
|
-
|
670
|
+
if need_to_combine
|
671
|
+
if i_is_less_j && j_is_less_i
|
672
|
+
# differs, no need to combine
|
728
673
|
|
729
|
-
|
674
|
+
elsif i_is_less_j && !j_is_less_i
|
675
|
+
# combine i to j
|
676
|
+
if !vectors[i].key?("resolutions")
|
677
|
+
vectors[i]["resolutions"] = []
|
678
|
+
end
|
679
|
+
if !vectors[j].key?("resolutions")
|
680
|
+
vectors[j]["resolutions"] = []
|
681
|
+
end
|
682
|
+
vectors[i]["resolutions"].push(["combine_to", j])
|
683
|
+
vectors[j]["resolutions"].push(["absorb", i])
|
730
684
|
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
685
|
+
elsif !i_is_less_j && j_is_less_i
|
686
|
+
# combine j to i
|
687
|
+
if !vectors[i].key?("resolutions")
|
688
|
+
vectors[i]["resolutions"] = []
|
689
|
+
end
|
690
|
+
if !vectors[j].key?("resolutions")
|
691
|
+
vectors[j]["resolutions"] = []
|
692
|
+
end
|
693
|
+
vectors[j]["resolutions"].push(["combine_to", i])
|
694
|
+
vectors[i]["resolutions"].push(["absorb", j])
|
738
695
|
|
739
|
-
|
740
|
-
|
696
|
+
else
|
697
|
+
# equals, combine j to i and delete j
|
698
|
+
if !vectors[i].key?("resolutions")
|
699
|
+
vectors[i]["resolutions"] = []
|
741
700
|
end
|
701
|
+
if !vectors[j].key?("resolutions")
|
702
|
+
vectors[j]["resolutions"] = []
|
703
|
+
end
|
704
|
+
vectors[j]["resolutions"].push(["combine_to", i])
|
705
|
+
vectors[i]["resolutions"].push(["absorb", j])
|
742
706
|
|
743
707
|
end
|
708
|
+
end
|
709
|
+
end
|
710
|
+
end
|
744
711
|
|
745
|
-
|
746
|
-
|
747
|
-
return {
|
748
|
-
"status" => "success",
|
749
|
-
"possible_mistakes" => possible_mistakes,
|
750
|
-
"validated" => result
|
751
|
-
}
|
752
|
-
|
753
|
-
else
|
754
|
-
|
755
|
-
# search for possible errors in credentials
|
712
|
+
# 4. combine vectors part 2 - resolutions execution => absorb smaller, merge equal
|
713
|
+
vectors_to_remove = []
|
756
714
|
|
757
|
-
|
715
|
+
for i in 0..(vectors.length-1)
|
758
716
|
|
759
|
-
|
760
|
-
possible_mistakes = []
|
717
|
+
vector_i = vectors[i]
|
761
718
|
|
762
|
-
|
719
|
+
if vector_i.key?("resolutions")
|
763
720
|
|
764
|
-
|
721
|
+
need_to_delete = false
|
765
722
|
|
766
|
-
|
723
|
+
vector_i["resolutions"].each { |resolution|
|
724
|
+
|
725
|
+
resolution_type = resolution[0]
|
767
726
|
|
768
|
-
|
727
|
+
if resolution_type == "combine_to"
|
728
|
+
|
729
|
+
vector_i["resolutions"].each { |resolution_b|
|
730
|
+
|
731
|
+
if resolution_b[0] == "absorb"
|
732
|
+
if !vectors[resolution[1]].key?("resolutions")
|
733
|
+
vectors[resolution[1]]["resolutions"] = []
|
734
|
+
end
|
769
735
|
|
770
|
-
|
736
|
+
# check for dublicates
|
737
|
+
need_to_add = true
|
771
738
|
|
772
|
-
|
773
|
-
|
774
|
-
|
739
|
+
vectors[resolution[1]]["resolutions"].each { |resolution_c|
|
740
|
+
if resolution_c[0] == resolution_b[0] && resolution_c[1] == resolution_b[1]
|
741
|
+
need_to_add = false
|
742
|
+
break
|
743
|
+
end
|
744
|
+
}
|
775
745
|
|
776
|
-
|
777
|
-
|
778
|
-
|
746
|
+
if need_to_add
|
747
|
+
vectors[resolution[1]]["resolutions"].push(resolution_b)
|
748
|
+
end
|
779
749
|
end
|
780
750
|
}
|
781
751
|
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
matching_exact_match = validated_data_points[matching_doc_hash]
|
787
|
-
|
788
|
-
lookup_set.each { |lookup_field|
|
752
|
+
need_to_delete = true
|
753
|
+
end
|
754
|
+
}
|
789
755
|
|
790
|
-
|
756
|
+
if need_to_delete
|
757
|
+
vectors_to_remove.push(i)
|
758
|
+
end
|
759
|
+
end
|
760
|
+
end
|
791
761
|
|
792
|
-
|
793
|
-
}
|
762
|
+
for i in 0..(vectors.length - 1)
|
794
763
|
|
795
|
-
|
796
|
-
|
797
|
-
if !lookup_set.include?(field) && field != "doc_hash"
|
764
|
+
vector_i = vectors[i]
|
798
765
|
|
799
|
-
|
800
|
-
|
801
|
-
if !other_fields_index.key?(field)
|
802
|
-
other_fields_index[field] = {}
|
803
|
-
end
|
766
|
+
if vector_i.key?("resolutions")
|
767
|
+
if !vectors_to_remove.include?(i)
|
804
768
|
|
805
|
-
|
806
|
-
other_fields_index[field][value] = 0
|
807
|
-
end
|
769
|
+
vector_i["resolutions"].each { |resolution|
|
808
770
|
|
809
|
-
|
810
|
-
|
811
|
-
end
|
771
|
+
if resolution[0] == "absorb"
|
772
|
+
vector_j = vectors[resolution[1]]
|
812
773
|
|
774
|
+
vector_j.each { |vector_j_hashed_field, vector_j_values|
|
775
|
+
if vector_j_hashed_field != "names_parts" && vector_j_hashed_field != "resolutions"
|
776
|
+
vectors[i][vector_j_hashed_field][2] += vector_j_values[2]
|
813
777
|
end
|
814
|
-
|
815
778
|
}
|
816
|
-
|
817
|
-
lookup_set_match_found = true
|
818
779
|
end
|
780
|
+
|
819
781
|
}
|
820
782
|
|
821
|
-
|
822
|
-
break
|
823
|
-
end
|
783
|
+
vectors[i].delete("resolutions")
|
824
784
|
|
825
|
-
|
785
|
+
end
|
786
|
+
end
|
787
|
+
end
|
826
788
|
|
827
|
-
|
789
|
+
# remove marked vectors
|
790
|
+
vectors_removed_number = 0
|
791
|
+
vectors_to_remove.each { |index|
|
792
|
+
vectors.delete_at(index - vectors_removed_number)
|
793
|
+
vectors_removed_number += 1
|
794
|
+
}
|
828
795
|
|
829
|
-
|
796
|
+
# prepare for output
|
830
797
|
|
831
|
-
|
798
|
+
vectors_fliped = []
|
832
799
|
|
833
|
-
|
834
|
-
if value == sent_document[field]
|
835
|
-
result[field] = validated_count
|
836
|
-
else
|
837
|
-
possible_mistakes.push(field)
|
838
|
-
end
|
839
|
-
}
|
800
|
+
for i in 0..(vectors.length - 1)
|
840
801
|
|
841
|
-
|
842
|
-
possible_mistakes.push(field)
|
843
|
-
end
|
802
|
+
vector_fliped = {}
|
844
803
|
|
845
|
-
|
804
|
+
vectors[i].each { |hashed_vector_field, vector_values|
|
846
805
|
|
847
|
-
|
806
|
+
if hashed_vector_field != "names_parts"
|
807
|
+
val = "same"
|
808
|
+
if sent_document[vector_values[1]] != vector_values[0]
|
809
|
+
val = "different"
|
810
|
+
end
|
811
|
+
vector_fliped[vector_values[1]] = [val, vector_values[2]]
|
812
|
+
else
|
813
|
+
vector_fliped[hashed_vector_field] = vector_values
|
814
|
+
end
|
815
|
+
}
|
848
816
|
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
"
|
853
|
-
|
817
|
+
vector_raw_surname = ""
|
818
|
+
if vector_fliped.key?("names_parts")
|
819
|
+
if vector_fliped["names_parts"].key?("surname")
|
820
|
+
sep = ""
|
821
|
+
vector_fliped["names_parts"]["surname"].each { |surname_part|
|
822
|
+
vector_raw_surname += sep + names_index[surname_part]
|
823
|
+
sep = " "
|
824
|
+
}
|
825
|
+
else
|
826
|
+
vector_raw_surname = "different"
|
827
|
+
end
|
828
|
+
else
|
829
|
+
vector_raw_surname = "different"
|
830
|
+
end
|
854
831
|
|
832
|
+
vector_raw_given_names = ""
|
833
|
+
if vector_fliped.key?("names_parts")
|
834
|
+
if vector_fliped["names_parts"].key?("given_names")
|
835
|
+
sep = ""
|
836
|
+
vector_fliped["names_parts"]["given_names"].each { |given_names_part|
|
837
|
+
vector_raw_given_names += sep + names_index[given_names_part]
|
838
|
+
sep = " "
|
839
|
+
}
|
840
|
+
else
|
841
|
+
vector_raw_given_names = "different"
|
842
|
+
end
|
843
|
+
else
|
844
|
+
vector_raw_given_names = "different"
|
855
845
|
end
|
856
846
|
|
847
|
+
vector_fliped["surname"] = [vector_raw_surname, vector_fliped["surname"][1]]
|
848
|
+
vector_fliped["given_names"] = [vector_raw_given_names, vector_fliped["given_names"][1]]
|
849
|
+
|
850
|
+
vector_fliped.delete("names_parts")
|
851
|
+
|
852
|
+
vectors_fliped.push(vector_fliped)
|
853
|
+
|
857
854
|
end
|
858
855
|
|
856
|
+
# result output
|
857
|
+
|
858
|
+
return {
|
859
|
+
"status" => "success",
|
860
|
+
"vectors" => vectors_fliped
|
861
|
+
}
|
862
|
+
|
859
863
|
end
|
860
864
|
end
|
861
865
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vchain_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aleksandr Gorelik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: log4r
|