y-rb 0.1.4.beta.1-aarch64-linux

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d7b26ac724af9d4b0fc590d540530c7e69431d1a36733aa9177a6c1b22ccddbb
4
+ data.tar.gz: db1e43b3cc5a8c23cd72f3517cc6c1d694ec84dc032e89527176256c3071b2c3
5
+ SHA512:
6
+ metadata.gz: 2a70dfdff926644b02d01166038d346194fa814014193ef16d592f7b40fe8a1cc16fabff1f15b526fde4ef0a3e47c57d3e8303f4c2804e7573ac0d93d139be38
7
+ data.tar.gz: d3ac2f35a9c9c1e0f35db7dd65f107730dfb8e68a8975d79cfcab13d4c82ac6d233f748bc1a58f00047b3fe3279e8d7031a2bbca07c3e1ef6846a3090895ad3f
@@ -0,0 +1,19 @@
1
+ [package]
2
+ name = "yrb"
3
+ version = "0.1.4"
4
+ authors = ["Hannes Moser <box@hannesmoser.at>", "Hannes Moser <hmoser@gitlab.com>"]
5
+ edition = "2021"
6
+ homepage = "https://github.com/y-crdt/yrb"
7
+ repository = "https://github.com/y-crdt/yrb"
8
+
9
+ [dependencies]
10
+ lib0 = "0.12.0" # must match yrs version
11
+ magnus = { git = "https://github.com/matsadler/magnus" } # waiting for release with full rb-sys backend
12
+ yrs = "0.12.0"
13
+
14
+ [dev-dependencies]
15
+ magnus = { git = "https://github.com/matsadler/magnus", features = ["embed"] } # waiting for release with full rb-sys backend
16
+
17
+ [lib]
18
+ name = "yrb"
19
+ crate-type = ["cdylib"]
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mkmf"
4
+ require "rb_sys/mkmf"
5
+
6
+ create_rust_makefile("yrb") do |r|
7
+ if r.target&.include? "musl"
8
+ r.extra_rustflags = %w[-C target-feature=-crt-static]
9
+ end
10
+ end
@@ -0,0 +1,476 @@
1
+ use crate::yarray::YArray;
2
+ use crate::ydoc::YDoc;
3
+ use crate::ymap::YMap;
4
+ use crate::ytext::YText;
5
+ use crate::ytransaction::YTransaction;
6
+ use crate::yxml_element::YXmlElement;
7
+ use crate::yxml_text::YXmlText;
8
+ use magnus::{define_module, function, method, Error, Module, Object};
9
+
10
+ mod utils;
11
+ mod yany;
12
+ mod yarray;
13
+ mod yattrs;
14
+ mod ydoc;
15
+ mod ymap;
16
+ mod ytext;
17
+ mod ytransaction;
18
+ mod yvalue;
19
+ mod yxml_element;
20
+ mod yxml_text;
21
+
22
+ #[magnus::init]
23
+ fn init() -> Result<(), Error> {
24
+ let module = define_module("Y").expect("cannot define ::Y module");
25
+
26
+ let yarray = module
27
+ .define_class("Array", Default::default())
28
+ .expect("cannot find class Y::Array");
29
+
30
+ yarray
31
+ .define_private_method("yarray_each", method!(YArray::yarray_each, 1))
32
+ .expect("cannot define private method: yarray_each");
33
+ yarray
34
+ .define_private_method("yarray_get", method!(YArray::yarray_get, 1))
35
+ .expect("cannot define private method: yarray_get");
36
+ yarray
37
+ .define_private_method(
38
+ "yarray_insert",
39
+ method!(YArray::yarray_insert, 3)
40
+ )
41
+ .expect("cannot define private method: yarray_insert");
42
+ yarray
43
+ .define_private_method(
44
+ "yarray_insert_range",
45
+ method!(YArray::yarray_insert_range, 3)
46
+ )
47
+ .expect("cannot define private method: yarray_insert_range");
48
+ yarray
49
+ .define_private_method(
50
+ "yarray_length",
51
+ method!(YArray::yarray_length, 0)
52
+ )
53
+ .expect("cannot define private method: yarray_length");
54
+ yarray
55
+ .define_private_method(
56
+ "yarray_observe",
57
+ method!(YArray::yarray_observe, 1)
58
+ )
59
+ .expect("cannot define private method: yarray_observe");
60
+ yarray
61
+ .define_private_method(
62
+ "yarray_push_back",
63
+ method!(YArray::yarray_push_back, 2)
64
+ )
65
+ .expect("cannot define private method: yarray_push_back");
66
+ yarray
67
+ .define_private_method(
68
+ "yarray_push_front",
69
+ method!(YArray::yarray_push_front, 2)
70
+ )
71
+ .expect("cannot define private method: yarray_push_front");
72
+ yarray
73
+ .define_private_method(
74
+ "yarray_remove",
75
+ method!(YArray::yarray_remove, 2)
76
+ )
77
+ .expect("cannot define private method: yarray_remove");
78
+ yarray
79
+ .define_private_method(
80
+ "yarray_remove_range",
81
+ method!(YArray::yarray_remove_range, 3)
82
+ )
83
+ .expect("cannot define private method: yarray_remove_range");
84
+ yarray
85
+ .define_private_method("yarray_to_a", method!(YArray::yarray_to_a, 0))
86
+ .expect("cannot define private method: yarray_to_a");
87
+ yarray
88
+ .define_private_method(
89
+ "yarray_unobserve",
90
+ method!(YArray::yarray_unobserve, 1)
91
+ )
92
+ .expect("cannot define private method: yarray_unobserve");
93
+
94
+ let ydoc = module
95
+ .define_class("Doc", Default::default())
96
+ .expect("cannot define class Y::Doc");
97
+ ydoc.define_singleton_method("new", function!(YDoc::ydoc_new, -1))
98
+ .expect("cannot define singleton method: ydoc_new");
99
+ ydoc.define_private_method(
100
+ "ydoc_transact",
101
+ method!(YDoc::ydoc_transact, 0)
102
+ )
103
+ .expect("cannot define private method: ydoc_transact");
104
+ ydoc.define_private_method(
105
+ "ydoc_encode_diff_v1",
106
+ method!(YDoc::ydoc_encode_diff_v1, 1)
107
+ )
108
+ .expect("cannot define private method: ydoc_encode_diff_v1");
109
+
110
+ let ymap = module
111
+ .define_class("Map", Default::default())
112
+ .expect("cannot define class Y::Map");
113
+
114
+ ymap.define_private_method("ymap_clear", method!(YMap::ymap_clear, 1))
115
+ .expect("cannot define private method: ymap_clear");
116
+ ymap.define_private_method(
117
+ "ymap_contains",
118
+ method!(YMap::ymap_contains, 1)
119
+ )
120
+ .expect("cannot define private method: ymap_contains");
121
+ ymap.define_private_method("ymap_each", method!(YMap::ymap_each, 1))
122
+ .expect("cannot define private method: ymap_each");
123
+ ymap.define_private_method("ymap_get", method!(YMap::ymap_get, 1))
124
+ .expect("cannot define private method: ymap_get");
125
+ ymap.define_private_method("ymap_insert", method!(YMap::ymap_insert, 3))
126
+ .expect("cannot define private method: ymap_insert");
127
+ ymap.define_private_method("ymap_observe", method!(YMap::ymap_observe, 1))
128
+ .expect("cannot define private method: ymap_observe");
129
+ ymap.define_private_method("ymap_remove", method!(YMap::ymap_remove, 2))
130
+ .expect("cannot define private method: ymap_remove");
131
+ ymap.define_private_method("ymap_size", method!(YMap::ymap_size, 0))
132
+ .expect("cannot define private method: ymap_size");
133
+ ymap.define_private_method("ymap_to_h", method!(YMap::ymap_to_h, 0))
134
+ .expect("cannot define private method: ymap_to_h");
135
+ ymap.define_private_method(
136
+ "ymap_unobserve",
137
+ method!(YMap::ymap_unobserve, 1)
138
+ )
139
+ .expect("cannot define private method: ymap_unobserve");
140
+
141
+ let ytransaction = module
142
+ .define_class("Transaction", Default::default())
143
+ .expect("cannot define class Y::Transaction");
144
+
145
+ ytransaction
146
+ .define_private_method(
147
+ "ytransaction_apply_update",
148
+ method!(YTransaction::ytransaction_apply_update, 1)
149
+ )
150
+ .expect("cannot define private method: ytransaction_apply_update");
151
+ ytransaction
152
+ .define_private_method(
153
+ "ytransaction_commit",
154
+ method!(YTransaction::ytransaction_commit, 0)
155
+ )
156
+ .expect("cannot define private method: ytransaction_commit");
157
+ ytransaction
158
+ .define_private_method(
159
+ "ytransaction_get_array",
160
+ method!(YTransaction::ytransaction_get_array, 1)
161
+ )
162
+ .expect("cannot define private method: ytransaction_get_array");
163
+ ytransaction
164
+ .define_private_method(
165
+ "ytransaction_get_map",
166
+ method!(YTransaction::ytransaction_get_map, 1)
167
+ )
168
+ .expect("cannot define private method: ytransaction_get_mao");
169
+ ytransaction
170
+ .define_private_method(
171
+ "ytransaction_get_text",
172
+ method!(YTransaction::ytransaction_get_text, 1)
173
+ )
174
+ .expect("cannot define private method: ytransaction_get_text");
175
+ ytransaction
176
+ .define_private_method(
177
+ "ytransaction_get_xml_element",
178
+ method!(YTransaction::ytransaction_get_xml_element, 1)
179
+ )
180
+ .expect("cannot define private method: ytransaction_get_xml_element");
181
+ ytransaction
182
+ .define_private_method(
183
+ "ytransaction_get_xml_text",
184
+ method!(YTransaction::ytransaction_get_xml_text, 1)
185
+ )
186
+ .expect("cannot define private method: ytransaction_get_xml_text");
187
+ ytransaction
188
+ .define_private_method(
189
+ "ytransaction_state_vector",
190
+ method!(YTransaction::ytransaction_state_vector, 0)
191
+ )
192
+ .expect("cannot define private method: ytransaction_state_vector");
193
+
194
+ let ytext = module
195
+ .define_class("Text", Default::default())
196
+ .expect("cannot define class Y::Text");
197
+
198
+ ytext
199
+ .define_private_method("ytext_format", method!(YText::ytext_format, 4))
200
+ .expect("cannot define private method: ytext_format");
201
+ ytext
202
+ .define_private_method("ytext_insert", method!(YText::ytext_insert, 3))
203
+ .expect("cannot define private method: ytext_insert");
204
+ ytext
205
+ .define_private_method(
206
+ "ytext_insert_embed",
207
+ method!(YText::ytext_insert_embed, 3)
208
+ )
209
+ .expect("cannot define private method: ytext_insert_embed");
210
+ ytext
211
+ .define_private_method(
212
+ "ytext_insert_embed_with_attributes",
213
+ method!(YText::ytext_insert_embed_with_attributes, 4)
214
+ )
215
+ .expect(
216
+ "cannot define private method: ytext_insert_embed_with_attributes"
217
+ );
218
+ ytext
219
+ .define_private_method(
220
+ "ytext_insert_with_attributes",
221
+ method!(YText::ytext_insert_with_attributes, 4)
222
+ )
223
+ .expect("cannot define private method: ytext_insert_with_attributes");
224
+ ytext
225
+ .define_private_method("ytext_length", method!(YText::ytext_length, 0))
226
+ .expect("cannot define private method: ytext_length");
227
+ ytext
228
+ .define_private_method(
229
+ "ytext_observe",
230
+ method!(YText::ytext_observe, 1)
231
+ )
232
+ .expect("cannot define private method: ytext_observe");
233
+ ytext
234
+ .define_private_method("ytext_push", method!(YText::ytext_push, 2))
235
+ .expect("cannot define private method: ytext_push");
236
+ ytext
237
+ .define_private_method(
238
+ "ytext_remove_range",
239
+ method!(YText::ytext_remove_range, 3)
240
+ )
241
+ .expect("cannot define private method: ytext_remove_range");
242
+ ytext
243
+ .define_private_method("ytext_to_s", method!(YText::ytext_to_s, 0))
244
+ .expect("cannot define private method: ytext_to_s");
245
+ ytext
246
+ .define_private_method(
247
+ "ytext_unobserve",
248
+ method!(YText::ytext_unobserve, 1)
249
+ )
250
+ .expect("cannot define private method: ytext_unobserve");
251
+
252
+ let yxml_element = module
253
+ .define_class("XMLElement", Default::default())
254
+ .expect("cannot define class Y::XMLElement");
255
+
256
+ yxml_element
257
+ .define_private_method(
258
+ "yxml_element_attributes",
259
+ method!(YXmlElement::yxml_element_attributes, 0)
260
+ )
261
+ .expect("cannot define private method: yxml_element_attributes");
262
+ yxml_element
263
+ .define_private_method(
264
+ "yxml_element_first_child",
265
+ method!(YXmlElement::yxml_element_first_child, 0)
266
+ )
267
+ .expect("cannot define private method: yxml_element_first_child");
268
+ yxml_element
269
+ .define_private_method(
270
+ "yxml_element_get",
271
+ method!(YXmlElement::yxml_element_get, 1)
272
+ )
273
+ .expect("cannot define private method: yxml_element_get");
274
+ yxml_element
275
+ .define_private_method(
276
+ "yxml_element_get_attribute",
277
+ method!(YXmlElement::yxml_element_get_attribute, 1)
278
+ )
279
+ .expect("cannot define private method: yxml_element_get_attribute");
280
+ yxml_element
281
+ .define_private_method(
282
+ "yxml_element_insert_attribute",
283
+ method!(YXmlElement::yxml_element_insert_attribute, 3)
284
+ )
285
+ .expect("cannot define private method: yxml_element_insert_attribute");
286
+ yxml_element
287
+ .define_private_method(
288
+ "yxml_element_insert_element",
289
+ method!(YXmlElement::yxml_element_insert_element, 3)
290
+ )
291
+ .expect("cannot define private method: yxml_element_insert_element");
292
+ yxml_element
293
+ .define_private_method(
294
+ "yxml_element_insert_text",
295
+ method!(YXmlElement::yxml_element_insert_text, 2)
296
+ )
297
+ .expect("cannot define private method: yxml_element_insert_text");
298
+ yxml_element
299
+ .define_private_method(
300
+ "yxml_element_next_sibling",
301
+ method!(YXmlElement::yxml_element_next_sibling, 0)
302
+ )
303
+ .expect("cannot define private method: yxml_element_next_sibling");
304
+ yxml_element
305
+ .define_private_method(
306
+ "yxml_element_observe",
307
+ method!(YXmlElement::yxml_element_observe, 1)
308
+ )
309
+ .expect("cannot define private method: yxml_element_observe");
310
+ yxml_element
311
+ .define_private_method(
312
+ "yxml_element_parent",
313
+ method!(YXmlElement::yxml_element_parent, 0)
314
+ )
315
+ .expect("cannot define private method: yxml_element_parent");
316
+ yxml_element
317
+ .define_private_method(
318
+ "yxml_element_prev_sibling",
319
+ method!(YXmlElement::yxml_element_prev_sibling, 0)
320
+ )
321
+ .expect("cannot define private method: yxml_element_prev_sibling");
322
+ yxml_element
323
+ .define_private_method(
324
+ "yxml_element_push_elem_back",
325
+ method!(YXmlElement::yxml_element_push_element_back, 2)
326
+ )
327
+ .expect("cannot define private method: yxml_element_push_elem_back");
328
+ yxml_element
329
+ .define_private_method(
330
+ "yxml_element_push_elem_front",
331
+ method!(YXmlElement::yxml_element_push_element_front, 2)
332
+ )
333
+ .expect("cannot define private method: yxml_element_push_elem_front");
334
+ yxml_element
335
+ .define_private_method(
336
+ "yxml_element_push_text_back",
337
+ method!(YXmlElement::yxml_element_push_text_back, 1)
338
+ )
339
+ .expect("cannot define private method: yxml_element_push_text_back");
340
+ yxml_element
341
+ .define_private_method(
342
+ "yxml_element_push_text_front",
343
+ method!(YXmlElement::yxml_element_push_text_front, 1)
344
+ )
345
+ .expect("cannot define private method: yxml_element_push_text_front");
346
+ yxml_element
347
+ .define_private_method(
348
+ "yxml_element_remove_attribute",
349
+ method!(YXmlElement::yxml_element_remove_attribute, 2)
350
+ )
351
+ .expect("cannot define private method: yxml_element_remove_range");
352
+ yxml_element
353
+ .define_private_method(
354
+ "yxml_element_remove_range",
355
+ method!(YXmlElement::yxml_element_remove_range, 3)
356
+ )
357
+ .expect("cannot define private method: yxml_element_remove_range");
358
+ yxml_element
359
+ .define_private_method(
360
+ "yxml_element_size",
361
+ method!(YXmlElement::yxml_element_size, 0)
362
+ )
363
+ .expect("cannot define private method: yxml_element_size");
364
+ yxml_element
365
+ .define_private_method(
366
+ "yxml_element_tag",
367
+ method!(YXmlElement::yxml_element_tag, 0)
368
+ )
369
+ .expect("cannot define private method: yxml_element_tag");
370
+ yxml_element
371
+ .define_private_method(
372
+ "yxml_element_to_s",
373
+ method!(YXmlElement::yxml_element_to_s, 0)
374
+ )
375
+ .expect("cannot define private method: yxml_element_to_s");
376
+ yxml_element
377
+ .define_private_method(
378
+ "yxml_element_unobserve",
379
+ method!(YXmlElement::yxml_element_unobserve, 1)
380
+ )
381
+ .expect("cannot define private method: yxml_element_unobserve");
382
+
383
+ let yxml_text = module
384
+ .define_class("XMLText", Default::default())
385
+ .expect("cannot define class Y::XMLText");
386
+
387
+ yxml_text
388
+ .define_private_method(
389
+ "yxml_text_attributes",
390
+ method!(YXmlText::yxml_text_attributes, 0)
391
+ )
392
+ .expect("cannot define private method: yxml_text_attributes");
393
+ yxml_text
394
+ .define_private_method(
395
+ "yxml_text_format",
396
+ method!(YXmlText::yxml_text_format, 4)
397
+ )
398
+ .expect("cannot define private method: yxml_text_format");
399
+ yxml_text
400
+ .define_private_method(
401
+ "yxml_text_get_attribute",
402
+ method!(YXmlText::yxml_text_get_attribute, 1)
403
+ )
404
+ .expect("cannot define private method: yxml_text_get_attribute");
405
+ yxml_text
406
+ .define_private_method(
407
+ "yxml_text_insert",
408
+ method!(YXmlText::yxml_text_insert, 3)
409
+ )
410
+ .expect("cannot define private method: yxml_text_insert");
411
+ yxml_text
412
+ .define_private_method(
413
+ "yxml_text_insert_attribute",
414
+ method!(YXmlText::yxml_text_insert_attribute, 3)
415
+ )
416
+ .expect("cannot define private method: yxml_text_insert_attribute");
417
+ yxml_text.define_private_method("yxml_text_insert_embed_with_attrs", method!(YXmlText::yxml_text_insert_embed_with_attributes, 4)).expect("cannot define private method: yxml_text_insert_embed_with_attributes");
418
+ yxml_text
419
+ .define_private_method(
420
+ "yxml_text_insert_with_attrs",
421
+ method!(YXmlText::yxml_text_insert_with_attributes, 4)
422
+ )
423
+ .expect(
424
+ "cannot define private method: yxml_text_insert_with_attributes"
425
+ );
426
+ yxml_text
427
+ .define_private_method(
428
+ "yxml_text_insert_embed",
429
+ method!(YXmlText::yxml_text_insert_embed, 3)
430
+ )
431
+ .expect("cannot define private method: yxml_text_insert_embed");
432
+ yxml_text
433
+ .define_private_method(
434
+ "yxml_text_length",
435
+ method!(YXmlText::yxml_text_length, 0)
436
+ )
437
+ .expect("cannot define private method: yxml_text_length");
438
+ yxml_text
439
+ .define_private_method(
440
+ "yxml_text_next_sibling",
441
+ method!(YXmlText::yxml_text_next_sibling, 0)
442
+ )
443
+ .expect("cannot define private method: yxml_text_next_sibling");
444
+ yxml_text
445
+ .define_private_method(
446
+ "yxml_text_parent",
447
+ method!(YXmlText::yxml_text_parent, 0)
448
+ )
449
+ .expect("cannot define private method: yxml_text_parent");
450
+ yxml_text
451
+ .define_private_method(
452
+ "yxml_text_prev_sibling",
453
+ method!(YXmlText::yxml_text_prev_sibling, 0)
454
+ )
455
+ .expect("cannot define private method: yxml_text_prev_sibling");
456
+ yxml_text
457
+ .define_private_method(
458
+ "yxml_text_push",
459
+ method!(YXmlText::yxml_text_push, 2)
460
+ )
461
+ .expect("cannot define private method: yxml_text_push");
462
+ yxml_text
463
+ .define_private_method(
464
+ "yxml_text_remove_range",
465
+ method!(YXmlText::yxml_text_remove_range, 3)
466
+ )
467
+ .expect("cannot define private method: yxml_text_remove_range");
468
+ yxml_text
469
+ .define_private_method(
470
+ "yxml_text_to_s",
471
+ method!(YXmlText::yxml_text_to_s, 0)
472
+ )
473
+ .expect("cannot define private method: yxml_text_to_s");
474
+
475
+ Ok(())
476
+ }
@@ -0,0 +1,36 @@
1
+ use crate::yvalue::YValue;
2
+ use lib0::any::Any;
3
+ use magnus::r_hash::ForEach::Continue;
4
+ use magnus::{Error, RHash, RString, Symbol, Value};
5
+ use std::rc::Rc;
6
+ use yrs::types::Attrs;
7
+
8
+ #[derive(Debug, Clone)]
9
+ pub(crate) struct TypeConversionError;
10
+
11
+ pub(crate) fn indifferent_hash_key(key: Value) -> Option<String> {
12
+ RString::from_value(key)
13
+ .map(|v| v.to_string().unwrap())
14
+ .or_else(|| {
15
+ Symbol::from_value(key).map(|v| v.name().unwrap().to_string())
16
+ })
17
+ }
18
+
19
+ pub(crate) fn map_rhash_to_attrs(hash: RHash) -> Result<Attrs, Error> {
20
+ let mut a: Attrs = Default::default();
21
+
22
+ let result = hash.foreach(|key: Value, value: Value| {
23
+ let k = Rc::from(key.to_string());
24
+ let v = Any::from(YValue::from(value));
25
+
26
+ a.insert(k, v);
27
+
28
+ Ok(Continue)
29
+ });
30
+
31
+ if result.is_err() {
32
+ return Err(Error::runtime_error("could not map hash to attrs"));
33
+ }
34
+
35
+ Ok(a)
36
+ }
@@ -0,0 +1,44 @@
1
+ use lib0::any::Any;
2
+ use magnus::{RArray, RHash, RString, Value, QNIL};
3
+ use std::borrow::Borrow;
4
+ use std::ops::{Deref, DerefMut};
5
+
6
+ pub(crate) struct YAny(pub(crate) Any);
7
+
8
+ impl Deref for YAny {
9
+ type Target = Any;
10
+
11
+ fn deref(&self) -> &Self::Target {
12
+ &self.0
13
+ }
14
+ }
15
+
16
+ impl DerefMut for YAny {
17
+ fn deref_mut(&mut self) -> &mut Self::Target {
18
+ &mut self.0
19
+ }
20
+ }
21
+
22
+ impl TryInto<Value> for YAny {
23
+ type Error = ();
24
+
25
+ fn try_into(self) -> Result<Value, Self::Error> {
26
+ return match self.0 {
27
+ Any::Array(_v) => {
28
+ let arr = RArray::new();
29
+ Ok(Value::from(arr))
30
+ }
31
+ Any::Map(_v) => {
32
+ let hash = RHash::new();
33
+ Ok(Value::from(hash))
34
+ }
35
+ Any::Null => Ok(Value::from(QNIL)),
36
+ Any::Undefined => Ok(Value::from(QNIL)),
37
+ Any::Bool(v) => Ok(Value::from(v)),
38
+ Any::Number(v) => Ok(Value::from(v)),
39
+ Any::BigInt(v) => Ok(Value::from(v)),
40
+ Any::String(v) => Ok(Value::from(RString::from(v.borrow()))),
41
+ Any::Buffer(v) => Ok(Value::from(RString::from_slice(v.borrow())))
42
+ };
43
+ }
44
+ }