tplinkrouterc6u 4.2.0__py3-none-any.whl → 4.2.1__py3-none-any.whl

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.
test/test_client.py CHANGED
@@ -1,7 +1,7 @@
1
- import unittest
2
- import macaddress
3
- import ipaddress
4
- import json
1
+ from unittest import main, TestCase
2
+ from macaddress import EUI48
3
+ from ipaddress import IPv4Address
4
+ from json import loads
5
5
  from tplinkrouterc6u import (
6
6
  TplinkRouter,
7
7
  Connection,
@@ -11,7 +11,7 @@ from tplinkrouterc6u import (
11
11
  )
12
12
 
13
13
 
14
- class TestTPLinkClient(unittest.TestCase):
14
+ class TestTPLinkClient(TestCase):
15
15
  def test_get_status(self) -> None:
16
16
  response_status = '''
17
17
  {
@@ -206,9 +206,9 @@ class TestTPLinkClient(unittest.TestCase):
206
206
  def request(self, path: str, data: str,
207
207
  ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
208
208
  if path == 'admin/status?form=all&operation=read':
209
- return json.loads(response_status)['data']
209
+ return loads(response_status)['data']
210
210
  elif path == 'admin/wireless?form=statistics':
211
- return json.loads(response_stats)['data']
211
+ return loads(response_stats)['data']
212
212
  raise ClientException()
213
213
 
214
214
  client = TPLinkRouterTest('', '')
@@ -216,14 +216,14 @@ class TestTPLinkClient(unittest.TestCase):
216
216
 
217
217
  self.assertIsInstance(status, Status)
218
218
  self.assertEqual(status.wan_macaddr, 'D6-0B-40-57-DA-60')
219
- self.assertIsInstance(status.wan_macaddress, macaddress.EUI48)
219
+ self.assertIsInstance(status.wan_macaddress, EUI48)
220
220
  self.assertEqual(status.lan_macaddr, '06-E6-97-9E-23-F5')
221
- self.assertIsInstance(status.lan_macaddress, macaddress.EUI48)
221
+ self.assertIsInstance(status.lan_macaddress, EUI48)
222
222
  self.assertEqual(status.wan_ipv4_addr, '192.168.1.100')
223
- self.assertIsInstance(status.lan_ipv4_address, ipaddress.IPv4Address)
223
+ self.assertIsInstance(status.lan_ipv4_address, IPv4Address)
224
224
  self.assertEqual(status.lan_ipv4_addr, '192.168.1.100')
225
225
  self.assertEqual(status.wan_ipv4_gateway, '192.168.1.254')
226
- self.assertIsInstance(status.wan_ipv4_address, ipaddress.IPv4Address)
226
+ self.assertIsInstance(status.wan_ipv4_address, IPv4Address)
227
227
  self.assertEqual(status.wired_total, 2)
228
228
  self.assertEqual(status.wifi_clients_total, 2)
229
229
  self.assertEqual(status.guest_clients_total, 0)
@@ -242,18 +242,18 @@ class TestTPLinkClient(unittest.TestCase):
242
242
  self.assertIsInstance(status.devices[0], Device)
243
243
  self.assertEqual(status.devices[0].type, Connection.WIRED)
244
244
  self.assertEqual(status.devices[0].macaddr, '3D-24-25-24-30-79')
245
- self.assertIsInstance(status.devices[0].macaddress, macaddress.EUI48)
245
+ self.assertIsInstance(status.devices[0].macaddress, EUI48)
246
246
  self.assertEqual(status.devices[0].ipaddr, '192.168.1.228')
247
- self.assertIsInstance(status.devices[0].ipaddress, ipaddress.IPv4Address)
247
+ self.assertIsInstance(status.devices[0].ipaddress, IPv4Address)
248
248
  self.assertEqual(status.devices[0].hostname, 'SERVER')
249
249
  self.assertEqual(status.devices[0].packets_sent, None)
250
250
  self.assertEqual(status.devices[0].packets_received, None)
251
251
  self.assertIsInstance(status.devices[0], Device)
252
252
  self.assertEqual(status.devices[1].type, Connection.WIRED)
253
253
  self.assertEqual(status.devices[1].macaddr, 'AC-04-D6-25-2A-96')
254
- self.assertIsInstance(status.devices[1].macaddress, macaddress.EUI48)
254
+ self.assertIsInstance(status.devices[1].macaddress, EUI48)
255
255
  self.assertEqual(status.devices[1].ipaddr, '192.168.1.254')
256
- self.assertIsInstance(status.devices[1].ipaddress, ipaddress.IPv4Address)
256
+ self.assertIsInstance(status.devices[1].ipaddress, IPv4Address)
257
257
  self.assertEqual(status.devices[1].hostname, 'UNKNOWN')
258
258
  self.assertEqual(status.devices[1].packets_sent, None)
259
259
  self.assertEqual(status.devices[1].packets_received, None)
@@ -321,9 +321,9 @@ class TestTPLinkClient(unittest.TestCase):
321
321
  def request(self, path: str, data: str,
322
322
  ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
323
323
  if path == 'admin/status?form=all&operation=read':
324
- return json.loads(response_status)['data']
324
+ return loads(response_status)['data']
325
325
  elif path == 'admin/wireless?form=statistics':
326
- return json.loads(response_stats)['data']
326
+ return loads(response_stats)['data']
327
327
  raise ClientException()
328
328
 
329
329
  client = TPLinkRouterTest('', '')
@@ -332,7 +332,7 @@ class TestTPLinkClient(unittest.TestCase):
332
332
  self.assertIsInstance(status, Status)
333
333
  self.assertEqual(status.wan_macaddr, None)
334
334
  self.assertEqual(status.lan_macaddr, '06-E6-97-9E-23-F5')
335
- self.assertIsInstance(status.lan_macaddress, macaddress.EUI48)
335
+ self.assertIsInstance(status.lan_macaddress, EUI48)
336
336
  self.assertEqual(status.wan_ipv4_addr, None)
337
337
  self.assertEqual(status.lan_ipv4_addr, None)
338
338
  self.assertEqual(status.wan_ipv4_gateway, None)
@@ -357,27 +357,27 @@ class TestTPLinkClient(unittest.TestCase):
357
357
  self.assertIsInstance(status.devices[0], Device)
358
358
  self.assertEqual(status.devices[0].type, Connection.WIRED)
359
359
  self.assertEqual(status.devices[0].macaddr, '3D-24-25-24-30-79')
360
- self.assertIsInstance(status.devices[0].macaddress, macaddress.EUI48)
360
+ self.assertIsInstance(status.devices[0].macaddress, EUI48)
361
361
  self.assertEqual(status.devices[0].ipaddr, '192.168.1.228')
362
- self.assertIsInstance(status.devices[0].ipaddress, ipaddress.IPv4Address)
362
+ self.assertIsInstance(status.devices[0].ipaddress, IPv4Address)
363
363
  self.assertEqual(status.devices[0].hostname, 'SERVER')
364
364
  self.assertEqual(status.devices[0].packets_sent, None)
365
365
  self.assertEqual(status.devices[0].packets_received, None)
366
366
  self.assertIsInstance(status.devices[1], Device)
367
367
  self.assertEqual(status.devices[1].type, Connection.WIRED)
368
368
  self.assertEqual(status.devices[1].macaddr, 'AC-04-D6-25-2A-96')
369
- self.assertIsInstance(status.devices[1].macaddress, macaddress.EUI48)
369
+ self.assertIsInstance(status.devices[1].macaddress, EUI48)
370
370
  self.assertEqual(status.devices[1].ipaddr, '192.168.1.254')
371
- self.assertIsInstance(status.devices[1].ipaddress, ipaddress.IPv4Address)
371
+ self.assertIsInstance(status.devices[1].ipaddress, IPv4Address)
372
372
  self.assertEqual(status.devices[1].hostname, 'UNKNOWN')
373
373
  self.assertEqual(status.devices[1].packets_sent, None)
374
374
  self.assertEqual(status.devices[1].packets_received, None)
375
375
  self.assertIsInstance(status.devices[2], Device)
376
376
  self.assertEqual(status.devices[2].type, Connection.HOST_2G)
377
377
  self.assertEqual(status.devices[2].macaddr, '06-82-9D-2B-8F-C6')
378
- self.assertIsInstance(status.devices[2].macaddress, macaddress.EUI48)
378
+ self.assertIsInstance(status.devices[2].macaddress, EUI48)
379
379
  self.assertEqual(status.devices[2].ipaddr, '192.168.1.186')
380
- self.assertIsInstance(status.devices[2].ipaddress, ipaddress.IPv4Address)
380
+ self.assertIsInstance(status.devices[2].ipaddress, IPv4Address)
381
381
  self.assertEqual(status.devices[2].hostname, 'UNKNOWN')
382
382
  self.assertEqual(status.devices[2].packets_sent, None)
383
383
  self.assertEqual(status.devices[2].packets_received, None)
@@ -425,11 +425,14 @@ class TestTPLinkClient(unittest.TestCase):
425
425
  response_game_accelerator = '''
426
426
  {
427
427
  "data": [
428
- {"mac": "06:82:9d:2b:8f:c6", "deviceTag":"2.4G", "isGuest":false, "ip":"192.168.1.186", "deviceName":"name1",
429
- "uploadSpeed":12, "downloadSpeed":77},
430
- {"mac": "fb:90:b8:2a:8a:b1", "deviceTag":"iot_2.4G", "isGuest":false, "ip":"192.168.1.187", "deviceName":"name2"},
431
- {"mac": "54:b3:a2:f7:be:ea", "deviceTag":"iot_5G", "isGuest":false, "ip":"192.168.1.188", "deviceName":"name3"},
432
- {"mac": "3c:ae:e1:83:94:9d", "deviceTag":"iot_6G", "isGuest":false, "ip":"192.168.1.189", "deviceName":"name4"}
428
+ {"mac": "06:82:9d:2b:8f:c6", "deviceTag":"2.4G", "isGuest":false, "ip":"192.168.1.186",
429
+ "deviceName":"name1", "uploadSpeed":12, "downloadSpeed":77},
430
+ {"mac": "fb:90:b8:2a:8a:b1", "deviceTag":"iot_2.4G", "isGuest":false, "ip":"192.168.1.187",
431
+ "deviceName":"name2"},
432
+ {"mac": "54:b3:a2:f7:be:ea", "deviceTag":"iot_5G", "isGuest":false, "ip":"192.168.1.188",
433
+ "deviceName":"name3"},
434
+ {"mac": "3c:ae:e1:83:94:9d", "deviceTag":"iot_6G", "isGuest":false, "ip":"192.168.1.189",
435
+ "deviceName":"name4"}
433
436
  ],
434
437
  "timeout": false,
435
438
  "success": true
@@ -463,11 +466,11 @@ class TestTPLinkClient(unittest.TestCase):
463
466
  def request(self, path: str, data: str,
464
467
  ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
465
468
  if path == 'admin/status?form=all&operation=read':
466
- return json.loads(response_status)['data']
469
+ return loads(response_status)['data']
467
470
  elif path == 'admin/smart_network?form=game_accelerator':
468
- return json.loads(response_game_accelerator)['data']
471
+ return loads(response_game_accelerator)['data']
469
472
  elif path == 'admin/wireless?form=statistics':
470
- return json.loads(response_stats)['data']
473
+ return loads(response_stats)['data']
471
474
  raise ClientException()
472
475
 
473
476
  client = TPLinkRouterTest('', '')
@@ -476,7 +479,7 @@ class TestTPLinkClient(unittest.TestCase):
476
479
  self.assertIsInstance(status, Status)
477
480
  self.assertEqual(status.wan_macaddr, None)
478
481
  self.assertEqual(status.lan_macaddr, '06-E6-97-9E-23-F5')
479
- self.assertIsInstance(status.lan_macaddress, macaddress.EUI48)
482
+ self.assertIsInstance(status.lan_macaddress, EUI48)
480
483
  self.assertEqual(status.wan_ipv4_addr, None)
481
484
  self.assertEqual(status.lan_ipv4_addr, None)
482
485
  self.assertEqual(status.wan_ipv4_gateway, None)
@@ -501,27 +504,27 @@ class TestTPLinkClient(unittest.TestCase):
501
504
  self.assertIsInstance(status.devices[0], Device)
502
505
  self.assertEqual(status.devices[0].type, Connection.WIRED)
503
506
  self.assertEqual(status.devices[0].macaddr, '3D-24-25-24-30-79')
504
- self.assertIsInstance(status.devices[0].macaddress, macaddress.EUI48)
507
+ self.assertIsInstance(status.devices[0].macaddress, EUI48)
505
508
  self.assertEqual(status.devices[0].ipaddr, '192.168.1.228')
506
- self.assertIsInstance(status.devices[0].ipaddress, ipaddress.IPv4Address)
509
+ self.assertIsInstance(status.devices[0].ipaddress, IPv4Address)
507
510
  self.assertEqual(status.devices[0].hostname, 'SERVER')
508
511
  self.assertEqual(status.devices[0].packets_sent, None)
509
512
  self.assertEqual(status.devices[0].packets_received, None)
510
513
  self.assertIsInstance(status.devices[1], Device)
511
514
  self.assertEqual(status.devices[1].type, Connection.WIRED)
512
515
  self.assertEqual(status.devices[1].macaddr, 'AC-04-D6-25-2A-96')
513
- self.assertIsInstance(status.devices[1].macaddress, macaddress.EUI48)
516
+ self.assertIsInstance(status.devices[1].macaddress, EUI48)
514
517
  self.assertEqual(status.devices[1].ipaddr, '192.168.1.254')
515
- self.assertIsInstance(status.devices[1].ipaddress, ipaddress.IPv4Address)
518
+ self.assertIsInstance(status.devices[1].ipaddress, IPv4Address)
516
519
  self.assertEqual(status.devices[1].hostname, 'UNKNOWN')
517
520
  self.assertEqual(status.devices[1].packets_sent, None)
518
521
  self.assertEqual(status.devices[1].packets_received, None)
519
522
  self.assertIsInstance(status.devices[2], Device)
520
523
  self.assertEqual(status.devices[2].type, Connection.HOST_2G)
521
524
  self.assertEqual(status.devices[2].macaddr, '06-82-9D-2B-8F-C6')
522
- self.assertIsInstance(status.devices[2].macaddress, macaddress.EUI48)
525
+ self.assertIsInstance(status.devices[2].macaddress, EUI48)
523
526
  self.assertEqual(status.devices[2].ipaddr, '192.168.1.186')
524
- self.assertIsInstance(status.devices[2].ipaddress, ipaddress.IPv4Address)
527
+ self.assertIsInstance(status.devices[2].ipaddress, IPv4Address)
525
528
  self.assertEqual(status.devices[2].hostname, 'UNKNOWN')
526
529
  self.assertEqual(status.devices[2].packets_sent, 450333)
527
530
  self.assertEqual(status.devices[2].packets_received, 4867482)
@@ -530,36 +533,36 @@ class TestTPLinkClient(unittest.TestCase):
530
533
  self.assertIsInstance(status.devices[3], Device)
531
534
  self.assertEqual(status.devices[3].type, Connection.IOT_2G)
532
535
  self.assertEqual(status.devices[3].macaddr, 'FB-90-B8-2A-8A-B1')
533
- self.assertIsInstance(status.devices[3].macaddress, macaddress.EUI48)
536
+ self.assertIsInstance(status.devices[3].macaddress, EUI48)
534
537
  self.assertEqual(status.devices[3].ipaddr, '192.168.1.187')
535
- self.assertIsInstance(status.devices[3].ipaddress, ipaddress.IPv4Address)
538
+ self.assertIsInstance(status.devices[3].ipaddress, IPv4Address)
536
539
  self.assertEqual(status.devices[3].hostname, 'name2')
537
540
  self.assertEqual(status.devices[3].packets_sent, None)
538
541
  self.assertEqual(status.devices[3].packets_received, None)
539
542
  self.assertIsInstance(status.devices[4], Device)
540
543
  self.assertEqual(status.devices[4].type, Connection.IOT_5G)
541
544
  self.assertEqual(status.devices[4].macaddr, '54-B3-A2-F7-BE-EA')
542
- self.assertIsInstance(status.devices[4].macaddress, macaddress.EUI48)
545
+ self.assertIsInstance(status.devices[4].macaddress, EUI48)
543
546
  self.assertEqual(status.devices[4].ipaddr, '192.168.1.188')
544
- self.assertIsInstance(status.devices[4].ipaddress, ipaddress.IPv4Address)
547
+ self.assertIsInstance(status.devices[4].ipaddress, IPv4Address)
545
548
  self.assertEqual(status.devices[4].hostname, 'name3')
546
549
  self.assertEqual(status.devices[4].packets_sent, None)
547
550
  self.assertEqual(status.devices[4].packets_received, None)
548
551
  self.assertIsInstance(status.devices[5], Device)
549
552
  self.assertEqual(status.devices[5].type, Connection.IOT_6G)
550
553
  self.assertEqual(status.devices[5].macaddr, '3C-AE-E1-83-94-9D')
551
- self.assertIsInstance(status.devices[5].macaddress, macaddress.EUI48)
554
+ self.assertIsInstance(status.devices[5].macaddress, EUI48)
552
555
  self.assertEqual(status.devices[5].ipaddr, '192.168.1.189')
553
- self.assertIsInstance(status.devices[5].ipaddress, ipaddress.IPv4Address)
556
+ self.assertIsInstance(status.devices[5].ipaddress, IPv4Address)
554
557
  self.assertEqual(status.devices[5].hostname, 'name4')
555
558
  self.assertEqual(status.devices[5].packets_sent, None)
556
559
  self.assertEqual(status.devices[5].packets_received, None)
557
560
  self.assertIsInstance(status.devices[6], Device)
558
561
  self.assertEqual(status.devices[6].type, Connection.HOST_5G)
559
562
  self.assertEqual(status.devices[6].macaddr, '1F-7A-BD-F7-20-0D')
560
- self.assertIsInstance(status.devices[6].macaddress, macaddress.EUI48)
563
+ self.assertIsInstance(status.devices[6].macaddress, EUI48)
561
564
  self.assertEqual(status.devices[6].ipaddr, '0.0.0.0')
562
- self.assertIsInstance(status.devices[6].ipaddress, ipaddress.IPv4Address)
565
+ self.assertIsInstance(status.devices[6].ipaddress, IPv4Address)
563
566
  self.assertEqual(status.devices[6].hostname, '')
564
567
  self.assertEqual(status.devices[6].packets_sent, 134815)
565
568
  self.assertEqual(status.devices[6].packets_received, 2953078)
@@ -596,11 +599,11 @@ class TestTPLinkClient(unittest.TestCase):
596
599
  def request(self, path: str, data: str,
597
600
  ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
598
601
  if path == 'admin/status?form=all&operation=read':
599
- return json.loads(response_status)['data']
602
+ return loads(response_status)['data']
600
603
  elif path == 'admin/status?form=perf&operation=read':
601
- return json.loads(perf_stats)['data']
604
+ return loads(perf_stats)['data']
602
605
  elif path == 'admin/wireless?form=statistics':
603
- return json.loads(response_stats)['data']
606
+ return loads(response_stats)['data']
604
607
  raise ClientException()
605
608
 
606
609
  client = TPLinkRouterTest('', '')
@@ -609,7 +612,7 @@ class TestTPLinkClient(unittest.TestCase):
609
612
  self.assertIsInstance(status, Status)
610
613
  self.assertEqual(status.wan_macaddr, None)
611
614
  self.assertEqual(status.lan_macaddr, '06-E6-97-9E-23-F5')
612
- self.assertIsInstance(status.lan_macaddress, macaddress.EUI48)
615
+ self.assertIsInstance(status.lan_macaddress, EUI48)
613
616
  self.assertEqual(status.wan_ipv4_addr, None)
614
617
  self.assertEqual(status.lan_ipv4_addr, None)
615
618
  self.assertEqual(status.wan_ipv4_gateway, None)
@@ -679,4 +682,4 @@ class TestTPLinkClient(unittest.TestCase):
679
682
 
680
683
 
681
684
  if __name__ == '__main__':
682
- unittest.main()
685
+ main()
test/test_client_c1200.py CHANGED
@@ -1,12 +1,13 @@
1
- import unittest
2
- import json
1
+ from unittest import main, TestCase
2
+ from json import loads
3
3
  from tplinkrouterc6u import (
4
4
  TplinkC1200Router,
5
5
  Connection,
6
6
  ClientException
7
7
  )
8
8
 
9
- class TestTPLinkC1200Client(unittest.TestCase):
9
+
10
+ class TestTPLinkC1200Client(TestCase):
10
11
 
11
12
  def test_set_led_on(self) -> None:
12
13
 
@@ -30,18 +31,18 @@ class TestTPLinkC1200Client(unittest.TestCase):
30
31
  def request(self, path: str, data: str,
31
32
  ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
32
33
  if path == 'admin/ledgeneral?form=setting&operation=read':
33
- return json.loads(response_led_general_read)
34
+ return loads(response_led_general_read)
34
35
  if path == 'admin/ledgeneral?form=setting&operation=write':
35
36
  self.captured_path = path
36
- return json.loads(response_led_general_write)
37
+ return loads(response_led_general_write)
37
38
  raise ClientException()
38
39
 
39
40
  client = TPLinkRouterTest('', '')
40
-
41
+
41
42
  client.set_led(True)
42
43
 
43
44
  expected_path = "admin/ledgeneral?form=setting&operation=write"
44
-
45
+
45
46
  self.assertEqual(client.captured_path, expected_path)
46
47
 
47
48
  def test_set_led_off(self) -> None:
@@ -66,10 +67,10 @@ class TestTPLinkC1200Client(unittest.TestCase):
66
67
  def request(self, path: str, data: str,
67
68
  ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
68
69
  if path == 'admin/ledgeneral?form=setting&operation=read':
69
- return json.loads(response_led_general_read)
70
+ return loads(response_led_general_read)
70
71
  elif path == 'admin/ledgeneral?form=setting&operation=write':
71
72
  self.captured_path = path
72
- return json.loads(response_led_general_write)
73
+ return loads(response_led_general_write)
73
74
  raise ClientException()
74
75
 
75
76
  client = TPLinkRouterTest('', '')
@@ -77,7 +78,7 @@ class TestTPLinkC1200Client(unittest.TestCase):
77
78
  client.set_led(False)
78
79
 
79
80
  expected_path = "admin/ledgeneral?form=setting&operation=write"
80
-
81
+
81
82
  self.assertEqual(client.captured_path, expected_path)
82
83
 
83
84
  def test_led_status(self) -> None:
@@ -89,12 +90,12 @@ class TestTPLinkC1200Client(unittest.TestCase):
89
90
  "ledpm_support": "yes"
90
91
  }
91
92
  '''
92
-
93
+
93
94
  class TPLinkRouterTest(TplinkC1200Router):
94
95
  def request(self, path: str, data: str,
95
96
  ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
96
97
  if path == 'admin/ledgeneral?form=setting&operation=read':
97
- return json.loads(response_led_general_read)
98
+ return loads(response_led_general_read)
98
99
  raise ClientException()
99
100
 
100
101
  client = TPLinkRouterTest('', '')
@@ -102,7 +103,6 @@ class TestTPLinkC1200Client(unittest.TestCase):
102
103
  led_status = client.get_led()
103
104
  self.assertTrue(led_status)
104
105
 
105
-
106
106
  def test_set_wifi(self) -> None:
107
107
 
108
108
  class TPLinkRouterTest(TplinkC1200Router):
@@ -128,14 +128,15 @@ class TestTPLinkC1200Client(unittest.TestCase):
128
128
  txpower="20",
129
129
  disabled_all="no"
130
130
  )
131
-
131
+
132
132
  expected_data = ("operation=write&enable=on&ssid=TestSSID&hidden=no&encryption=WPA3-PSK&"
133
133
  "psk_version=2&psk_cipher=AES&psk_key=testkey123&hwmode=11ac&"
134
134
  "htmode=VHT20&channel=36&txpower=20&disabled_all=no")
135
135
  expected_path = f"admin/wireless?form=wireless_5g&{expected_data}"
136
-
136
+
137
137
  self.assertEqual(client.captured_path, expected_path)
138
138
  self.assertEqual(client.captured_data, expected_data)
139
139
 
140
+
140
141
  if __name__ == '__main__':
141
- unittest.main()
142
+ main()