pact_broker 0.0.10 → 1.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +0 -3
  3. data/README.md +28 -1
  4. data/Rakefile +4 -2
  5. data/assets/d3.v3.js +9263 -0
  6. data/assets/force.csv +29 -0
  7. data/assets/index.html +186 -0
  8. data/assets/index2.html +224 -0
  9. data/assets/relationships +4 -0
  10. data/assets/stylesheets/github.css +387 -0
  11. data/bethtest.rb +67 -0
  12. data/config.ru +10 -4
  13. data/config/boot.rb +4 -0
  14. data/example/Gemfile +5 -0
  15. data/example/config.ru +18 -0
  16. data/lib/db.rb +52 -0
  17. data/lib/pact_broker.rb +2 -0
  18. data/lib/pact_broker/api.rb +2 -0
  19. data/lib/pact_broker/api/decorators/pact_collection_decorator.rb +1 -1
  20. data/lib/pact_broker/api/decorators/pacticipant_collection_decorator.rb +1 -1
  21. data/lib/pact_broker/api/decorators/relationships_csv_decorator.rb +32 -0
  22. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +43 -0
  23. data/lib/pact_broker/api/resources/latest_pact.rb +7 -1
  24. data/lib/pact_broker/api/resources/relationships.rb +29 -0
  25. data/lib/pact_broker/app.rb +82 -0
  26. data/lib/pact_broker/configuration.rb +47 -0
  27. data/lib/pact_broker/db.rb +7 -39
  28. data/lib/pact_broker/models/relationship.rb +27 -0
  29. data/lib/pact_broker/project_root.rb +7 -0
  30. data/lib/pact_broker/services/pacticipant_service.rb +6 -0
  31. data/lib/pact_broker/ui/controllers/base_controller.rb +15 -0
  32. data/lib/pact_broker/ui/controllers/clusters.rb +28 -0
  33. data/lib/pact_broker/ui/controllers/relationships.rb +21 -0
  34. data/lib/pact_broker/ui/view_models/clusters.rb +0 -0
  35. data/lib/pact_broker/ui/view_models/relationship.rb +35 -0
  36. data/lib/pact_broker/ui/view_models/relationships.rb +21 -0
  37. data/lib/pact_broker/ui/views/clusters/show.haml +2 -0
  38. data/lib/pact_broker/ui/views/layouts/main.haml +2 -0
  39. data/lib/pact_broker/ui/views/relationships/show.haml +44 -0
  40. data/lib/pact_broker/version.rb +1 -1
  41. data/lib/rack/hal_browser.rb +1 -0
  42. data/lib/rack/hal_browser/redirect.rb +45 -0
  43. data/pact_broker.gemspec +10 -8
  44. data/public/bootstrap.zip +0 -0
  45. data/public/config.json +412 -0
  46. data/public/css/bootstrap-theme.css +346 -0
  47. data/public/css/bootstrap-theme.min.css +7 -0
  48. data/public/css/bootstrap.css +5780 -0
  49. data/public/css/bootstrap.min.css +7 -0
  50. data/public/fonts/glyphicons-halflings-regular.eot +0 -0
  51. data/public/fonts/glyphicons-halflings-regular.svg +229 -0
  52. data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  53. data/public/fonts/glyphicons-halflings-regular.woff +0 -0
  54. data/public/javascripts/jquery-2.1.1.min.js +4 -0
  55. data/public/javascripts/jquery.tablesorter.js +1765 -0
  56. data/public/javascripts/jquery.tablesorter.min.js +5 -0
  57. data/public/js/bootstrap.js +1943 -0
  58. data/public/js/bootstrap.min.js +7 -0
  59. data/public/stylesheets/github.css +387 -0
  60. data/public/stylesheets/relationships.css +18 -0
  61. data/script/update-hal-browser +6 -0
  62. data/spec/fixtures/renderer_pact.json +34 -0
  63. data/spec/lib/pact_broker/api/decorators/relationships_csv_decorator_spec.rb +30 -0
  64. data/spec/lib/pact_broker/api/renderers/html_pact_renderer_spec.rb +29 -0
  65. data/spec/lib/pact_broker/api/resources/latest_pact_spec.rb +57 -0
  66. data/spec/lib/pact_broker/configuration_spec.rb +21 -0
  67. data/spec/lib/pact_broker/services/pacticipant_service_spec.rb +30 -0
  68. data/spec/lib/pact_broker/ui/controllers/clusters_spec.rb +27 -0
  69. data/spec/lib/pact_broker/ui/controllers/relationships_spec.rb +37 -0
  70. data/spec/lib/pact_broker/ui/view_models/relationship_spec.rb +29 -0
  71. data/spec/lib/rack/hal_browser/redirect_spec.rb +63 -0
  72. data/spec/service_consumers/pact_helper.rb +1 -1
  73. data/spec/spec_helper.rb +10 -3
  74. data/tasks/database.rb +57 -0
  75. data/tasks/db.rake +57 -12
  76. data/tasks/pact.rake +1 -1
  77. data/tasks/rspec.rake +1 -9
  78. data/vendor/hal-browser/.gitignore +1 -0
  79. data/vendor/hal-browser/MIT-LICENSE.txt +20 -0
  80. data/vendor/hal-browser/README.md +35 -0
  81. data/vendor/hal-browser/browser.html +246 -0
  82. data/vendor/hal-browser/js/hal.js +57 -0
  83. data/vendor/hal-browser/js/hal/browser.js +60 -0
  84. data/vendor/hal-browser/js/hal/http/client.js +38 -0
  85. data/vendor/hal-browser/js/hal/resource.js +34 -0
  86. data/vendor/hal-browser/js/hal/views/browser.js +29 -0
  87. data/vendor/hal-browser/js/hal/views/documentation.js +7 -0
  88. data/vendor/hal-browser/js/hal/views/embedded_resource.js +56 -0
  89. data/vendor/hal-browser/js/hal/views/embedded_resources.js +41 -0
  90. data/vendor/hal-browser/js/hal/views/explorer.js +23 -0
  91. data/vendor/hal-browser/js/hal/views/inspector.js +39 -0
  92. data/vendor/hal-browser/js/hal/views/links.js +54 -0
  93. data/vendor/hal-browser/js/hal/views/location_bar.js +40 -0
  94. data/vendor/hal-browser/js/hal/views/navigation.js +19 -0
  95. data/vendor/hal-browser/js/hal/views/non_safe_request_dialog.js +53 -0
  96. data/vendor/hal-browser/js/hal/views/properties.js +14 -0
  97. data/vendor/hal-browser/js/hal/views/query_uri_dialog.js +69 -0
  98. data/vendor/hal-browser/js/hal/views/request_headers.js +30 -0
  99. data/vendor/hal-browser/js/hal/views/resource.js +38 -0
  100. data/vendor/hal-browser/js/hal/views/response.js +24 -0
  101. data/vendor/hal-browser/js/hal/views/response_body.js +40 -0
  102. data/vendor/hal-browser/js/hal/views/response_headers.js +19 -0
  103. data/vendor/hal-browser/styles.css +67 -0
  104. data/vendor/hal-browser/vendor/css/bootstrap-responsive.css +1109 -0
  105. data/vendor/hal-browser/vendor/css/bootstrap.css +6158 -0
  106. data/vendor/hal-browser/vendor/img/ajax-loader.gif +0 -0
  107. data/vendor/hal-browser/vendor/img/glyphicons-halflings-white.png +0 -0
  108. data/vendor/hal-browser/vendor/img/glyphicons-halflings.png +0 -0
  109. data/vendor/hal-browser/vendor/js/backbone.js +1487 -0
  110. data/vendor/hal-browser/vendor/js/bootstrap.js +2276 -0
  111. data/vendor/hal-browser/vendor/js/jquery-1.9.1.js +9597 -0
  112. data/vendor/hal-browser/vendor/js/underscore.js +1227 -0
  113. data/vendor/hal-browser/vendor/js/uritemplates.js +438 -0
  114. metadata +162 -47
  115. data/Gemfile.lock +0 -110
data/assets/force.csv ADDED
@@ -0,0 +1,29 @@
1
+ source,target,value
2
+ Contract Transaction Service,MAS,1
3
+ Contract Transaction Service,Media Proposals,1
4
+ Sarah,Media Billee Orchestrator,1
5
+ Eveie,Media Billee Orchestrator,1
6
+ Peter,Media Billee Orchestrator,1
7
+ Media Proposals,Media Billee Orchestrator,1
8
+ James,Media Billee Orchestrator,1
9
+ Contract Transaction Service,Carol,1
10
+ Contract Transaction Service,Nicky,1
11
+ Media Proposal Sync,Frank,1
12
+ Media Billee Orchestrator,Media Proposals,1
13
+ Contract Transaction Service,Lynne,1
14
+ Sarah,James,1
15
+ Roger,James,1
16
+ Maddy,James,1
17
+ Sonny,Roger,1
18
+ James,Roger,1
19
+ Media Billee Orchestrator,Peter,1
20
+ Johan,Peter,1
21
+ Media Billee Orchestrator,Eveie,1
22
+ Contract Transaction Service,Eveie,1
23
+ Eveie,Contract Transaction Service,1
24
+ Henry,Mikey,1
25
+ Elric,Mikey,1
26
+ James,Sarah,1
27
+ Media Billee Orchestrator,Sarah,1
28
+ James,Maddy,1
29
+ Peter,Johan,1
data/assets/index.html ADDED
@@ -0,0 +1,186 @@
1
+ <!DOCTYPE html>
2
+ <meta charset="utf-8">
3
+ <script src="http://d3js.org/d3.v3.js"></script>
4
+ <style>
5
+
6
+ path.link {
7
+ fill: none;
8
+ stroke: #666;
9
+ stroke-width: 1.5px;
10
+ }
11
+
12
+ path.link.twofive {
13
+ opacity: 0.25;
14
+ }
15
+
16
+ path.link.fivezero {
17
+ opacity: 0.50;
18
+ }
19
+
20
+ path.link.sevenfive {
21
+ opacity: 0.75;
22
+ }
23
+
24
+ path.link.onezerozero {
25
+ opacity: 1.0;
26
+ }
27
+
28
+ circle {
29
+ fill: #ccc;
30
+ stroke: #fff;
31
+ stroke-width: 1.5px;
32
+ }
33
+
34
+ text {
35
+ fill: #000;
36
+ font: 10px sans-serif;
37
+ pointer-events: none;
38
+ }
39
+
40
+ </style>
41
+ <body>
42
+ <script>
43
+
44
+ // get the data
45
+ d3.csv("relationships", function(error, links) {
46
+
47
+ var nodes = {};
48
+
49
+ // Compute the distinct nodes from the links.
50
+ links.forEach(function(link) {
51
+ link.source = nodes[link.source] ||
52
+ (nodes[link.source] = {name: link.source});
53
+ link.target = nodes[link.target] ||
54
+ (nodes[link.target] = {name: link.target});
55
+ link.value = +link.value;
56
+ });
57
+
58
+ var width = 1500,
59
+ height = 1000;
60
+
61
+ var force = d3.layout.force()
62
+ .nodes(d3.values(nodes))
63
+ .links(links)
64
+ .size([width, height])
65
+ .linkDistance(150)
66
+ .charge(-1300)
67
+ .on("tick", tick)
68
+ .start();
69
+
70
+ // Set the range
71
+ var v = d3.scale.linear().range([0, 100]);
72
+
73
+ // Scale the range of the data
74
+ v.domain([0, d3.max(links, function(d) { return d.value; })]);
75
+
76
+ // asign a type per value to encode opacity
77
+ links.forEach(function(link) {
78
+ if (v(link.value) <= 25) {
79
+ link.type = "twofive";
80
+ } else if (v(link.value) <= 50 && v(link.value) > 25) {
81
+ link.type = "fivezero";
82
+ } else if (v(link.value) <= 75 && v(link.value) > 50) {
83
+ link.type = "sevenfive";
84
+ } else if (v(link.value) <= 100 && v(link.value) > 75) {
85
+ link.type = "onezerozero";
86
+ }
87
+ });
88
+
89
+ var svg = d3.select("body").append("svg")
90
+ .attr("width", width)
91
+ .attr("height", height);
92
+
93
+ // build the arrow.
94
+ svg.append("svg:defs").selectAll("marker")
95
+ .data(["end"]) // Different link/path types can be defined here
96
+ .enter().append("svg:marker") // This section adds in the arrows
97
+ .attr("id", String)
98
+ .attr("viewBox", "0 -5 10 10")
99
+ .attr("refX", 15)
100
+ .attr("refY", -1.5)
101
+ .attr("markerWidth", 6)
102
+ .attr("markerHeight", 6)
103
+ .attr("orient", "auto")
104
+ .append("svg:path")
105
+ .attr("d", "M0,-5L10,0L0,5");
106
+
107
+ // add the links and the arrows
108
+ var path = svg.append("svg:g").selectAll("path")
109
+ .data(force.links())
110
+ .enter().append("svg:path")
111
+ .attr("class", function(d) { return "link " + d.type; })
112
+ .attr("marker-end", "url(#end)");
113
+
114
+ // define the nodes
115
+ var node = svg.selectAll(".node")
116
+ .data(force.nodes())
117
+ .enter().append("g")
118
+ .attr("class", "node")
119
+ .on("click", click)
120
+ .on("dblclick", dblclick)
121
+ .call(force.drag);
122
+
123
+ // add the nodes
124
+ node.append("circle")
125
+ .attr("r", 5);
126
+
127
+ // add the text
128
+ node.append("text")
129
+ .attr("x", 12)
130
+ .attr("dy", ".35em")
131
+ .text(function(d) { return d.name; });
132
+
133
+ // add the curvy lines
134
+ function tick() {
135
+ path.attr("d", function(d) {
136
+ var dx = d.target.x - d.source.x,
137
+ dy = d.target.y - d.source.y,
138
+ dr = Math.sqrt(dx * dx + dy * dy);
139
+ return "M" +
140
+ d.source.x + "," +
141
+ d.source.y + "A" +
142
+ dr + "," + dr + " 0 0,1 " +
143
+ d.target.x + "," +
144
+ d.target.y;
145
+ });
146
+
147
+ node
148
+ .attr("transform", function(d) {
149
+ return "translate(" + d.x + "," + d.y + ")"; });
150
+ }
151
+
152
+ // action to take on mouse click
153
+ function click() {
154
+ d3.select(this).select("text").transition()
155
+ .duration(750)
156
+ .attr("x", 22)
157
+ .style("fill", "steelblue")
158
+ .style("stroke", "lightsteelblue")
159
+ .style("stroke-width", ".5px")
160
+ .style("font", "20px sans-serif");
161
+ d3.select(this).select("circle").transition()
162
+ .duration(750)
163
+ .attr("r", 16)
164
+ .style("fill", "lightsteelblue");
165
+ }
166
+
167
+ // action to take on mouse double click
168
+ function dblclick() {
169
+ d3.select(this).select("circle").transition()
170
+ .duration(750)
171
+ .attr("r", 6)
172
+ .style("fill", "#ccc");
173
+ d3.select(this).select("text").transition()
174
+ .duration(750)
175
+ .attr("x", 12)
176
+ .style("stroke", "none")
177
+ .style("fill", "black")
178
+ .style("stroke", "none")
179
+ .style("font", "10px sans-serif");
180
+ }
181
+
182
+ });
183
+
184
+ </script>
185
+ </body>
186
+ </html>
@@ -0,0 +1,224 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Force based label placement</title>
6
+ <!--
7
+ <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?3.0.0"></script>
8
+ -->
9
+ <script src="http://d3js.org/d3.v3.js" charset="utf-8"></script>
10
+ </head>
11
+ <body>
12
+ <script type="text/javascript" charset="utf-8">
13
+
14
+ d3.csv("relationships", function(error, relationships) {
15
+ var w = 960, h = 500;
16
+
17
+ var labelDistance = 0;
18
+
19
+ var vis = d3.select("body").append("svg:svg").attr("width", w).attr("height", h);
20
+
21
+ var nodes = [];
22
+ var labelAnchors = [];
23
+ var labelAnchorLinks = [];
24
+ var links = [];
25
+
26
+ /* *
27
+ for(var i = 0; i < 4; i++) {
28
+ var node = {
29
+ label : "node " + i
30
+ };
31
+ nodes.push(node);
32
+ labelAnchors.push({
33
+ node : node
34
+ });
35
+ labelAnchors.push({
36
+ node : node
37
+ });
38
+ };
39
+
40
+
41
+
42
+ for(var i = 0; i < nodes.length; i++) {
43
+ for(var j = 0; j < i; j++) {
44
+ if(Math.random() > .5)
45
+ links.push({
46
+ source : i,
47
+ target : j,
48
+ weight : 1 //Math.random()
49
+ });
50
+ }
51
+ labelAnchorLinks.push({
52
+ source : i * 2,
53
+ target : i * 2 + 1,
54
+ weight : 1
55
+ });
56
+ };
57
+
58
+ links = [{
59
+ source : 0,
60
+ target : 1,
61
+ weight : 1 //Math.random()
62
+ },{
63
+ source : 0,
64
+ target : 2,
65
+ weight : 1 //Math.random()
66
+ },{
67
+ source : 0,
68
+ target : 3,
69
+ weight : 1 //Math.random()
70
+ }
71
+
72
+ ];
73
+ /* */
74
+
75
+ /*
76
+ nodes
77
+ [{"label":"node 0"},{"label":"node 1"},{"label":"node 2"},{"label":"node 3"}]
78
+ links
79
+ [{"source":1,"target":0,"weight":0.5917420655023307},{"source":2,"target":0,"weight":0.8654833608306944},{"source":3,"target":0,"weight":0.0552730702329427},{"source":3,"target":2,"weight":0.2258284434210509}]
80
+ labelAnchorLinks
81
+ [{"source":0,"target":1,"weight":1},{"source":2,"target":3,"weight":1},{"source":4,"target":5,"weight":1},{"source":6,"target":7,"weight":1}]
82
+ labelAnchors
83
+ [{"node":{"label":"node 0"}},{"node":{"label":"node 0"}},{"node":{"label":"node 1"}},{"node":{"label":"node 1"}},{"node":{"label":"node 2"}},{"node":{"label":"node 2"}},{"node":{"label":"node 3"}},{"node":{"label":"node 3"}}]
84
+
85
+
86
+ nodes index2.html:136
87
+ [{"label":"Media Proposal Sync"},{"label":"Media Projects"},{"label":"Media Opportunity Events"},{"label":"Media Advertising"}] index2.html:137
88
+ links index2.html:138
89
+ [{"source":0,"target":1,"value":1},{"source":0,"target":2,"value":1},{"source":0,"target":3,"value":1}] index2.html:139
90
+ labelAnchorLinks index2.html:140
91
+ [{"source":0,"target":1,"weight":1},{"source":2,"target":3,"weight":1},{"source":4,"target":5,"weight":1},{"source":6,"target":7,"weight":1}] index2.html:141
92
+ labelAnchors index2.html:142
93
+ [{"node":{"label":"Media Proposal Sync"}},{"node":{"label":"Media Proposal Sync"}},{"node":{"label":"Media Projects"}},{"node":{"label":"Media Projects"}},{"node":{"label":"Media Opportunity Events"}},{"node":{"label":"Media Opportunity Events"}},{"node":{"label":"Media Advertising"}},{"node":{"label":"Media Advertising"}}]
94
+
95
+ JSON.stringify(nodes)
96
+ JSON.stringify(links)
97
+ JSON.stringify(labelAnchorLinks)
98
+ JSON.stringify(labelAnchors)
99
+
100
+ /* */
101
+
102
+
103
+
104
+ var allLabels = [];
105
+
106
+ relationships.forEach(function(relationship) {
107
+ allLabels.push(relationship.source);
108
+ allLabels.push(relationship.target);
109
+ });
110
+
111
+ var labels = d3.set(allLabels).values();
112
+
113
+ labels.forEach(function(label, i){
114
+ var node = {
115
+ label: label
116
+ };
117
+ nodes.push(node)
118
+
119
+ labelAnchors.push({
120
+ node : node
121
+ });
122
+
123
+ labelAnchors.push({
124
+ node : node
125
+ });
126
+
127
+ labelAnchorLinks.push({
128
+ source : i * 2,
129
+ target : i * 2 + 1,
130
+ weight : 1
131
+ });
132
+ });
133
+
134
+ links = relationships;
135
+ // Compute the distinct nodes from the links.
136
+ relationships.forEach(function(relationship, i) {
137
+ relationship.source = labels.indexOf(relationship.source);
138
+ relationship.target = labels.indexOf(relationship.target);;
139
+ relationship.value = +relationship.value;
140
+ });
141
+
142
+
143
+ var force = d3.layout.force().size([w, h]).nodes(nodes).links(links).gravity(1).linkDistance(100).charge(-3000).linkStrength(function(x) {
144
+ return x.weight * 10
145
+ });
146
+
147
+
148
+ force.start();
149
+
150
+ var force2 = d3.layout.force().nodes(labelAnchors).links(labelAnchorLinks).gravity(0).linkDistance(0).linkStrength(8).charge(-300).size([w, h]);
151
+ force2.start();
152
+
153
+ var link = vis.selectAll("line.link").data(links).enter().append("svg:line").attr("class", "link").style("stroke", "#CCC");
154
+
155
+ var node = vis.selectAll("g.node").data(force.nodes()).enter().append("svg:g").attr("class", "node");
156
+ node.append("svg:circle").attr("r", 5).style("fill", "#555").style("stroke", "#FFF").style("stroke-width", 3);
157
+ node.call(force.drag);
158
+
159
+
160
+ var anchorLink = vis.selectAll("line.anchorLink").data(labelAnchorLinks)//.enter().append("svg:line").attr("class", "anchorLink").style("stroke", "#999");
161
+
162
+ var anchorNode = vis.selectAll("g.anchorNode").data(force2.nodes()).enter().append("svg:g").attr("class", "anchorNode");
163
+ anchorNode.append("svg:circle").attr("r", 0).style("fill", "#FFF");
164
+ anchorNode.append("svg:text").text(function(d, i) {
165
+ return i % 2 == 0 ? "" : d.node.label
166
+ }).style("fill", "#555").style("font-family", "Arial").style("font-size", 12);
167
+
168
+ var updateLink = function() {
169
+ this.attr("x1", function(d) {
170
+ return d.source.x;
171
+ }).attr("y1", function(d) {
172
+ return d.source.y;
173
+ }).attr("x2", function(d) {
174
+ return d.target.x;
175
+ }).attr("y2", function(d) {
176
+ return d.target.y;
177
+ });
178
+
179
+ }
180
+
181
+ var updateNode = function() {
182
+ this.attr("transform", function(d) {
183
+ return "translate(" + d.x + "," + d.y + ")";
184
+ });
185
+
186
+ }
187
+
188
+
189
+ force.on("tick", function() {
190
+
191
+ force2.start();
192
+
193
+ node.call(updateNode);
194
+
195
+ anchorNode.each(function(d, i) {
196
+ if(i % 2 == 0) {
197
+ d.x = d.node.x;
198
+ d.y = d.node.y;
199
+ } else {
200
+ var b = this.childNodes[1].getBBox();
201
+
202
+ var diffX = d.x - d.node.x;
203
+ var diffY = d.y - d.node.y;
204
+
205
+ var dist = Math.sqrt(diffX * diffX + diffY * diffY);
206
+
207
+ var shiftX = b.width * (diffX - dist) / (dist * 2);
208
+ shiftX = Math.max(-b.width, Math.min(0, shiftX));
209
+ var shiftY = 5;
210
+ this.childNodes[1].setAttribute("transform", "translate(" + shiftX + "," + shiftY + ")");
211
+ }
212
+ });
213
+
214
+
215
+ anchorNode.call(updateNode);
216
+
217
+ link.call(updateLink);
218
+ anchorLink.call(updateLink);
219
+
220
+ });
221
+ });
222
+ </script>
223
+ </body>
224
+ </html>
@@ -0,0 +1,4 @@
1
+ source,target,weight
2
+ Media Proposal Sync,Media Projects,1
3
+ Media Proposal Sync,Media Opportunity Events,1
4
+ Media Proposal Sync,Media Advertising,1
@@ -0,0 +1,387 @@
1
+ body {
2
+ font-family: Helvetica, arial, sans-serif;
3
+ font-size: 14px;
4
+ line-height: 1.6;
5
+ padding-top: 10px;
6
+ padding-bottom: 10px;
7
+ background-color: white;
8
+ padding: 30px;
9
+ color: #333;
10
+ }
11
+
12
+ body > *:first-child {
13
+ margin-top: 0 !important;
14
+ }
15
+
16
+ body > *:last-child {
17
+ margin-bottom: 0 !important;
18
+ }
19
+
20
+ a {
21
+ color: #4183C4;
22
+ text-decoration: none;
23
+ }
24
+
25
+ a.absent {
26
+ color: #cc0000;
27
+ }
28
+
29
+ a.anchor {
30
+ display: block;
31
+ padding-left: 30px;
32
+ margin-left: -30px;
33
+ cursor: pointer;
34
+ position: absolute;
35
+ top: 0;
36
+ left: 0;
37
+ bottom: 0;
38
+ }
39
+
40
+ h1, h2, h3, h4, h5, h6 {
41
+ margin: 20px 0 10px;
42
+ padding: 0;
43
+ font-weight: bold;
44
+ -webkit-font-smoothing: antialiased;
45
+ cursor: text;
46
+ position: relative;
47
+ }
48
+
49
+ h2:first-child, h1:first-child, h1:first-child + h2, h3:first-child, h4:first-child, h5:first-child, h6:first-child {
50
+ margin-top: 0;
51
+ padding-top: 0;
52
+ }
53
+
54
+ h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
55
+ text-decoration: none;
56
+ }
57
+
58
+ h1 tt, h1 code {
59
+ font-size: inherit;
60
+ }
61
+
62
+ h2 tt, h2 code {
63
+ font-size: inherit;
64
+ }
65
+
66
+ h3 tt, h3 code {
67
+ font-size: inherit;
68
+ }
69
+
70
+ h4 tt, h4 code {
71
+ font-size: inherit;
72
+ }
73
+
74
+ h5 tt, h5 code {
75
+ font-size: inherit;
76
+ }
77
+
78
+ h6 tt, h6 code {
79
+ font-size: inherit;
80
+ }
81
+
82
+ h1 {
83
+ font-size: 28px;
84
+ color: black;
85
+ }
86
+
87
+ h2 {
88
+ font-size: 24px;
89
+ border-bottom: 1px solid #cccccc;
90
+ color: black;
91
+ }
92
+
93
+ h3 {
94
+ font-size: 18px;
95
+ }
96
+
97
+ h4 {
98
+ font-size: 16px;
99
+ }
100
+
101
+ h5 {
102
+ font-size: 14px;
103
+ }
104
+
105
+ h6 {
106
+ color: #777777;
107
+ font-size: 14px;
108
+ }
109
+
110
+ p, blockquote, ul, ol, dl, li, table, pre {
111
+ margin: 15px 0;
112
+ }
113
+
114
+ hr {
115
+ background: transparent url("http://tinyurl.com/bq5kskr") repeat-x 0 0;
116
+ border: 0 none;
117
+ color: #cccccc;
118
+ height: 4px;
119
+ padding: 0;
120
+ }
121
+
122
+ body > h2:first-child {
123
+ margin-top: 0;
124
+ padding-top: 0;
125
+ }
126
+
127
+ body > h1:first-child {
128
+ margin-top: 0;
129
+ padding-top: 0;
130
+ }
131
+
132
+ body > h1:first-child + h2 {
133
+ margin-top: 0;
134
+ padding-top: 0;
135
+ }
136
+
137
+ body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
138
+ margin-top: 0;
139
+ padding-top: 0;
140
+ }
141
+
142
+ a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
143
+ margin-top: 0;
144
+ padding-top: 0;
145
+ }
146
+
147
+ h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
148
+ margin-top: 0;
149
+ }
150
+
151
+ li p.first {
152
+ display: inline-block;
153
+ }
154
+
155
+ ul, ol {
156
+ padding-left: 30px;
157
+ }
158
+
159
+ ul :first-child, ol :first-child {
160
+ margin-top: 0;
161
+ }
162
+
163
+ ul :last-child, ol :last-child {
164
+ margin-bottom: 0;
165
+ }
166
+
167
+ dl {
168
+ padding: 0;
169
+ }
170
+
171
+ dl dt {
172
+ font-size: 14px;
173
+ font-weight: bold;
174
+ font-style: italic;
175
+ padding: 0;
176
+ margin: 15px 0 5px;
177
+ }
178
+
179
+ dl dt:first-child {
180
+ padding: 0;
181
+ }
182
+
183
+ dl dt > :first-child {
184
+ margin-top: 0;
185
+ }
186
+
187
+ dl dt > :last-child {
188
+ margin-bottom: 0;
189
+ }
190
+
191
+ dl dd {
192
+ margin: 0 0 15px;
193
+ padding: 0 15px;
194
+ }
195
+
196
+ dl dd > :first-child {
197
+ margin-top: 0;
198
+ }
199
+
200
+ dl dd > :last-child {
201
+ margin-bottom: 0;
202
+ }
203
+
204
+ blockquote {
205
+ border-left: 4px solid #dddddd;
206
+ padding: 0 15px;
207
+ color: #777777;
208
+ }
209
+
210
+ blockquote > :first-child {
211
+ margin-top: 0;
212
+ }
213
+
214
+ blockquote > :last-child {
215
+ margin-bottom: 0;
216
+ }
217
+
218
+ table {
219
+ padding: 0;
220
+ }
221
+ table tr {
222
+ border-top: 1px solid #cccccc;
223
+ background-color: white;
224
+ margin: 0;
225
+ padding: 0;
226
+ }
227
+
228
+ table tr:nth-child(2n) {
229
+ background-color: #f8f8f8;
230
+ }
231
+
232
+ table tr th {
233
+ font-weight: bold;
234
+ border: 1px solid #cccccc;
235
+ text-align: left;
236
+ margin: 0;
237
+ padding: 6px 13px;
238
+ }
239
+
240
+ table tr td {
241
+ border: 1px solid #cccccc;
242
+ text-align: left;
243
+ margin: 0;
244
+ padding: 6px 13px;
245
+ }
246
+
247
+ table tr th :first-child, table tr td :first-child {
248
+ margin-top: 0;
249
+ }
250
+
251
+ table tr th :last-child, table tr td :last-child {
252
+ margin-bottom: 0;
253
+ }
254
+
255
+ img {
256
+ max-width: 100%;
257
+ }
258
+
259
+ span.frame {
260
+ display: block;
261
+ overflow: hidden;
262
+ }
263
+
264
+ span.frame > span {
265
+ border: 1px solid #dddddd;
266
+ display: block;
267
+ float: left;
268
+ overflow: hidden;
269
+ margin: 13px 0 0;
270
+ padding: 7px;
271
+ width: auto;
272
+ }
273
+
274
+ span.frame span img {
275
+ display: block;
276
+ float: left;
277
+ }
278
+
279
+ span.frame span span {
280
+ clear: both;
281
+ color: #333333;
282
+ display: block;
283
+ padding: 5px 0 0;
284
+ }
285
+
286
+ span.align-center {
287
+ display: block;
288
+ overflow: hidden;
289
+ clear: both;
290
+ }
291
+
292
+ span.align-center > span {
293
+ display: block;
294
+ overflow: hidden;
295
+ margin: 13px auto 0;
296
+ text-align: center;
297
+ }
298
+
299
+ span.align-center span img {
300
+ margin: 0 auto;
301
+ text-align: center;
302
+ }
303
+
304
+ span.align-right {
305
+ display: block;
306
+ overflow: hidden;
307
+ clear: both;
308
+ }
309
+
310
+ span.align-right > span {
311
+ display: block;
312
+ overflow: hidden;
313
+ margin: 13px 0 0;
314
+ text-align: right;
315
+ }
316
+
317
+ span.align-right span img {
318
+ margin: 0;
319
+ text-align: right;
320
+ }
321
+
322
+ span.float-left {
323
+ display: block;
324
+ margin-right: 13px;
325
+ overflow: hidden;
326
+ float: left;
327
+ }
328
+
329
+ span.float-left span {
330
+ margin: 13px 0 0;
331
+ }
332
+
333
+ span.float-right {
334
+ display: block;
335
+ margin-left: 13px;
336
+ overflow: hidden;
337
+ float: right;
338
+ }
339
+
340
+ span.float-right > span {
341
+ display: block;
342
+ overflow: hidden;
343
+ margin: 13px auto 0;
344
+ text-align: right;
345
+ }
346
+
347
+ code, tt {
348
+ margin: 0 2px;
349
+ padding: 0 5px;
350
+ white-space: nowrap;
351
+ border: 1px solid #eaeaea;
352
+ background-color: #f8f8f8;
353
+ border-radius: 3px;
354
+ }
355
+
356
+ pre code {
357
+ margin: 0;
358
+ padding: 0;
359
+ white-space: pre;
360
+ border: none;
361
+ background: transparent;
362
+ }
363
+
364
+ .highlight pre {
365
+ background-color: #f8f8f8;
366
+ border: 1px solid #cccccc;
367
+ font-size: 13px;
368
+ line-height: 19px;
369
+ overflow: auto;
370
+ padding: 6px 10px;
371
+ border-radius: 3px;
372
+ }
373
+
374
+ pre {
375
+ background-color: #f8f8f8;
376
+ border: 1px solid #cccccc;
377
+ font-size: 13px;
378
+ line-height: 19px;
379
+ overflow: auto;
380
+ padding: 6px 10px;
381
+ border-radius: 3px;
382
+ }
383
+
384
+ pre code, pre tt {
385
+ background-color: transparent;
386
+ border: none;
387
+ }