gnms 2.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of gnms might be problematic. Click here for more details.

Files changed (140) hide show
  1. data/LICENSE +459 -0
  2. data/README +29 -0
  3. data/bin/gnms +11 -0
  4. data/gnms.gemspec +70 -0
  5. data/lib/cmd_parse.rb +747 -0
  6. data/lib/config_global.rb +414 -0
  7. data/lib/contact.rb +171 -0
  8. data/lib/external/crypt/blowfish-tables.rb +190 -0
  9. data/lib/external/crypt/blowfish.rb +110 -0
  10. data/lib/external/crypt/cbc.rb +123 -0
  11. data/lib/external/crypt/stringxor.rb +27 -0
  12. data/lib/external/fog.rb +41 -0
  13. data/lib/external/jjmx.rb +45 -0
  14. data/lib/external/sms.rb +282 -0
  15. data/lib/external/xmpp4r-simple.rb +497 -0
  16. data/lib/format.rb +85 -0
  17. data/lib/gnms.rb +329 -0
  18. data/lib/gui/about_window.rb +177 -0
  19. data/lib/gui/adddelnode.rb +799 -0
  20. data/lib/gui/base_window.rb +789 -0
  21. data/lib/gui/canvas_map.rb +498 -0
  22. data/lib/gui/charts/gruff.rb +51 -0
  23. data/lib/gui/color_macro.rb +145 -0
  24. data/lib/gui/config_window.rb +2151 -0
  25. data/lib/gui/custom_plugin_window.rb +90 -0
  26. data/lib/gui/debug_window.rb +46 -0
  27. data/lib/gui/event_window.rb +469 -0
  28. data/lib/gui/find_node_window.rb +438 -0
  29. data/lib/gui/help_window.rb +47 -0
  30. data/lib/gui/ipcalculator.rb +147 -0
  31. data/lib/gui/jmx_ref_window.rb +309 -0
  32. data/lib/gui/link_view.rb +46 -0
  33. data/lib/gui/mib_browser.rb +585 -0
  34. data/lib/gui/node_host_property.rb +3712 -0
  35. data/lib/gui/node_host_view.rb +270 -0
  36. data/lib/gui/node_network_property.rb +1059 -0
  37. data/lib/gui/node_network_view.rb +186 -0
  38. data/lib/gui/node_view.rb +672 -0
  39. data/lib/gui/oid_ref_window.rb +288 -0
  40. data/lib/gui/snmptrap_ref_window.rb +288 -0
  41. data/lib/gui/sub/account_frame.rb +196 -0
  42. data/lib/gui/sub/contact_frame.rb +519 -0
  43. data/lib/gui/syslog_ref_window.rb +288 -0
  44. data/lib/gui/treenode_window.rb +320 -0
  45. data/lib/gui/update_window.rb +124 -0
  46. data/lib/gui/widgets.rb +169 -0
  47. data/lib/gui/wmi_ref_window.rb +286 -0
  48. data/lib/interface.rb +16 -0
  49. data/lib/ipcalc.rb +266 -0
  50. data/lib/link.rb +45 -0
  51. data/lib/main.rb +1091 -0
  52. data/lib/monitor/client/custom/custom_monitoring.rb +40 -0
  53. data/lib/monitor/client/jmx/jmx_attr_monitoring.rb +36 -0
  54. data/lib/monitor/client/jmx/jmx_monitoring.rb +83 -0
  55. data/lib/monitor/client/jmx/jmx_ref.rb +114 -0
  56. data/lib/monitor/client/snmp/mibs/SNMPv2-MIB.txt +854 -0
  57. data/lib/monitor/client/snmp/mibs/SNMPv2-SMI.txt +344 -0
  58. data/lib/monitor/client/snmp/oid_ref.rb +141 -0
  59. data/lib/monitor/client/snmp/snmp.rb +178 -0
  60. data/lib/monitor/client/snmp/snmp_monitoring.rb +58 -0
  61. data/lib/monitor/client/wmi/wmi.rb +139 -0
  62. data/lib/monitor/client/wmi/wmi_monitoring.rb +60 -0
  63. data/lib/monitor/client/wmi/wmi_ref.rb +141 -0
  64. data/lib/monitor/custom_plugin.rb +50 -0
  65. data/lib/monitor/server/msg_buffer.rb +39 -0
  66. data/lib/monitor/server/snmp/snmptrap_analyzer.rb +81 -0
  67. data/lib/monitor/server/snmp/snmptrap_capture.rb +26 -0
  68. data/lib/monitor/server/snmp/snmptrap_monitoring.rb +32 -0
  69. data/lib/monitor/server/snmp/snmptrap_ref.rb +135 -0
  70. data/lib/monitor/server/snmp/snmptrap_server.rb +50 -0
  71. data/lib/monitor/server/syslog/syslog_analyzer.rb +141 -0
  72. data/lib/monitor/server/syslog/syslog_capture.rb +28 -0
  73. data/lib/monitor/server/syslog/syslog_monitoring.rb +32 -0
  74. data/lib/monitor/server/syslog/syslog_ref.rb +136 -0
  75. data/lib/monitor/server/syslog/syslog_server.rb +43 -0
  76. data/lib/node.rb +1020 -0
  77. data/lib/node_db.rb +2668 -0
  78. data/lib/node_host.rb +215 -0
  79. data/lib/node_listener.rb +639 -0
  80. data/lib/node_network.rb +269 -0
  81. data/lib/node_property.rb +39 -0
  82. data/lib/notify/alarm.rb +247 -0
  83. data/lib/notify/irc_bot.rb +167 -0
  84. data/lib/notify/xmpp_bot.rb +107 -0
  85. data/lib/service.rb +36 -0
  86. data/lib/version.rb +8 -0
  87. data/pixmap/bg/map_bg.jpg +0 -0
  88. data/pixmap/bg/map_bg2.jpg +0 -0
  89. data/pixmap/logo.jpg +0 -0
  90. data/pixmap/logo_icon.png +0 -0
  91. data/pixmap/os/3com.png +0 -0
  92. data/pixmap/os/aix.gif +0 -0
  93. data/pixmap/os/amiga.png +0 -0
  94. data/pixmap/os/beos.png +0 -0
  95. data/pixmap/os/cisco.png +0 -0
  96. data/pixmap/os/freebsd.png +0 -0
  97. data/pixmap/os/hp.png +0 -0
  98. data/pixmap/os/hurd.gif +0 -0
  99. data/pixmap/os/irix.gif +0 -0
  100. data/pixmap/os/linux.png +0 -0
  101. data/pixmap/os/mac.png +0 -0
  102. data/pixmap/os/netbsd.gif +0 -0
  103. data/pixmap/os/netware.png +0 -0
  104. data/pixmap/os/openbsd.png +0 -0
  105. data/pixmap/os/os2warp.gif +0 -0
  106. data/pixmap/os/qnx.gif +0 -0
  107. data/pixmap/os/sco.gif +0 -0
  108. data/pixmap/os/sgi.xpm +111 -0
  109. data/pixmap/os/solaris.gif +0 -0
  110. data/pixmap/os/unix.gif +0 -0
  111. data/pixmap/os/unknown.png +0 -0
  112. data/pixmap/os/vms.xpm +345 -0
  113. data/pixmap/os/windows.png +0 -0
  114. data/pixmap/type/cloud.png +0 -0
  115. data/pixmap/type/device.png +0 -0
  116. data/pixmap/type/firewall.png +0 -0
  117. data/pixmap/type/gateway.png +0 -0
  118. data/pixmap/type/home.png +0 -0
  119. data/pixmap/type/host.png +0 -0
  120. data/pixmap/type/network.png +0 -0
  121. data/pixmap/type/printer.png +0 -0
  122. data/pixmap/type/router.png +0 -0
  123. data/pixmap/type/server.png +0 -0
  124. data/pixmap/type/switch.png +0 -0
  125. data/pixmap/type/vm.png +0 -0
  126. data/plugins/Defaultme.rb +7 -0
  127. data/plugins/DnsCheck.rb +46 -0
  128. data/plugins/FooMonitor.rb +26 -0
  129. data/plugins/HttpVirtualHostMonitor.rb +43 -0
  130. data/plugins/MysqlShowStatusMonitor.rb +64 -0
  131. data/plugins/PgsqlPercentConnectionMonitor.rb +72 -0
  132. data/plugins/SshCpuLoadMonitor.rb +85 -0
  133. data/plugins/SshDiskMonitor.rb +69 -0
  134. data/plugins/SshFgtAvExpiredMonitor.rb +75 -0
  135. data/plugins/SshPercentUsedRamMonitor.rb +74 -0
  136. data/plugins/TelnetCpuLoadMonitor.rb +69 -0
  137. data/plugins/example1.rb +15 -0
  138. data/plugins/example2.rb +7 -0
  139. data/sound/beep.wav +0 -0
  140. metadata +378 -0
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env ruby
2
+ #doing my own class here as the xmpp project seems not maintain anymore
3
+
4
+ require 'socket'
5
+
6
+ class IrcBot
7
+
8
+ def initialize()
9
+ if $config.irc_daemon && ($config.irc_server != "")
10
+ @buff = MsgBuffer.new(1)
11
+ @connected = 0
12
+ @channel = $config.irc_channel
13
+ if !@channel or @channel == ""
14
+ $log.error("IRC bot error: channel not set")
15
+ return false
16
+ end
17
+ @server = $config.irc_server
18
+ @port = isInteger($config.irc_port) ? $config.irc_port : 6667
19
+ @botname = "gnmsbot"
20
+ $log.info("Starting IRC bot #{@server}:#{@port} on channel ##{@channel}")
21
+ begin
22
+ @socket = TCPSocket.open(@server, @port)
23
+ rescue Exception => msg
24
+ $log.error("IRC bot error: #{msg}")
25
+ return false
26
+ end
27
+ try_join(@botname)
28
+ run()
29
+ end
30
+ end
31
+
32
+ def try_join(nm)
33
+ say "NICK #{nm}"
34
+ say "USER #{nm} 0 * #{nm}"
35
+ #try to join
36
+ say "JOIN ##{@channel}"
37
+ end
38
+
39
+ def say(msg)
40
+ $log.debug("IRC bot sent: #{msg}")
41
+ @socket.puts msg
42
+ end
43
+
44
+ def say_to_chan(msg)
45
+ $log.debug("IRC bot sent: #{msg}")
46
+ say "PRIVMSG ##{@channel} :#{msg}"
47
+ end
48
+
49
+ def say_to_user(user, msg)
50
+ $log.debug("IRC bot sent to #{user}: #{msg}")
51
+ say "PRIVMSG #{user} :#{msg}"
52
+ end
53
+
54
+ def run
55
+ @sender = Thread.start do
56
+ while $config.irc_daemon
57
+ send_messages if @buff.full?
58
+ Thread.pass
59
+ sleep(2)
60
+ end
61
+ $log.debug("end of IrcBot sender thread")
62
+ end
63
+ @receiver = Thread.start do
64
+ until $config.irc_daemon and @socket.eof? do
65
+ msg = @socket.gets
66
+ if (msg)
67
+ msg.chomp!
68
+ $log.debug("IRC bot received: #{msg}")
69
+
70
+ if msg.match(/^PING :(.*)$/)
71
+ say "PONG #{$~[1]}"
72
+ next
73
+ end
74
+
75
+ if msg.match(/:(.+)!~.+ PRIVMSG #{@botname} :(.*)$/)
76
+ sender = $~[1]
77
+ content = $~[2]
78
+ if sender != ""
79
+ if content and content.match(/^status$/)
80
+ $host.each_value {|node|
81
+ say_to_user(sender, "IP #{node.ip} status is #{$status[$status_value.index(node.status)]}")
82
+ }
83
+ else
84
+ say_to_user(sender, "status - display stats regarding known hosts")
85
+ end
86
+ end
87
+ next
88
+ end
89
+
90
+ if msg.match(/PRIVMSG ##{@channel} :(.*)$/)
91
+ content = $~[1]
92
+ if content.match(/^beer$/)
93
+ say_to_chan "Gimme a free beeeeeeeer"
94
+ end
95
+ next
96
+ end
97
+
98
+ if msg.match(/\s433\s/)
99
+ if @connected == 0
100
+ #nickname may be already in use
101
+ @botname += "-#{rand(2**256).to_s(36)[0..4]}"
102
+ $log.info("Irc bot renamed to #{@botname}")
103
+ try_join(@botname)
104
+ @connected = 1
105
+ else
106
+ $log.fatal("Irc bot can't connect #{msg}")
107
+ stop()
108
+ end
109
+ next
110
+ end
111
+
112
+ if msg.match(/:End of \/MOTD/)
113
+ #as there was a MOTD the join may have not succeed
114
+ say "JOIN ##{@channel}"
115
+ @connected = 1
116
+ next
117
+ end
118
+ end
119
+ Thread.pass
120
+ end
121
+ $log.debug("end of IrcBot receiver thread")
122
+ end
123
+ end
124
+
125
+ def add_in_queue(msg)
126
+ $log.debug("irc message added in queue")
127
+ if $config.irc_daemon
128
+ @buff.put msg unless !@buff
129
+ end
130
+ end
131
+
132
+ def stop()
133
+ if defined?(@sender) && (@sender != nil)
134
+ $log.info("Stopping IRC bot")
135
+ quit()
136
+ sleep(1)
137
+ Thread.kill(@sender)
138
+ Thread.kill(@receiver) if @receiver != nil
139
+ @socket.close
140
+ @connected = 0
141
+ $log.debug("end of IrcBot threads")
142
+ end
143
+ end
144
+
145
+ def quit
146
+ say "PART ##{@channel} :Bye"
147
+ say 'QUIT'
148
+ end
149
+
150
+ private
151
+ def send_messages()
152
+ while @connected and @buff.has_more?
153
+ irc_msg=@buff.get
154
+ if irc_msg != nil
155
+ begin
156
+ say_to_chan(irc_msg)
157
+ sleep(1)
158
+ Thread.pass if @buff.full?
159
+ rescue Exception => msg
160
+ #catch when stream is closed by close() method
161
+ $log.error(msg)
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ end
@@ -0,0 +1,107 @@
1
+ begin
2
+ require "#{GNMSLIB}"+'/external/xmpp4r-simple.rb'
3
+ rescue LoadError
4
+ $log.error("Xmpp4r is not installed, you should install the gem to have IM notification")
5
+ end
6
+
7
+ class XmppBot
8
+ def initialize()
9
+ #Jabber::debug = true
10
+ if $config.im_daemon && ($config.im_login != "")
11
+ @buff=MsgBuffer.new(1)
12
+ $log.info("Starting XMPP bot")
13
+ begin
14
+ timeout(10) {@messenger = Jabber::Simple.new($config.im_login, $config.im_password)}
15
+ rescue Timeout::Error
16
+ $log.error("XMPP bot error: can't connect to #{$config.im_login}")
17
+ return false
18
+ rescue Exception=> msg
19
+ $log.error("XMPP bot error: #{msg}")
20
+ return false
21
+ end
22
+ @sender = Thread.start do
23
+ while $config.im_daemon
24
+ send_messages if @buff.full?
25
+ sleep(2)
26
+ Thread.pass
27
+ @messenger.received_messages do |msg|
28
+ $log.debug("Send from "+ msg.from.node+"@"+msg.from.domain + " \"#{msg.body}\"")
29
+ case msg.body
30
+ when /^help/i
31
+ @messenger.deliver(msg.from, "status - display stats regarding host alived\nstatus ip - display the status of the given ip")
32
+ when /^beer/i
33
+ @messenger.deliver(msg.from, "Gimme a free beeeeeeeer")
34
+ when /^status/i
35
+ hup=0
36
+ hdown=0
37
+ begin
38
+ $host.each_key {|ip|
39
+ if $host[ip] && ($host[ip].status == NORMAL)
40
+ hup=hup+1
41
+ else
42
+ hdown=hdown+1
43
+ end
44
+ }
45
+ rescue Exception => msg
46
+ $log.error(msg)
47
+ end
48
+ @messenger.deliver(msg.from, "Active Host" + ($host.size<2?" ":"s ") + "#{hup}/#{$host.size}")
49
+ when /^info\s+/i
50
+ ipasked=msg.body.gsub(/info\s+/,"")
51
+ if isValidIPv4(ipasked)
52
+ if $host[ipasked]
53
+ @messenger.deliver(msg.from, "Ip node #{ipasked} status is #{$status[$status_value.index($host[ipasked].status)]}")
54
+ elsif $network[ipasked]
55
+ @messenger.deliver(msg.from, "Network node #{ipasked} status is #{$status[$status_value.index($network[ipasked].status)]}")
56
+ else
57
+ @messenger.deliver(msg.from, "Unkown ip address #{ipasked}")
58
+ end
59
+ else
60
+ @messenger.deliver(msg.from, "#{ipasked} is not a valid ip address")
61
+ end
62
+
63
+ else
64
+ @messenger.deliver(msg.from, "Sorry , I didn't understand that. Message me with 'help' for a list of commands")
65
+ end
66
+ end
67
+ end
68
+ $log.debug("end of XmppBot thread")
69
+ end
70
+ end
71
+ end
72
+
73
+ def add_in_queue(im_recipient, msg)
74
+ $log.debug("xmpp add message in queue")
75
+ if $config.im_daemon
76
+ @buff.put im_recipient+"|"+msg unless !@buff
77
+ end
78
+ end
79
+
80
+ def stop()
81
+ if defined?(@sender) && (@sender != nil)
82
+ $log.info("Stopping XMPP bot")
83
+ @messenger.disconnect unless !@messenger
84
+ Thread.kill(@sender)
85
+ $log.debug("end of XmppBot thread")
86
+ end
87
+ end
88
+
89
+ private
90
+ def send_messages()
91
+ while @buff.has_more?
92
+ im_msg=@buff.get
93
+ if im_msg != nil
94
+ begin
95
+ $log.debug("in xmpp send_messages: #{im_msg}")
96
+ pos=im_msg.index('|')
97
+ @messenger.deliver(im_msg[0..pos-1],im_msg[pos+1..im_msg.size-1])
98
+ sleep(2)
99
+ Thread.pass if @buff.full?
100
+ rescue Exception => msg
101
+ #catch when stream is closed by close() method
102
+ $log.error(msg)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,36 @@
1
+ class Service
2
+ attr_reader :protocol
3
+ attr_accessor :port, :name, :monitor, :severity
4
+
5
+ def initialize (proto, p, n="?", s=1, sev=0)
6
+ @protocol=proto
7
+ @port=p
8
+ @name=n
9
+ if (s==1) || (s==true)
10
+ @monitor=1
11
+ else
12
+ @monitor=0
13
+ end
14
+ @severity = sev
15
+ end
16
+
17
+ def set_protocol(str)
18
+ case str.downcase()
19
+ when "tcp"
20
+ @protocol="tcp"
21
+ when "udp"
22
+ @protocol="udp"
23
+ else
24
+ puts "error setting protocol"
25
+ end
26
+ end
27
+
28
+ def switch_state()
29
+ @state ^=1
30
+ end
31
+
32
+ def monitored?()
33
+ return @monitor==1
34
+ end
35
+
36
+ end #class
@@ -0,0 +1,8 @@
1
+ GNMSMAJORVERSION=2
2
+ GNMSMINORVERSION=1
3
+ GNMSTAGVERSION=0
4
+ if GNMSTAGVERSION != ""
5
+ GNMSVERSION = "#{GNMSMAJORVERSION}.#{GNMSMINORVERSION}.#{GNMSTAGVERSION}"
6
+ else
7
+ GNMSVERSION = "#{GNMSMAJORVERSION}.#{GNMSMINORVERSION}"
8
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,111 @@
1
+ /* XPM */
2
+ static char * sgi_xpm[] = {
3
+ "47 47 61 1",
4
+ " c None",
5
+ ". c #DFEBDF",
6
+ "+ c #EFEBEF",
7
+ "@ c #DFEBEF",
8
+ "# c #EFDBEF",
9
+ "$ c #DFDBDF",
10
+ "% c #CFDBDF",
11
+ "& c #D7D3D7",
12
+ "* c #CFCBCF",
13
+ "= c #BEC3C7",
14
+ "- c #9EAAAE",
15
+ "; c #514161",
16
+ "> c #F7F3F7",
17
+ ", c #EFEBFF",
18
+ "' c #8E698E",
19
+ ") c #302830",
20
+ "! c #CFBACF",
21
+ "~ c #717D79",
22
+ "{ c #202030",
23
+ "] c #716171",
24
+ "^ c #202020",
25
+ "/ c #000000",
26
+ "( c #AEAAAE",
27
+ "_ c #616586",
28
+ ": c #201030",
29
+ "< c #203041",
30
+ "[ c #302041",
31
+ "} c #202041",
32
+ "| c #AEBABE",
33
+ "1 c #303051",
34
+ "2 c #302051",
35
+ "3 c #BEBABE",
36
+ "4 c #616171",
37
+ "5 c #101020",
38
+ "6 c #7D9EBE",
39
+ "7 c #3C5D7D",
40
+ "8 c #BEAABE",
41
+ "9 c #A2A2A6",
42
+ "0 c #828282",
43
+ "a c #AEBAAE",
44
+ "b c #AEAABE",
45
+ "c c #080810",
46
+ "d c #AE9AAE",
47
+ "e c #515161",
48
+ "f c #9EAA9E",
49
+ "g c #9E9AAE",
50
+ "h c #9E929E",
51
+ "i c #8E929E",
52
+ "j c #495971",
53
+ "k c #96928E",
54
+ "l c #8E8A8E",
55
+ "m c #385D38",
56
+ "n c #718A8E",
57
+ "o c #414141",
58
+ "p c #BEAAAE",
59
+ "q c #38FB30",
60
+ "r c #414161",
61
+ "s c #413051",
62
+ "t c #413041",
63
+ "u c #696961",
64
+ "v c #616161",
65
+ " ",
66
+ ".+++@+++@+++@+++@+++@+++@+++.#.$$$%$&&&***=&-; ",
67
+ ">@+@,@+@,@+@,@+@,@+@,@+@,@+@@@@.$.$%%%*&*&*=') ",
68
+ ">+@+++@+++@+++@+++@+++@+++@#.$.$$$&&&*&***=!~{ ",
69
+ ">@,@+@,@+@,@+@,@+@,@+@,@+@@@@.$.$%%%*&*=*===]^ ",
70
+ ">+++@///////////////////////////////////(!==_: ",
71
+ ">@+@,////////////<[<[<[<[<}{}{{{{{{{{{{{>==|]^ ",
72
+ ">+@++/////////////12121[[///////{{{:{{{:>33345 ",
73
+ ">@,@+//////////////671277/////////}{{{}{>|=|]5 ",
74
+ ">+++@////////////6777//7677/////////{:{:>3|845 ",
75
+ ">@+@,//////////677790//907677////////{{{>|3a_5 ",
76
+ ">+@++////////6777//90//90//7677///////{:>3a845 ",
77
+ ">@,@+///////677////90//90////767//////}{>aba_5 ",
78
+ ">+++@///////7767///90//90///6777///////:>8((45 ",
79
+ ">@+@,/////////7767/90//90/6777/////////{>ab-_5 ",
80
+ ">+@++///////6///77670//96777///6///////:>(((45 ",
81
+ ">@,@+//////6767///77666777///6777//////{>-b-_c ",
82
+ ">+++@//////677767//977770//677767//////:>(-de5 ",
83
+ ">@+@,//////67//776700//996777//67//////{>-(f_c ",
84
+ ">+@++//////67///97767//67779///67/////{:>dfde5 ",
85
+ ">@,@+//////67/9900067//6700099/67/////}{>-gf_c ",
86
+ ">+++@//////67900///679967///00967/////{:>dhgec ",
87
+ ">@+@,//////670///9967006799///067////{{{>fgijc ",
88
+ ">+@++///////6//990067//670099//6/////{{:>hhhec ",
89
+ ">@,@+////////6900//67//67//0096/////{{}{>ihijc ",
90
+ ">+++.///////767////67//67////677////{:{:>hihec ",
91
+ ">@+@@////////7767//67//67//6777////{{{{{>ihkec ",
92
+ ">+.#.//////////776767{{676777/////{:{{{:>hkkec ",
93
+ ">@@@$////////////7767{}6777/////{{}{{{}{>kik;/ ",
94
+ ">#.$$////////////:{77:{67:{:{:{:{:{:{:{:>hllmc ",
95
+ ">.$.$//////////{{{{{{{{{{{{{{{{{{{{{{{{{>kln;/ ",
96
+ ">$.$$(>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ll'o/ ",
97
+ ">%$%$%*%*=*=*====|3|8abab(b-(-gfgihih///lnln;/ ",
98
+ ">$%$&&&***=!=!3338|8ap(((((dfdhghhihk/qq3'~'o/ ",
99
+ ">%$%*&*&*=*====|3||aba(-(-(fgfgihihkik3|=n'~r/ ",
100
+ ">(~]~]~]]]4]4]4]4_4_4_e_e_e_eje;e;m;m;o;o;oso/ ",
101
+ "~///////////////////////////////////////////// ",
102
+ " >4omom)=|di'4eot){^5^[)t1tu ",
103
+ " >(u4u4ue14n'n4eo115:{1m4u_4{u ",
104
+ " >$~'ll~'l'vvos1t1t1sme~'llkk4)u ",
105
+ " >>fgfgfg-dfg-(-(-(-(-(-b-(-ba(4{u ",
106
+ " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>4) ",
107
+ " >((((((((((((((((((((((((((((((((/ ",
108
+ " >((((((((((((((((((((((((((((((((/ ",
109
+ " _////////////////////////////////{ ",
110
+ " (lvvvvvuvvvuvuvuvuuuv]uuu]u]_]u]_( ",
111
+ " "};