line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=encoding utf-8 |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=head1 NAME |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
Business::cXML::ItemIn - cXML line item, from seller to buyer |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 SYNOPSIS |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
use Business::cXML::ItemIn; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 DESCRIPTION |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
Object representation of cXML C<ItemIn>. |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 METHODS |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
See L<Business::cXML::Object/COMMON METHODS>. |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 PROPERTY METHODS |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
See L<Business::cXML::Object/PROPERTY METHODS> for how the following operate. |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=over |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=cut |
26
|
|
|
|
|
|
|
|
27
|
2
|
|
|
2
|
|
928
|
use 5.014; |
|
2
|
|
|
|
|
6
|
|
28
|
2
|
|
|
2
|
|
10
|
use strict; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
58
|
|
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
use base qw(Business::cXML::Object); |
31
|
2
|
|
|
2
|
|
8
|
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
127
|
|
32
|
|
|
|
|
|
|
use constant NODENAME => 'ItemIn'; |
33
|
2
|
|
|
2
|
|
12
|
use constant PROPERTIES => ( |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
178
|
|
34
|
2
|
|
|
|
|
151
|
sku => '', |
35
|
|
|
|
|
|
|
qty => 0, |
36
|
|
|
|
|
|
|
qty_open => undef, |
37
|
|
|
|
|
|
|
qty_promised => undef, |
38
|
|
|
|
|
|
|
i => undef, |
39
|
|
|
|
|
|
|
i_parent => undef, |
40
|
|
|
|
|
|
|
is_group => undef, |
41
|
|
|
|
|
|
|
is_parent_group => undef, |
42
|
|
|
|
|
|
|
is_service => undef, |
43
|
|
|
|
|
|
|
price => undef, |
44
|
|
|
|
|
|
|
descriptions => [], |
45
|
|
|
|
|
|
|
unit => 'EA', |
46
|
|
|
|
|
|
|
class_domain => 'UNSPSC', |
47
|
|
|
|
|
|
|
class => '', |
48
|
|
|
|
|
|
|
manu_part => undef, |
49
|
|
|
|
|
|
|
manu_name => undef, |
50
|
|
|
|
|
|
|
manu_lang => 'en-US', |
51
|
|
|
|
|
|
|
delay => undef, |
52
|
|
|
|
|
|
|
chars => [], |
53
|
|
|
|
|
|
|
url => undef, |
54
|
|
|
|
|
|
|
shipping => undef, |
55
|
|
|
|
|
|
|
tax => undef, |
56
|
|
|
|
|
|
|
); |
57
|
2
|
|
|
2
|
|
12
|
use constant OBJ_PROPERTIES => ( |
|
2
|
|
|
|
|
4
|
|
58
|
2
|
|
|
|
|
105
|
price => [ 'Business::cXML::Amount', 'UnitPrice' ], |
59
|
|
|
|
|
|
|
descriptions => 'Business::cXML::Description', |
60
|
|
|
|
|
|
|
chars => 'Business::cXML::Characteristic', |
61
|
|
|
|
|
|
|
shipping => [ 'Business::cXML::Amount', 'Shipping' ], |
62
|
|
|
|
|
|
|
tax => [ 'Business::cXML::Amount', 'Tax' ], |
63
|
|
|
|
|
|
|
); |
64
|
2
|
|
|
2
|
|
16
|
|
|
2
|
|
|
|
|
5
|
|
65
|
|
|
|
|
|
|
use Business::cXML::Amount; |
66
|
2
|
|
|
2
|
|
13
|
use XML::LibXML::Ferry; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
51
|
|
67
|
2
|
|
|
2
|
|
11
|
|
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
1234
|
|
68
|
|
|
|
|
|
|
my ($self, $val) = @_; |
69
|
|
|
|
|
|
|
return 1 if $val =~ /^(composite|groupLevel|service)$/; |
70
|
6
|
|
|
6
|
|
1824
|
return 0; # DTD guarantees: item|itemLevel|material |
71
|
6
|
100
|
|
|
|
27
|
} |
72
|
3
|
|
|
|
|
7
|
|
73
|
|
|
|
|
|
|
my ($self, $el) = @_; |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
$el->ferry($self, { |
76
|
5
|
|
|
5
|
1
|
11
|
quantity => 'qty', |
77
|
|
|
|
|
|
|
openQuantity => 'qty_open', |
78
|
5
|
|
|
|
|
162
|
promisedQuantity => 'qty_promised', |
79
|
|
|
|
|
|
|
lineNumber => 'i', |
80
|
|
|
|
|
|
|
parentLineNumber => 'i_parent', |
81
|
|
|
|
|
|
|
itemType => [ 'is_group', \&_bool ], |
82
|
|
|
|
|
|
|
compositeItemType => [ 'is_parent_group', \&_bool ], |
83
|
|
|
|
|
|
|
itemClassification => [ 'is_service', \&_bool ], |
84
|
|
|
|
|
|
|
itemCategory => '__UNIMPLEMENTED', |
85
|
|
|
|
|
|
|
ItemID => { |
86
|
|
|
|
|
|
|
# UNIMPLEMENTED SupplierPartID.revisionID |
87
|
|
|
|
|
|
|
SupplierPartID => 'sku', |
88
|
|
|
|
|
|
|
SupplierPartAuxiliaryID => '__UNIMPLEMENTED', |
89
|
|
|
|
|
|
|
BuyerPartID => '__UNIMPLEMENTED', |
90
|
|
|
|
|
|
|
IdReference => '__UNIMPLEMENTED', |
91
|
|
|
|
|
|
|
}, |
92
|
|
|
|
|
|
|
Path => '__UNIMPLEMENTED', |
93
|
|
|
|
|
|
|
ItemDetail => { |
94
|
|
|
|
|
|
|
UnitPrice => [ 'price', 'Business::cXML::Amount' ], |
95
|
|
|
|
|
|
|
Description => [ 'descriptions', 'Business::cXML::Description' ], |
96
|
|
|
|
|
|
|
OverallLimit => '__UNIMPLEMENTED', |
97
|
|
|
|
|
|
|
ExpectedLimit => '__UNIMPLEMENTED', |
98
|
|
|
|
|
|
|
UnitOfMeasure => 'unit', |
99
|
|
|
|
|
|
|
PriceBasisQuantity => '__UNIMPLEMENTED', |
100
|
|
|
|
|
|
|
Classification => { |
101
|
|
|
|
|
|
|
# We only keep the last one that will be processed |
102
|
|
|
|
|
|
|
domain => 'class_domain', |
103
|
|
|
|
|
|
|
code => '__UNIMPLEMENTED', |
104
|
|
|
|
|
|
|
__text => 'class', |
105
|
|
|
|
|
|
|
}, |
106
|
|
|
|
|
|
|
ManufacturerPartID => 'manu_part', |
107
|
|
|
|
|
|
|
ManufacturerName => { |
108
|
|
|
|
|
|
|
'xml:lang' => 'manu_lang', |
109
|
|
|
|
|
|
|
__text => 'manu_name', |
110
|
|
|
|
|
|
|
}, |
111
|
|
|
|
|
|
|
# URL is implicit |
112
|
|
|
|
|
|
|
LeadTime => 'delay', |
113
|
|
|
|
|
|
|
Dimension => '__UNIMPLEMENTED', |
114
|
|
|
|
|
|
|
ItemDetailIndustry => { |
115
|
|
|
|
|
|
|
# Attribute isConfigurableMaterial is implied from the presence of characteristics |
116
|
|
|
|
|
|
|
ItemDetailRetail => { |
117
|
|
|
|
|
|
|
EANID => '__OBSOLETE', |
118
|
|
|
|
|
|
|
EuropeanWasteCatalogID => '__UNIMPLEMENTED', |
119
|
|
|
|
|
|
|
Characteristic => [ 'chars', 'Business::cXML::Characteristic' ], |
120
|
|
|
|
|
|
|
}, |
121
|
|
|
|
|
|
|
}, |
122
|
|
|
|
|
|
|
AttachmentReference => '__UNIMPLEMENTED', |
123
|
|
|
|
|
|
|
PlannedAcceptanceDays => '__UNIMPLEMENTED', |
124
|
|
|
|
|
|
|
}, |
125
|
|
|
|
|
|
|
SupplierID => '__UNIMPLEMENTED', |
126
|
|
|
|
|
|
|
SupplierList => '__UNIMPLEMENTED', |
127
|
|
|
|
|
|
|
ShipTo => '__UNIMPLEMENTED', |
128
|
|
|
|
|
|
|
Shipping => [ 'shipping', 'Business::cXML::Amount' ], |
129
|
|
|
|
|
|
|
Tax => [ 'tax', 'Business::cXML::Amount' ], |
130
|
|
|
|
|
|
|
SpendDetail => '__UNIMPLEMENTED', |
131
|
|
|
|
|
|
|
Distribution => '__UNIMPLEMENTED', |
132
|
|
|
|
|
|
|
Contact => '__UNIMPLEMENTED', |
133
|
|
|
|
|
|
|
Comments => '__UNIMPLEMENTED', |
134
|
|
|
|
|
|
|
ScheduleLine => '__UNIMPLEMENTED', |
135
|
|
|
|
|
|
|
BillTo => '__UNIMPLEMENTED', |
136
|
|
|
|
|
|
|
Batch => '__UNIMPLEMENTED', |
137
|
|
|
|
|
|
|
DateInfo => '__UNIMPLEMENTED', |
138
|
|
|
|
|
|
|
}); |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
my ($self, $doc) = @_; |
142
|
|
|
|
|
|
|
my $node = $doc->create($self->{_nodeName}, undef, |
143
|
|
|
|
|
|
|
quantity => $self->{qty}, |
144
|
|
|
|
|
|
|
openQuantity => $self->{qty_open}, |
145
|
11
|
|
|
11
|
1
|
95
|
promisedQuantity => $self->{qty_promised}, |
146
|
|
|
|
|
|
|
lineNumber => $self->{i}, |
147
|
|
|
|
|
|
|
parentLineNumber => $self->{i_parent}, |
148
|
|
|
|
|
|
|
); |
149
|
|
|
|
|
|
|
$node->{itemType} = ($self->is_group ? 'composite' : 'item' ) if defined $self->{is_group}; |
150
|
|
|
|
|
|
|
$node->{compositeItemType} = ($self->is_parent_group ? 'groupLevel' : 'itemLevel') if defined $self->{is_parent_group}; |
151
|
|
|
|
|
|
|
$node->{itemClassification} = ($self->is_service ? 'service' : 'material' ) if defined $self->{is_service}; |
152
|
11
|
|
|
|
|
35
|
|
153
|
11
|
100
|
|
|
|
453
|
$node->add('ItemID')->add('SupplierPartID', $self->{sku}); |
|
|
100
|
|
|
|
|
|
154
|
11
|
100
|
|
|
|
163
|
|
|
|
100
|
|
|
|
|
|
155
|
11
|
100
|
|
|
|
93
|
my $idet = $node->add('ItemDetail'); |
|
|
100
|
|
|
|
|
|
156
|
|
|
|
|
|
|
$self->price({}) unless defined $self->{price}; |
157
|
11
|
|
|
|
|
93
|
$idet->add($self->{price}->to_node($doc)); |
158
|
|
|
|
|
|
|
$self->descriptions({}) unless scalar(@{ $self->{descriptions} } > 0); |
159
|
11
|
|
|
|
|
601
|
$idet->add($_->to_node($doc)) foreach (@{ $self->{descriptions} }); |
160
|
11
|
100
|
|
|
|
344
|
$idet->add('UnitOfMeasure', $self->{unit}); |
161
|
11
|
|
|
|
|
26
|
$idet->add('Classification', $self->{class}, domain => $self->{class_domain}); |
162
|
11
|
100
|
|
|
|
167
|
$idet->add('ManufacturerPartID', $self->{manu_part}) if defined $self->{manu_part}; |
|
11
|
|
|
|
|
113
|
|
163
|
11
|
|
|
|
|
17
|
$idet->add('ManufacturerName', $self->{manu_name}, 'xml:lang' => $self->{manu_lang}) if defined $self->{manu_name}; |
|
11
|
|
|
|
|
44
|
|
164
|
11
|
|
|
|
|
303
|
$idet->add('URL', $self->{url}) if defined $self->{url}; |
165
|
11
|
|
|
|
|
362
|
$idet->add('LeadTime', $self->{delay}) if defined $self->{delay}; |
166
|
11
|
100
|
|
|
|
526
|
if (scalar(@{ $self->{chars} }) > 0) { |
167
|
11
|
100
|
|
|
|
57
|
my $ret = $idet->add('ItemDetailIndustry', undef, isConfigurableMaterial => 'yes')->add('ItemDetailRetail'); |
168
|
11
|
100
|
|
|
|
78
|
$ret->add($_->to_node($doc)) foreach (@{ $self->{chars} }); |
169
|
11
|
100
|
|
|
|
54
|
}; |
170
|
11
|
100
|
|
|
|
48
|
|
|
11
|
|
|
|
|
26
|
|
171
|
1
|
|
|
|
|
4
|
$node->add($self->{shipping}->to_node($doc)) if defined $self->{shipping}; |
172
|
1
|
|
|
|
|
68
|
$node->add($self->{tax}->to_node($doc) ) if defined $self->{tax}; |
|
1
|
|
|
|
|
13
|
|
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
return $node; |
175
|
11
|
100
|
|
|
|
98
|
} |
176
|
11
|
100
|
|
|
|
36
|
|
177
|
|
|
|
|
|
|
|
178
|
11
|
|
|
|
|
38
|
=item C<B<sku>> |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
Mandatory SKU, a string uniquely identifying the product being sold, with the |
181
|
|
|
|
|
|
|
L</chars> (colors, sizes) selected. |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=item C<B<qty>> |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Mandatory, how many items. Default: C<0> |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=item C<B<qty_open>> |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
Optional, the quantity pending to be fulfilled by the seller to ship to the |
190
|
|
|
|
|
|
|
buyer. |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=item C<B<qty_promised>> |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
Optional, the quantity that has been promised by the selling party. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=item C<B<i>> |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=item C<B<i_parent>> |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
Optional, line number (starting from 1). I<C<i_parent>> refers to a parent |
201
|
|
|
|
|
|
|
item's I<C<i>>. This allows nesting items. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item C<B<is_group>> |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=item C<B<is_parent_group>> |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
Optional, whether the item (or its parent) contains child items. |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
The current implementation B<does not set this for you> when you use |
210
|
|
|
|
|
|
|
I<C<i_parent>>: you must set these according to your structure. |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=item C<B<is_service>> |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
Optional, clarify whether the item is a service (true) or material (false). |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=item C<B<price>> |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
Mandatory, L<Business::cXML::Amount> object of type C<UnitPrice>. |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=item C<B<descriptions>> |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
Mandatory (at least one) |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=item C<B<unit>> |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
Mandatory, UN/CEFACT Recommendation 20 unit of measure. Default: C<EA> |
227
|
|
|
|
|
|
|
meaning "each", items are regarded as separate units. Also common: C<HUR> |
228
|
|
|
|
|
|
|
means one hour. |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
See |
231
|
|
|
|
|
|
|
L<http://www.unece.org/tradewelcome/un-centre-for-trade-facilitation-and-e-business-uncefact/outputs/cefactrecommendationsrec-index/list-of-trade-facilitation-recommendations-n-16-to-20.html> |
232
|
|
|
|
|
|
|
for more details about UN/CEFACT Recommendation 20 units of measure. |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=item C<B<class_domain>> |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=item C<B<class>> |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
Mandatory, name of classification such as C<UNSPSC> (default) and the |
239
|
|
|
|
|
|
|
classification itself (such as an 8+ digit UNSPSC number). |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
See L<https://en.wikipedia.org/wiki/UNSPSC> and L<http://www.unspsc.org/> for |
242
|
|
|
|
|
|
|
more details about UNSPSC classifications, for example, C<53101902> "Men's |
243
|
|
|
|
|
|
|
suits" |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=item C<B<manu_part>> |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
Optional, ID with which the item's manufacturer identifies the item. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=item C<B<manu_name>> |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=item C<B<manu_lang>> |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
Optional, name of the item's manufacturer and language of that name. |
254
|
|
|
|
|
|
|
C<manu_lang> defaults to C<en-us> if only C<manu_name> is set. |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=item C<B<delay>> |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
Optional, number of days to receive the item. |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
=item C<B<chars>> |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
Optional, list of L<Business::cXML::Characteristic> that define this specific |
263
|
|
|
|
|
|
|
product item (colors, sizes, etc.) The item will be deemed "configurable" if |
264
|
|
|
|
|
|
|
there are any characteristics. |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=item C<B<url>> |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
Optional |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=item C<B<shipping>> |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
Optional, L<Business::cXML::Amount> object of type C<Shipping> |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=item C<B<tax>> |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
Optional, L<Business::cXML::Amount> object of type C<Tax> |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
=back |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=head1 AUTHOR |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
Stéphane Lavergne L<https://github.com/vphantom> |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
Graph X Design Inc. L<https://www.gxd.ca/> sponsored this project. |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
Copyright (c) 2017-2018 Stéphane Lavergne L<https://github.com/vphantom> |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
293
|
|
|
|
|
|
|
of this software and associated documentation files (the "Software"), to deal |
294
|
|
|
|
|
|
|
in the Software without restriction, including without limitation the rights |
295
|
|
|
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
296
|
|
|
|
|
|
|
copies of the Software, and to permit persons to whom the Software is |
297
|
|
|
|
|
|
|
furnished to do so, subject to the following conditions: |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all |
300
|
|
|
|
|
|
|
copies or substantial portions of the Software. |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
303
|
|
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
304
|
|
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
305
|
|
|
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
306
|
|
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
307
|
|
|
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
308
|
|
|
|
|
|
|
SOFTWARE. |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=cut |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
1; |