annotate variant_effect_predictor/Bio/EnsEMBL/DBFile/FileAdaptor.pm @ 3:d30fa12e4cc5 default tip

Merge heads 2:a5976b2dce6f and 1:09613ce8151e which were created as a result of a recently fixed bug.
author devteam <devteam@galaxyproject.org>
date Mon, 13 Jan 2014 10:38:30 -0500
parents 1f6dce3d34e0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1 =head1 LICENSE
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
2
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
3 Copyright (c) 1999-2012 The European Bioinformatics Institute and
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
4 Genome Research Limited. All rights reserved.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
5
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
6 This software is distributed under a modified Apache license.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
7 For license details, please see
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
8
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
9 http://www.ensembl.org/info/about/code_licence.html
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
10
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
11 =head1 CONTACT
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
12
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
13 Please email comments or questions to the public Ensembl
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
14 developers list at <dev@ensembl.org>.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
15
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
16 Questions may also be sent to the Ensembl help desk at
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
17 <helpdesk@ensembl.org>.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
18
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
19 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
20
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
21 =head1 NAME
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
22
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
23 Bio::EnsEMBL::DBFile::FileAdaptor - Base Adaptor for direct file access
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
24
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
25 =head1 DESCRIPTION
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
26
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
27 Basic wrapper class to provide access to file based data.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
28
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
29 This is primarily aimed at indexed Collection(.col) files which are optimised for Slice
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
30 based queries. Collections store fixed width width/windowed data as BLOBS. This makes
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
31 it possible to seek to the a required location given slice coordinate and read the only
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
32 the required amount of data covering the slice.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
33
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
34 Currently only works as hybrid DBAdaptor e.g. ResultFeatureAdaptor which inherits both from
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
35 here and BaseFeatureAdaptor.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
36
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
37 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
38
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
39
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
40
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
41 package Bio::EnsEMBL::DBFile::FileAdaptor;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
42
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
43 use Bio::EnsEMBL::Utils::Exception qw(throw warning deprecate);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
44 use strict;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
45 use warnings;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
46
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
47
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
48 =head2 get_filehandle
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
49
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
50 Arg[1] : string - filepath
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
51 Arg[2] : HASHREF - Optional params, see open_file
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
52 Example : my $fh = $self->get_filehandle($filepath, 1);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
53 Description: Gets and caches a simple file handle.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
54 Returntype : GLOB/undef - filehandle
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
55 Exceptions : warns if cache entry exists but is not defined
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
56 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
57 Status : at risk
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
58
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
59 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
60
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
61 sub get_filehandle{
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
62 my ($self, $filepath, $params_hash) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
63
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
64 my $file_op = '<';
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
65
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
66 if(exists $params_hash->{-file_operator}){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
67 $file_op = $params_hash->{-file_operator};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
68 }else{
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
69 $params_hash->{-file_operator} = $file_op;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
70 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
71
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
72 if(! exists $self->{file_cache}{$filepath}{filehandle}){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
73 my $fh = $self->Bio::EnsEMBL::DBFile::FileAdaptor::open_file($filepath, $params_hash);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
74
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
75 if(defined $fh){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
76 $self->{file_cache}{$filepath}{filehandle} = $fh;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
77 #$self->initialise_filehandle($filepath) if $self->can('initialise_filehandle');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
78 $self->initialise_filehandle($filepath) if($file_op eq '<');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
79 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
80 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
81 elsif(! defined $self->{file_cache}{$filepath}{filehandle}){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
82 #This maybe one of several read/seek errors which will have already been warned
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
83 warn "Encountered and error with file handle for $filepath\n";
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
84 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
85 #else
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
86 # check against cache file op
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
87 # to make sure we aren't trying to open an already open fh with a different operator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
88
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
89
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
90 return $self->{file_cache}{$filepath}{filehandle};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
91 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
92
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
93
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
94 =head2 open_file
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
95
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
96 Arg[1] : string - filepath
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
97 Arg[2] : HASHREF - Optional params:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
98 -binmode => 0|1, # Boolean i.e. treat file as binary
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
99 -file_operator => '>' # Default is '<'
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
100 #-perms_octal => # Requires FileHandle
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
101 Example : my $fh = $self->open_file($filepath, {-binmode = > 1, -file_operator => '>'});
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
102 Description: Opens a file for reading or writing.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
103 Returntype : GLOB/undef - filehandle
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
104 Exceptions : warns if file open fails
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
105 warns if file operator unsupported
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
106 warns if failed to set binmode
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
107 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
108 Status : at risk
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
109
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
110 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
111
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
112 sub open_file{
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
113 my ($self, $filepath, $params_hash) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
114
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
115 #Validate params_hash?
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
116 #rearrange? Will not warn/throw for invalid keys?
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
117 #perms octal, requires FileHandle? See EFGUtils::open_file
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
118
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
119
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
120
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
121 my $file_op = $params_hash->{-file_operator} || '<';
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
122
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
123 if(($file_op ne '<') &&
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
124 ($file_op ne '>') &&
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
125 ($file_op ne '>>')){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
126 throw("Cannot perform open with unsupported operator:\t${file_op}${filepath}");
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
127 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
128
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
129 my $fh;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
130 my $success = open($fh, "${file_op}${filepath}");
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
131 #$fh will be still be GLOB on fail
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
132
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
133 #These warn instead of throw/die to allow
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
134 #open_file to be used to test a file
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
135 #this prevents throws/die when an attempting to access an absent file (good for webcode)
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
136 #could alternatively change to throw/die and eval where required
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
137 #prevents need to catch everywhere else and potential double reporting of error
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
138
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
139 if(! $success){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
140 #undef $fh;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
141 throw("Failed to open:\t$filepath\n$!\n");
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
142 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
143 elsif($params_hash->{-binmode}){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
144 $success = binmode $fh;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
145
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
146 if(! $success){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
147 throw("Failed to set binmode:\t$filepath\n$!");
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
148 #undef $fh;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
149 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
150 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
151
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
152 return $fh;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
153 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
154
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
155
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
156 =head2 validate_file_length
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
157
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
158 Arg[1] : string - filepath
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
159 Arg[2] : int - expected length in bytes
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
160 Example : $self->validate_file_length($filepath, $expected_length);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
161 Description: Utility method which can be used during file creation
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
162 Returntype : None
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
163 Exceptions : warns if file open fails
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
164 throws if file is not expected length
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
165 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
166 Status : at risk - change to seek to accounts for 'logical characters'
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
167
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
168 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
169
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
170 sub validate_file_length{
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
171 my ($self, $filepath, $expected_length, $binmode) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
172
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
173 #Currently not using cache as we rarely want to
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
174 #use the file handle afterwards
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
175
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
176
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
177 #THIS WAS USING EFGUtils::open_file imported in the Collector::ResultFeature!!!!
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
178 #which is just a sub not a class method, and is in a parallel inheritance path
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
179 #No warnings about redefining method :(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
180 #Force use of FileAdaptor::open_file
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
181
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
182 my $fh = $self->Bio::EnsEMBL::DBFile::FileAdaptor::open_file($filepath, {-binmode => $binmode});
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
183
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
184
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
185 #sysseek always returns length in bytes, change to seek which
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
186 #uses logical characters i.e. actual encoding?
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
187 #Does seek use bytes in binmode and chars in non-binmode?
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
188
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
189 my $seeked_bytes = sysseek($fh, 0, 2);# 2 is SEEK_END
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
190 #There is no systell function. Use sysseek(FH, 0, 1) for that.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
191
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
192 if($seeked_bytes < $expected_length){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
193 throw("File is shorter($seeked_bytes) than expected($expected_length):\t$filepath\n");
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
194 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
195 elsif($seeked_bytes > $expected_length){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
196 throw("File is longer($seeked_bytes) than expected($expected_length):\t$filepath\n");
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
197 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
198
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
199 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
200 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
201
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
202
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
203
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
204
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
205
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
206 ### STUBB/TEMPLATE METHODS ###
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
207 #
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
208 # If required hese should be over-ridden in the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
209 # descendant FileAdaptor e.g. CollectionAdaptor
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
210 # Listed here rather for visibility (rather than
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
211 # using 'can')
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
212
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
213
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
214 sub initialise_filehandle{
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
215 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
216 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
217
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
218
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
219
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
220 1;