pg_ltree 1.0.0

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.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +29 -0
  4. data/lib/pg_ltree/ltree.rb +190 -0
  5. data/lib/pg_ltree/scoped_for.rb +45 -0
  6. data/lib/pg_ltree/version.rb +8 -0
  7. data/lib/pg_ltree.rb +5 -0
  8. data/lib/tasks/pg_ltree_tasks.rake +4 -0
  9. data/test/doc/_index.html +88 -0
  10. data/test/doc/class_list.html +58 -0
  11. data/test/doc/css/common.css +1 -0
  12. data/test/doc/css/full_list.css +57 -0
  13. data/test/doc/css/style.css +339 -0
  14. data/test/doc/file_list.html +57 -0
  15. data/test/doc/frames.html +26 -0
  16. data/test/doc/index.html +88 -0
  17. data/test/doc/js/app.js +219 -0
  18. data/test/doc/js/full_list.js +181 -0
  19. data/test/doc/js/jquery.js +4 -0
  20. data/test/doc/method_list.html +57 -0
  21. data/test/doc/top-level-namespace.html +102 -0
  22. data/test/dummy/README.rdoc +28 -0
  23. data/test/dummy/Rakefile +6 -0
  24. data/test/dummy/app/assets/javascripts/application.js +13 -0
  25. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  26. data/test/dummy/app/controllers/application_controller.rb +5 -0
  27. data/test/dummy/app/helpers/application_helper.rb +2 -0
  28. data/test/dummy/app/models/not_uniq_tree_node.rb +6 -0
  29. data/test/dummy/app/models/tree_node.rb +3 -0
  30. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  31. data/test/dummy/bin/bundle +3 -0
  32. data/test/dummy/bin/rails +4 -0
  33. data/test/dummy/bin/rake +4 -0
  34. data/test/dummy/bin/setup +29 -0
  35. data/test/dummy/config/application.rb +26 -0
  36. data/test/dummy/config/boot.rb +5 -0
  37. data/test/dummy/config/database.yml.example +14 -0
  38. data/test/dummy/config/environment.rb +5 -0
  39. data/test/dummy/config/environments/development.rb +41 -0
  40. data/test/dummy/config/environments/production.rb +79 -0
  41. data/test/dummy/config/environments/test.rb +42 -0
  42. data/test/dummy/config/initializers/assets.rb +11 -0
  43. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  44. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  45. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  46. data/test/dummy/config/initializers/inflections.rb +16 -0
  47. data/test/dummy/config/initializers/mime_types.rb +4 -0
  48. data/test/dummy/config/initializers/session_store.rb +3 -0
  49. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  50. data/test/dummy/config/locales/en.yml +23 -0
  51. data/test/dummy/config/routes.rb +56 -0
  52. data/test/dummy/config/secrets.yml +22 -0
  53. data/test/dummy/config.ru +4 -0
  54. data/test/dummy/db/migrate/20150809114511_enable_postgres_ltree.rb +13 -0
  55. data/test/dummy/db/migrate/20150809114528_create_tree_node.rb +7 -0
  56. data/test/dummy/db/migrate/20150809114547_create_not_uniq_tree_node.rb +8 -0
  57. data/test/dummy/db/schema.rb +29 -0
  58. data/test/dummy/log/development.log +718 -0
  59. data/test/dummy/log/test.log +34557 -0
  60. data/test/dummy/public/404.html +67 -0
  61. data/test/dummy/public/422.html +67 -0
  62. data/test/dummy/public/500.html +66 -0
  63. data/test/dummy/public/favicon.ico +0 -0
  64. data/test/pg_ltree/ltree_test.rb +154 -0
  65. data/test/pg_ltree/scoped_for_test.rb +157 -0
  66. data/test/pg_ltree_test.rb +7 -0
  67. data/test/test_helper.rb +26 -0
  68. metadata +199 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f6149a7caa97eb49d20b3f8b9c144d98ee6af04e
4
+ data.tar.gz: ab7a5c2f1d37d3f55c2c49bda92eb8f0fe43e4c2
5
+ SHA512:
6
+ metadata.gz: 2226c78595c239d7db0e29dc69d91ff93a1a2c4a47903fe531c88efe7d7022a24eef7b873afd5efb1610d60b6d32f3d9f22fe115f1983a6908d701e2cfe33d4e
7
+ data.tar.gz: 1a2df813b90353f92db7ab1b4f5c0dc2f65af997a6c337a8df45ab906cce7ae676c6f3d53873ce3164905b4241704cece1a8744adaa54a71a3ea7dbc48394d75
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Andrei Panamarenka
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'PgLtree'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ Bundler::GemHelper.install_tasks
18
+
19
+ require 'rake/testtask'
20
+
21
+ Rake::TestTask.new(:test) do |t|
22
+ t.libs << 'lib'
23
+ t.libs << 'test'
24
+ t.pattern = 'test/**/*_test.rb'
25
+ t.verbose = false
26
+ end
27
+
28
+
29
+ task default: :test
@@ -0,0 +1,190 @@
1
+ module PgLtree
2
+ # Implementatios Postgres ltree for ActiveRecord
3
+ #
4
+ # @see [ActiveRecord::Base]
5
+ # @see http://www.postgresql.org/docs/current/static/ltree.html
6
+ #
7
+ # @author a.ponomarenko
8
+ module Ltree
9
+
10
+ # Initialzie ltree for active model
11
+ #
12
+ # @param column [String] ltree column name
13
+ def ltree(column = :path)
14
+ cattr_accessor :ltree_path_column
15
+
16
+ self.ltree_path_column = column
17
+
18
+ has_and_belongs_to_many column.to_s.tableize.to_sym,
19
+       class_name: self.class.name,
20
+       association_foreign_key: 'path'
21
+
22
+ extend ClassMethods
23
+ include InstanceMethods
24
+ end
25
+
26
+ # Define class methods
27
+ module ClassMethods
28
+ # Get roots
29
+ #
30
+ # @return [ActiveRecord::Relation] relations of node's roots
31
+ def roots
32
+ at_depth 1
33
+ end
34
+
35
+ # Get nodes on the level
36
+ #
37
+ # @param depth [Integer] Depth of the nodes
38
+ # @return [ActiveRecord::Relation] relations of nodes for the depth
39
+ def at_depth(depth)
40
+ where "NLEVEL(#{ltree_path_column}) = ?", depth
41
+ end
42
+
43
+ # Get all leaves
44
+ #
45
+ # @return [ActiveRecord::Relation] relations of node's leaves
46
+ def leaves
47
+ subquery =
48
+ select("COUNT(subquery.#{ltree_path_column}) = 1")
49
+ .from("#{table_name} AS subquery")
50
+ .where("subquery.#{ltree_path_column} <@ #{table_name}.#{ltree_path_column}").to_sql
51
+ where subquery
52
+ end
53
+
54
+ # Get all with nodes when path liked the lquery
55
+ #
56
+ # @param lquery [String] ltree query
57
+ # @return [ActiveRecord::Relation] relations of node'
58
+ def where_path_liked(lquery)
59
+ where "#{ltree_path_column} ~ ?", lquery
60
+ end
61
+ end
62
+
63
+ # Define instance methods
64
+ module InstanceMethods
65
+
66
+ # Get default scope of ltree
67
+ #
68
+ # @return current class
69
+ def ltree_scope
70
+ self.class
71
+ end
72
+
73
+ # Get lTree column
74
+ #
75
+ # @return [String] ltree column name
76
+ def ltree_path_column
77
+ ltree_scope.ltree_path_column
78
+ end
79
+
80
+ # Get lTree value
81
+ #
82
+ # @return [String] ltree current value
83
+ def ltree_path
84
+ public_send ltree_path_column
85
+ end
86
+
87
+ # Get lTree previous value
88
+ #
89
+ # @return [String] ltree previous value
90
+ def ltree_path_was
91
+ public_send :"#{ltree_path_column}_was"
92
+ end
93
+
94
+ # Check what current node is root
95
+ #
96
+ # @return [Boolean] True - for root node, False - for childen node
97
+ def root?
98
+ depth == 1
99
+ end
100
+
101
+ # Get node depth
102
+ #
103
+ # @return [Integer] node depth
104
+ def depth
105
+ ltree_scope.distinct.pluck("NLEVEL('#{ltree_path}')").first || nil
106
+ end
107
+
108
+ # Get root of the node
109
+ #
110
+ # return [Object] root node
111
+ def root
112
+ ltree_scope.where("#{ltree_path_column} = SUBPATH(?, 0, 1)", ltree_path).first
113
+ end
114
+
115
+ # Get parent of the node
116
+ #
117
+ # return [Object] root node
118
+ def parent
119
+ ltree_scope.find_by "#{ltree_path_column} = SUBPATH(?, 0, NLEVEL(?) - 1)", ltree_path, ltree_path
120
+ end
121
+
122
+ # Get leaves of the node
123
+ #
124
+ # @return [ActiveRecord::Relation]
125
+ def leaves
126
+ ltree_scope.leaves.where("#{ltree_path_column} <@ ?", ltree_path).where.not ltree_path_column => ltree_path
127
+ end
128
+
129
+ # Check what current node have leaves
130
+ #
131
+ # @return [Boolean] True - if node have leaves, False - if node doesn't have leaves
132
+ def leaf?
133
+ leaves.count == 0
134
+ end
135
+
136
+ # Get self and ancestors
137
+ #
138
+ # @return [ActiveRecord::Relation]
139
+ def self_and_ancestors
140
+ ltree_scope.where("#{ltree_path_column} @> ?", ltree_path)
141
+ end
142
+
143
+ # Get ancestors
144
+ #
145
+ # @return [ActiveRecord::Relation]
146
+ def ancestors
147
+ self_and_ancestors.where.not ltree_path_column => ltree_path
148
+ end
149
+
150
+ # Get self and descendents
151
+ #
152
+ # @return [ActiveRecord::Relation]
153
+ def self_and_descendents
154
+ ltree_scope.where("#{ltree_path_column} <@ ?", ltree_path)
155
+ end
156
+
157
+ # Get descendents
158
+ #
159
+ # @return [ActiveRecord::Relation]
160
+ def descendents
161
+ self_and_descendents.where.not ltree_path_column => ltree_path
162
+ end
163
+
164
+ # Get self and siblings
165
+ #
166
+ # @return [ActiveRecord::Relation]
167
+ def self_and_siblings
168
+ ltree_scope.where(
169
+ "SUBPATH(?, 0, NLEVEL(?) - 1) @> #{ltree_path_column} AND nlevel(#{ltree_path_column}) = NLEVEL(?)",
170
+ ltree_path, ltree_path, ltree_path
171
+ )
172
+ end
173
+
174
+ # Get siblings
175
+ #
176
+ # @return [ActiveRecord::Relation]
177
+ def siblings
178
+ self_and_siblings.where.not ltree_path_column => ltree_path
179
+ end
180
+
181
+ # Get children
182
+ #
183
+ # @return [ActiveRecord::Relation]
184
+ def children
185
+ ltree_scope.where "? @> #{ltree_path_column} AND nlevel(#{ltree_path_column}) = NLEVEL(?) + 1",
186
+ ltree_path, ltree_path
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,45 @@
1
+ module PgLtree
2
+ # Narrowing the Scope for ActiveRecord Model
3
+ # @note When model have composite uniq key (for example: state + path), you should use this module for narrowing the scope
4
+ #
5
+ # @author a.ponomarenko
6
+ module ScopedFor
7
+
8
+ # Define base instance scope for model by columns
9
+ #
10
+ # @param columns [Array] List of scoped fields
11
+ def ltree_scoped_for(columns = [])
12
+ cattr_accessor :ltree_scoped_for
13
+
14
+ self.ltree_scoped_for = Array.wrap(columns)
15
+
16
+ extend ClassMethods
17
+ include InstanceMethods
18
+ end
19
+
20
+ # Define class methods
21
+ module ClassMethods
22
+ # Get all leaves
23
+ #
24
+ # @return [ActiveRecord::Relation] relations of node's leaves
25
+ def leaves
26
+ subquery =
27
+ select("COUNT(subquery.#{ltree_path_column}) = (SELECT COUNT(DISTINCT #{ltree_scoped_for.first}) FROM #{table_name})")
28
+ .from("#{table_name} AS subquery")
29
+ .where("subquery.#{ltree_path_column} <@ #{table_name}.#{ltree_path_column}").to_sql
30
+ where subquery
31
+ end
32
+ end
33
+
34
+ # Define instance methods
35
+ module InstanceMethods
36
+
37
+ # Get default scope of ltree
38
+ #
39
+ # @return current class
40
+ def ltree_scope
41
+ self.class.where *(ltree_scoped_for.map { |column| { column => public_send(column) } })
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,8 @@
1
+ # Organise ActiveRecord model into a tree structure with PostgreSQL LTree
2
+ #
3
+ # @author a.ponomarenko
4
+ module PgLtree
5
+
6
+ # Gem Version
7
+ VERSION = "1.0.0"
8
+ end
data/lib/pg_ltree.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "pg_ltree/ltree"
2
+ require "pg_ltree/scoped_for"
3
+ require "pg_ltree/version"
4
+
5
+ ActiveRecord::Base.extend(PgLtree::Ltree)
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :pg_ltree do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,88 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+ <title>
7
+ Documentation by YARD 0.8.7.6
8
+
9
+ </title>
10
+
11
+ <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
12
+
13
+ <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
14
+
15
+ <script type="text/javascript" charset="utf-8">
16
+ hasFrames = window.top.frames.main ? true : false;
17
+ relpath = '';
18
+ framesUrl = "frames.html#!_index.html";
19
+ </script>
20
+
21
+
22
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
23
+
24
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
25
+
26
+
27
+ </head>
28
+ <body>
29
+ <div id="header">
30
+ <div id="menu">
31
+
32
+
33
+ <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
34
+ </div>
35
+
36
+ <div id="search">
37
+
38
+ <a class="full_list_link" id="class_list_link"
39
+ href="class_list.html">
40
+ Class List
41
+ </a>
42
+
43
+ <a class="full_list_link" id="method_list_link"
44
+ href="method_list.html">
45
+ Method List
46
+ </a>
47
+
48
+ <a class="full_list_link" id="file_list_link"
49
+ href="file_list.html">
50
+ File List
51
+ </a>
52
+
53
+ </div>
54
+ <div class="clear"></div>
55
+ </div>
56
+
57
+ <iframe id="search_frame"></iframe>
58
+
59
+ <div id="content"><h1 class="noborder title">Documentation by YARD 0.8.7.6</h1>
60
+ <div id="listing">
61
+ <h1 class="alphaindex">Alphabetic Index</h1>
62
+
63
+ <div class="clear"></div>
64
+ <h2>Namespace Listing A-Z</h2>
65
+
66
+
67
+
68
+
69
+ <table>
70
+ <tr>
71
+ <td valign='top' width="33%">
72
+
73
+ </td>
74
+ </tr>
75
+ </table>
76
+
77
+ </div>
78
+
79
+ </div>
80
+
81
+ <div id="footer">
82
+ Generated on Sun Aug 9 21:09:19 2015 by
83
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
84
+ 0.8.7.6 (ruby-2.2.0).
85
+ </div>
86
+
87
+ </body>
88
+ </html>
@@ -0,0 +1,58 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html>
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+
7
+ <link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" charset="utf-8" />
8
+
9
+ <link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
10
+
11
+
12
+
13
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
14
+
15
+ <script type="text/javascript" charset="utf-8" src="js/full_list.js"></script>
16
+
17
+
18
+ <title>Class List</title>
19
+ <base id="base_target" target="_parent" />
20
+ </head>
21
+ <body>
22
+ <script type="text/javascript" charset="utf-8">
23
+ var hasFrames = false;
24
+ try {
25
+ hasFrames = window.top.frames.main ? true : false;
26
+ } catch (e) { }
27
+ if (hasFrames) {
28
+ document.getElementById('base_target').target = 'main';
29
+ document.body.className = 'frames';
30
+ }
31
+ </script>
32
+ <div id="content">
33
+ <h1 id="full_list_header">Class List</h1>
34
+ <div id="nav">
35
+
36
+ <span><a target="_self" href="class_list.html">
37
+ Classes
38
+ </a></span>
39
+
40
+ <span><a target="_self" href="method_list.html">
41
+ Methods
42
+ </a></span>
43
+
44
+ <span><a target="_self" href="file_list.html">
45
+ Files
46
+ </a></span>
47
+
48
+ </div>
49
+ <div id="search">Search: <input type="text" /></div>
50
+
51
+ <ul id="full_list" class="class">
52
+ <li><span class='object_link'><a href="top-level-namespace.html" title="Top Level Namespace (root)">Top Level Namespace</a></span></li>
53
+
54
+
55
+ </ul>
56
+ </div>
57
+ </body>
58
+ </html>
@@ -0,0 +1 @@
1
+ /* Override this file with custom rules */
@@ -0,0 +1,57 @@
1
+ body {
2
+ margin: 0;
3
+ font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif;
4
+ font-size: 13px;
5
+ height: 101%;
6
+ overflow-x: hidden;
7
+ }
8
+
9
+ h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; }
10
+ .clear { clear: both; }
11
+ #search { position: absolute; right: 5px; top: 9px; padding-left: 24px; }
12
+ #content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; }
13
+ #full_list { padding: 0; list-style: none; margin-left: 0; }
14
+ #full_list ul { padding: 0; }
15
+ #full_list li { padding: 5px; padding-left: 12px; margin: 0; font-size: 1.1em; list-style: none; }
16
+ #noresults { padding: 7px 12px; }
17
+ #content.insearch #noresults { margin-left: 7px; }
18
+ ul.collapsed ul, ul.collapsed li { display: none; }
19
+ ul.collapsed.search_uncollapsed { display: block; }
20
+ ul.collapsed.search_uncollapsed li { display: list-item; }
21
+ li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; }
22
+ li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; }
23
+ li { color: #888; cursor: pointer; }
24
+ li.deprecated { text-decoration: line-through; font-style: italic; }
25
+ li.r1 { background: #f0f0f0; }
26
+ li.r2 { background: #fafafa; }
27
+ li:hover { background: #ddd; }
28
+ li small:before { content: "("; }
29
+ li small:after { content: ")"; }
30
+ li small.search_info { display: none; }
31
+ a:link, a:visited { text-decoration: none; color: #05a; }
32
+ li.clicked { background: #05a; color: #ccc; }
33
+ li.clicked a:link, li.clicked a:visited { color: #eee; }
34
+ li.clicked a.toggle { opacity: 0.5; background-position: bottom right; }
35
+ li.collapsed.clicked a.toggle { background-position: top right; }
36
+ #search input { border: 1px solid #bbb; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
37
+ #nav { margin-left: 10px; font-size: 0.9em; display: none; color: #aaa; }
38
+ #nav a:link, #nav a:visited { color: #358; }
39
+ #nav a:hover { background: transparent; color: #5af; }
40
+ .frames #nav span:after { content: ' | '; }
41
+ .frames #nav span:last-child:after { content: ''; }
42
+
43
+ .frames #content h1 { margin-top: 0; }
44
+ .frames li { white-space: nowrap; cursor: normal; }
45
+ .frames li small { display: block; font-size: 0.8em; }
46
+ .frames li small:before { content: ""; }
47
+ .frames li small:after { content: ""; }
48
+ .frames li small.search_info { display: none; }
49
+ .frames #search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; }
50
+ .frames #content.insearch #search { background-position: center right; }
51
+ .frames #search input { width: 110px; }
52
+ .frames #nav { display: block; }
53
+
54
+ #full_list.insearch li { display: none; }
55
+ #full_list.insearch li.found { display: list-item; padding-left: 10px; }
56
+ #full_list.insearch li a.toggle { display: none; }
57
+ #full_list.insearch li small.search_info { display: block; }