narou 2.6.1 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of narou might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ChangeLog.md +65 -0
- data/README.md +69 -22
- data/lib/command.rb +1 -0
- data/lib/command/alias.rb +2 -2
- data/lib/command/convert.rb +3 -3
- data/lib/command/csv.rb +108 -0
- data/lib/command/download.rb +13 -1
- data/lib/command/freeze.rb +1 -1
- data/lib/command/init.rb +5 -1
- data/lib/command/inspect.rb +1 -1
- data/lib/command/mail.rb +1 -1
- data/lib/command/send.rb +2 -2
- data/lib/command/setting.rb +17 -1
- data/lib/command/tag.rb +28 -9
- data/lib/command/update.rb +57 -30
- data/lib/commandbase.rb +3 -2
- data/lib/commandline.rb +2 -2
- data/lib/converterbase.rb +70 -7
- data/lib/database.rb +1 -1
- data/lib/device.rb +3 -0
- data/lib/device/ibooks.rb +2 -2
- data/lib/device/ibunko.rb +4 -0
- data/lib/diffviewer.rb +2 -2
- data/lib/downloader.rb +16 -9
- data/lib/helper.rb +53 -22
- data/lib/inventory.rb +6 -2
- data/lib/narou.rb +13 -6
- data/lib/novelconverter.rb +35 -13
- data/lib/novelsetting.rb +7 -1
- data/lib/version.rb +1 -1
- data/lib/web/appserver.rb +78 -8
- data/lib/web/public/resources/common.ui.js +0 -39
- data/lib/web/public/resources/dataTables.colVis.js +1 -1
- data/lib/web/public/resources/default-style.css +1 -1
- data/lib/web/public/resources/help/bookmarklet1.png +0 -0
- data/lib/web/public/resources/help/bookmarklet2.png +0 -0
- data/lib/web/public/resources/images/dl_button0.gif +0 -0
- data/lib/web/public/resources/images/dl_button1.gif +0 -0
- data/lib/web/public/resources/narou.library.js +268 -36
- data/lib/web/public/resources/narou.queue.js +51 -0
- data/lib/web/public/resources/narou.ui.js +156 -59
- data/lib/web/settingmessages.rb +2 -1
- data/lib/web/views/{js/widget.erb → bookmarklet/download.js.erb} +1 -1
- data/lib/web/views/bookmarklet/insert_button.js.erb +133 -0
- data/lib/web/views/help.haml +31 -14
- data/lib/web/views/index.haml +62 -0
- data/lib/web/views/layout.haml +8 -7
- data/lib/web/views/parts/csv_import.haml +68 -0
- data/lib/web/views/parts/download_form.haml +89 -0
- data/lib/web/views/settings.haml +8 -3
- data/lib/web/views/style.scss +200 -14
- data/lib/web/views/{widget.haml → widget/download.haml} +18 -4
- data/lib/web/views/widget/drag_and_drop.haml +97 -0
- data/lib/web/worker.rb +39 -1
- data/narou.gemspec +56 -56
- data/preset/custom_chuki_tag.txt +1 -1
- data/preset/doubledash.png +0 -0
- data/preset/singledash.png +0 -0
- data/preset/vertical_font.css +1 -1
- data/spec/convert_spec.rb +5 -1
- data/spec/data/convert_test/auto_join_line/correct_test_auto_join_line.txt +6 -0
- data/spec/data/convert_test/auto_join_line/test_auto_join_line.txt +8 -0
- data/spec/data/convert_test/double_dash_to_image/correct_test_double_dash_to_image.txt +14 -0
- data/spec/data/convert_test/double_dash_to_image/setting.ini +1 -0
- data/spec/data/convert_test/double_dash_to_image/test_double_dash_to_image.txt +12 -0
- data/spec/worker_spec.rb +21 -2
- metadata +97 -60
data/lib/web/views/settings.haml
CHANGED
@@ -51,7 +51,7 @@
|
|
51
51
|
|
52
52
|
.container.container-main.theme-showcase(role="main")
|
53
53
|
.container-settings
|
54
|
-
- inventory = Inventory.load("local_setting"
|
54
|
+
- inventory = Inventory.load("local_setting").merge(Inventory.load("global_setting", :global))
|
55
55
|
- local_and_global_variables = @setting_variables[:local].merge(@setting_variables[:global])
|
56
56
|
- tab_info = Command::Setting.get_setting_tab_info
|
57
57
|
- error_tabs = @error_list.map { |name, _| local_and_global_variables[name][:tab] }.uniq
|
@@ -120,14 +120,19 @@
|
|
120
120
|
- when :select
|
121
121
|
%div.input-style
|
122
122
|
%select{name: name, class: "selectpicker show-tick"}
|
123
|
-
%option(value="")
|
123
|
+
%option(value="")
|
124
|
+
- if name == "theme"
|
125
|
+
デフォルト
|
126
|
+
- else
|
127
|
+
未設定
|
124
128
|
- value[:select_keys].each_with_index do |key, index|
|
125
129
|
%option{selected: item == key, value: key}
|
126
130
|
= value[:select_summaries][index]
|
127
131
|
- need_clear = true
|
128
132
|
- when :multiple
|
129
133
|
%div.input-style
|
130
|
-
%select{name: "#{name}[]", class: "selectpicker", multiple: true,
|
134
|
+
%select{name: "#{name}[]", class: "selectpicker", multiple: true,
|
135
|
+
title: "未設定", "data-selected-text-format" => "count"}
|
131
136
|
- selected_items = item.to_s.split(",")
|
132
137
|
- value[:select_keys].each_with_index do |key, index|
|
133
138
|
%option{selected: selected_items.include?(key), value: key}
|
data/lib/web/views/style.scss
CHANGED
@@ -67,6 +67,18 @@ body {
|
|
67
67
|
top: 100px;
|
68
68
|
}
|
69
69
|
|
70
|
+
button[disabled] {
|
71
|
+
cursor: default !important;
|
72
|
+
}
|
73
|
+
|
74
|
+
/*
|
75
|
+
* プログレスバー
|
76
|
+
*/
|
77
|
+
.progress-bar {
|
78
|
+
// アニメーションを切る
|
79
|
+
@include css3(transition, none !important);
|
80
|
+
}
|
81
|
+
|
70
82
|
/*
|
71
83
|
* テーブル関連
|
72
84
|
*/
|
@@ -204,7 +216,7 @@ table#novel-list {
|
|
204
216
|
content: " 更新";
|
205
217
|
}
|
206
218
|
|
207
|
-
/* 最新話更新日
|
219
|
+
/* 最新話更新日 */
|
208
220
|
.general-lastup {
|
209
221
|
}
|
210
222
|
/* 60分以内 */
|
@@ -366,7 +378,7 @@ table.dataTable {
|
|
366
378
|
width: 200px;
|
367
379
|
}
|
368
380
|
@media (min-width:768px) {
|
369
|
-
width:
|
381
|
+
width: 100px;
|
370
382
|
}
|
371
383
|
@media (min-width:992px){
|
372
384
|
width: 250px;
|
@@ -402,33 +414,52 @@ input::-ms-clear {
|
|
402
414
|
/*
|
403
415
|
* タグ
|
404
416
|
*/
|
417
|
+
.select-color-button {
|
418
|
+
float: right;
|
419
|
+
}
|
420
|
+
.select-color-button span {
|
421
|
+
display: inline-block;
|
422
|
+
width: 1.4em;
|
423
|
+
height: 1.4em;
|
424
|
+
border-radius: 0.7em;
|
425
|
+
text-align: center;
|
426
|
+
cursor: pointer;
|
427
|
+
color: white;
|
428
|
+
font-weight: bold;
|
429
|
+
}
|
430
|
+
|
405
431
|
.label {
|
406
432
|
cursor: pointer;
|
407
433
|
}
|
408
|
-
.label-green {
|
434
|
+
.label-green, .select-color-button .green {
|
409
435
|
background-color: #5cb85c;
|
410
436
|
}
|
411
|
-
.label-yellow {
|
437
|
+
.label-yellow, .select-color-button .yellow {
|
412
438
|
background-color: #f7d71e;
|
413
439
|
color: #666;
|
414
440
|
}
|
415
|
-
.label-blue {
|
441
|
+
.label-blue, .select-color-button .blue {
|
416
442
|
background-color: #428bca;
|
417
443
|
}
|
418
|
-
.label-magenta {
|
444
|
+
.label-magenta, .select-color-button .magenta {
|
419
445
|
background-color: #d37bca;
|
420
446
|
}
|
421
|
-
.label-cyan {
|
447
|
+
.label-cyan, .select-color-button .cyan {
|
422
448
|
background-color: #5bc0de;
|
423
449
|
}
|
424
|
-
.label-red {
|
450
|
+
.label-red, .select-color-button .red {
|
425
451
|
background-color: #d9534f;
|
426
452
|
}
|
427
|
-
.label-white {
|
453
|
+
.label-white, .select-color-button .white {
|
428
454
|
background-color: #e3e3e3;
|
429
455
|
color: #666;
|
430
456
|
}
|
431
457
|
|
458
|
+
.label-fixed-width {
|
459
|
+
display: inline-block;
|
460
|
+
width: 100%;
|
461
|
+
}
|
462
|
+
|
432
463
|
.dataTable {
|
433
464
|
.label {
|
434
465
|
font-size: 0.8em;
|
@@ -490,11 +521,42 @@ input::-ms-clear {
|
|
490
521
|
* 選択メニュー
|
491
522
|
*/
|
492
523
|
#rect-select-menu {
|
493
|
-
position: absolute;
|
494
|
-
display: none;
|
495
524
|
z-index: 101;
|
496
525
|
}
|
497
526
|
|
527
|
+
/*
|
528
|
+
* 色選択メニュー
|
529
|
+
*/
|
530
|
+
#select-color-menu {
|
531
|
+
position: fixed;
|
532
|
+
z-index: 9999;
|
533
|
+
border-color: #bbb;
|
534
|
+
background-color: white;
|
535
|
+
min-width: 130px;
|
536
|
+
}
|
537
|
+
#select-color-menu:before {
|
538
|
+
content: "";
|
539
|
+
position: absolute;
|
540
|
+
display: block;
|
541
|
+
top: 20px;
|
542
|
+
left: -18px;
|
543
|
+
border-style: solid;
|
544
|
+
border-width: 9px;
|
545
|
+
border-color: transparent white transparent transparent;
|
546
|
+
z-index: 10001;
|
547
|
+
}
|
548
|
+
#select-color-menu:after {
|
549
|
+
content: "";
|
550
|
+
position: absolute;
|
551
|
+
display: block;
|
552
|
+
top: 20px;
|
553
|
+
left: -19px;
|
554
|
+
border-style: solid;
|
555
|
+
border-width: 9px;
|
556
|
+
border-color: transparent #bbb transparent transparent;
|
557
|
+
z-index: 10000;
|
558
|
+
}
|
559
|
+
|
498
560
|
/*
|
499
561
|
* 範囲選択時の半透明範囲
|
500
562
|
*/
|
@@ -727,8 +789,6 @@ $console-color: white;
|
|
727
789
|
* 個別メニュー
|
728
790
|
*/
|
729
791
|
#context-menu {
|
730
|
-
position: absolute;
|
731
|
-
display: none;
|
732
792
|
z-index: 102;
|
733
793
|
}
|
734
794
|
|
@@ -785,6 +845,16 @@ $console-color: white;
|
|
785
845
|
width: 100%;
|
786
846
|
}
|
787
847
|
}
|
848
|
+
#ss-bookmarklet1, #ss-bookmarklet2 {
|
849
|
+
@media (min-width: 601px) {
|
850
|
+
float: right;
|
851
|
+
width: 300px;
|
852
|
+
margin-left: 15px;
|
853
|
+
}
|
854
|
+
@media (max-width: 600px) {
|
855
|
+
width: 100%;
|
856
|
+
}
|
857
|
+
}
|
788
858
|
|
789
859
|
h4 {
|
790
860
|
margin-top: 25px;
|
@@ -801,8 +871,53 @@ $console-color: white;
|
|
801
871
|
div > p{
|
802
872
|
text-indent: 1em;
|
803
873
|
}
|
874
|
+
|
875
|
+
h2 {
|
876
|
+
margin-bottom: 25px;
|
877
|
+
}
|
878
|
+
h3 {
|
879
|
+
position: relative;
|
880
|
+
font-size: 1.143em;
|
881
|
+
font-weight: bold;
|
882
|
+
margin: 0 0 1.0em;
|
883
|
+
padding: 0.5em 0.5em 0.5em 1.7em;
|
884
|
+
border-bottom: 3px solid #d94A4C;
|
885
|
+
width: 100%;
|
886
|
+
}
|
887
|
+
h3:before {
|
888
|
+
content: "";
|
889
|
+
position: absolute;
|
890
|
+
background: #d48789;
|
891
|
+
top: 0;
|
892
|
+
left: 0.4em;
|
893
|
+
height: 12px;
|
894
|
+
width: 12px;
|
895
|
+
transform: rotate(45deg);
|
896
|
+
-moz-transform: rotate(45deg);
|
897
|
+
-webkit-transform: rotate(45deg);
|
898
|
+
-o-transform: rotate(45deg);
|
899
|
+
-ms-transform: rotate(45deg);
|
900
|
+
}
|
901
|
+
h3:after {
|
902
|
+
content: "";
|
903
|
+
position: absolute;
|
904
|
+
background:#d26466;
|
905
|
+
top: 1.0em;
|
906
|
+
left: 0;
|
907
|
+
height: 8px;
|
908
|
+
width: 8px;
|
909
|
+
transform: rotate(15deg);
|
910
|
+
-moz-transform: rotate(15deg);
|
911
|
+
-webkit-transform: rotate(15deg);
|
912
|
+
-o-transform: rotate(15deg);
|
913
|
+
-ms-transform: rotate(15deg);
|
914
|
+
}
|
915
|
+
h3:nth-of-type(2) {
|
916
|
+
margin-top: 30px;
|
917
|
+
}
|
918
|
+
|
804
919
|
p {
|
805
|
-
margin-bottom:
|
920
|
+
margin-bottom: 2px;
|
806
921
|
}
|
807
922
|
}
|
808
923
|
|
@@ -851,3 +966,74 @@ $console-color: white;
|
|
851
966
|
color: #777;
|
852
967
|
}
|
853
968
|
}
|
969
|
+
|
970
|
+
/* D&D関係 */
|
971
|
+
#link-drop-here {
|
972
|
+
position: fixed;
|
973
|
+
top: 0;
|
974
|
+
display: none;
|
975
|
+
width: 100%;
|
976
|
+
height: 100%;
|
977
|
+
text-align: center;
|
978
|
+
vertical-align: middle;
|
979
|
+
color: white;
|
980
|
+
font-size: 100px;
|
981
|
+
background-color: rgba(0, 0, 0, 0.7);
|
982
|
+
z-index: 2000;
|
983
|
+
}
|
984
|
+
#link-drop-here .inner {
|
985
|
+
position: absolute;
|
986
|
+
display: table;
|
987
|
+
width: 95%;
|
988
|
+
height: 95%;
|
989
|
+
top: 2.5%;
|
990
|
+
left: 2.5%;
|
991
|
+
border: 6px dashed white;
|
992
|
+
}
|
993
|
+
#link-drop-here .inner .glyphicon {
|
994
|
+
display: table-cell;
|
995
|
+
vertical-align: middle;
|
996
|
+
}
|
997
|
+
.drop-cover {
|
998
|
+
position: absolute;
|
999
|
+
top: 0;
|
1000
|
+
width: 100%;
|
1001
|
+
height: 100%;
|
1002
|
+
background-color: transparent;
|
1003
|
+
}
|
1004
|
+
|
1005
|
+
/* CSVインポート関係 */
|
1006
|
+
#csv-drop-here {
|
1007
|
+
position: relative;
|
1008
|
+
width: 100%;
|
1009
|
+
height: 150px;
|
1010
|
+
border: 4px dashed lightgray;
|
1011
|
+
color: lightgray;
|
1012
|
+
transition: border-color 0.4s ease, background-color 0.4s ease, color 0.4s ease;
|
1013
|
+
|
1014
|
+
&.dragover {
|
1015
|
+
border: 4px dashed #ada;
|
1016
|
+
background-color: #efe;
|
1017
|
+
color: #5cb85c;
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
.inner {
|
1021
|
+
position: absolute;
|
1022
|
+
display: table;
|
1023
|
+
width: 100%;
|
1024
|
+
height: 100%;
|
1025
|
+
text-align: center;
|
1026
|
+
font-size: 1.5em;
|
1027
|
+
font-weight: bold;
|
1028
|
+
|
1029
|
+
& > div {
|
1030
|
+
display: table-cell;
|
1031
|
+
vertical-align: middle;
|
1032
|
+
}
|
1033
|
+
|
1034
|
+
.else {
|
1035
|
+
color: lightgray;
|
1036
|
+
font-size: 0.6em;
|
1037
|
+
}
|
1038
|
+
}
|
1039
|
+
}
|
@@ -7,9 +7,10 @@
|
|
7
7
|
%meta{:content => "whiteleaf", :name => "author"}/
|
8
8
|
%meta{:content => "none", :name => "robots"}/
|
9
9
|
%title Narou.rb WEB UI Widget
|
10
|
-
%link{:href => "//maxcdn.bootstrapcdn.com/bootstrap/3.
|
10
|
+
%link{:href => "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css", :rel => "stylesheet"}/
|
11
11
|
%link{:href => "/resources/perfect-scrollbar.min.css", :rel => "stylesheet"}/
|
12
|
-
%link{:href => "/style.css", :rel => "stylesheet"}/
|
12
|
+
%link{:href => "/style.css?_=#{Version}", :rel => "stylesheet"}/
|
13
|
+
%link{:href => "/resources/default-style.css?_=#{Version}", :rel => "stylesheet"}/
|
13
14
|
/ HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries
|
14
15
|
/[if lt IE 9]
|
15
16
|
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
@@ -21,12 +22,25 @@
|
|
21
22
|
margin: 0;
|
22
23
|
padding: 0;
|
23
24
|
}
|
25
|
+
#queue-text {
|
26
|
+
position: absolute;
|
27
|
+
top: 3px;
|
28
|
+
right: 3px;
|
29
|
+
color: white;
|
30
|
+
margin: 0;
|
31
|
+
padding: 0;
|
32
|
+
}
|
33
|
+
|
24
34
|
#console.console.fullscreen
|
35
|
+
#queue-text.navbar-text.navbar-right
|
36
|
+
%span.glyphicon.glyphicon-inbox
|
37
|
+
%span#queue 0
|
25
38
|
|
26
39
|
%script{:src => "//code.jquery.com/jquery-1.11.1.min.js"}
|
27
|
-
%script{:src => "//maxcdn.bootstrapcdn.com/bootstrap/3.
|
40
|
+
%script{:src => "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"}
|
28
41
|
%script{:src => "/resources/perfect-scrollbar.min.js"}
|
29
|
-
%script{:src => "/resources/narou.library.js"}
|
42
|
+
%script{:src => "/resources/narou.library.js?_=#{Version}"}
|
43
|
+
%script{:src => "/resources/narou.queue.js?_=#{Version}"}
|
30
44
|
:javascript
|
31
45
|
$(document).ready(function($) {
|
32
46
|
var notification = new Narou.Notification();
|
@@ -0,0 +1,97 @@
|
|
1
|
+
-# リンクのドラッグ&ドロップでダウンロードできるウィンドウ
|
2
|
+
!!! 5
|
3
|
+
%html{:lang => "ja"}
|
4
|
+
%head
|
5
|
+
%meta{:charset => "utf-8"}/
|
6
|
+
%meta{:content => "IE=edge", "http-equiv" => "X-UA-Compatible"}/
|
7
|
+
%meta{:content => "width=device-width, initial-scale=1", :name => "viewport"}/
|
8
|
+
%meta{:content => "whiteleaf", :name => "author"}/
|
9
|
+
%meta{:content => "none", :name => "robots"}/
|
10
|
+
%title Narou.rb DnD Window
|
11
|
+
%link{:href => "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css", :rel => "stylesheet"}/
|
12
|
+
%link{:href => "/resources/perfect-scrollbar.min.css", :rel => "stylesheet"}/
|
13
|
+
%link{:href => "/style.css?_=#{Version}", :rel => "stylesheet"}/
|
14
|
+
%link{:href => "/resources/default-style.css?_=#{Version}", :rel => "stylesheet"}/
|
15
|
+
/ HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries
|
16
|
+
/[if lt IE 9]
|
17
|
+
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
18
|
+
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
19
|
+
%body
|
20
|
+
:css
|
21
|
+
html, body, .console {
|
22
|
+
position: relative;
|
23
|
+
height: 100%;
|
24
|
+
margin: 0;
|
25
|
+
padding: 0;
|
26
|
+
}
|
27
|
+
#information {
|
28
|
+
position: absolute;
|
29
|
+
width: 100%;
|
30
|
+
top: 50%;
|
31
|
+
margin-top: -1em;
|
32
|
+
text-align: center;
|
33
|
+
color: white;
|
34
|
+
font-size: 20px;
|
35
|
+
font-weight: bold;
|
36
|
+
opacity: 0.17;
|
37
|
+
filter: alpha(opacity=17);
|
38
|
+
}
|
39
|
+
#queue-text {
|
40
|
+
position: absolute;
|
41
|
+
top: 3px;
|
42
|
+
right: 3px;
|
43
|
+
color: white;
|
44
|
+
margin: 0;
|
45
|
+
padding: 0;
|
46
|
+
}
|
47
|
+
|
48
|
+
#console.console.fullscreen
|
49
|
+
#information
|
50
|
+
このウィンドウ内にダウンロードしたい<br>
|
51
|
+
小説のリンクをドラッグ&ドロップ
|
52
|
+
#queue-text.navbar-text.navbar-right
|
53
|
+
%span.glyphicon.glyphicon-inbox
|
54
|
+
%span#queue 0
|
55
|
+
#link-drop-here
|
56
|
+
.inner
|
57
|
+
.glyphicon.glyphicon-download-alt
|
58
|
+
#link-drop-cover.drop-cover(effectAllowed="all")
|
59
|
+
|
60
|
+
%script{:src => "//code.jquery.com/jquery-1.11.1.min.js"}
|
61
|
+
%script{:src => "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"}
|
62
|
+
%script{:src => "/resources/perfect-scrollbar.min.js"}
|
63
|
+
%script{:src => "/resources/narou.library.js?_=#{Version}"}
|
64
|
+
%script{:src => "/resources/narou.queue.js?_=#{Version}"}
|
65
|
+
:javascript
|
66
|
+
$(document).ready(function($) {
|
67
|
+
$("#link-drop-here").hide();
|
68
|
+
|
69
|
+
var action = new Narou.Action(null);
|
70
|
+
var notification = new Narou.Notification;
|
71
|
+
var stream_console = new Narou.Console(notification, {
|
72
|
+
restore: false, buttons: false
|
73
|
+
});
|
74
|
+
var dnd = new Narou.DragDrop;
|
75
|
+
|
76
|
+
$(window).on("dragenter", function(e) {
|
77
|
+
$("#link-drop-here").show();
|
78
|
+
});
|
79
|
+
|
80
|
+
$("#link-drop-cover")
|
81
|
+
.on("dragover", function(e) {
|
82
|
+
e.preventDefault();
|
83
|
+
e.dataTransfer.dropEffect = "copy";
|
84
|
+
return false;
|
85
|
+
})
|
86
|
+
.on("dragleave", function(e) {
|
87
|
+
$("#link-drop-here").hide();
|
88
|
+
})
|
89
|
+
.on("drop", function(e) {
|
90
|
+
e.preventDefault();
|
91
|
+
dnd.getLinkText(e, function(link) {
|
92
|
+
action.download(link);
|
93
|
+
});
|
94
|
+
$("#link-drop-here").hide();
|
95
|
+
});
|
96
|
+
});
|
97
|
+
|