pbt 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02cfb8777d4c14fdb39421dc64c3e4d3e23ec57f1e933cccaac0ef67b8e103b0
4
- data.tar.gz: 6c30345dec4c52854f52c5a28c2894fb0d41b58d36ada5337f983323440ca9c5
3
+ metadata.gz: d02ba2667633586ac6e6582c3f0f181dd089e63d56b160877a0b3e51ebb353e0
4
+ data.tar.gz: 1e4dc60aa8ddbac429091bd86d3f8d601bb1a34034aa8e7c6c8c914d43e5e9b8
5
5
  SHA512:
6
- metadata.gz: a152aa19cd0f919b86216fe54457b50d7953aa96c93a302d0044ec7535177efbfa14104a20bd13e8fd2ad9aa9b7fc5cb10d6c1fbcf4e9ec9a0117c24b8bc2140
7
- data.tar.gz: 9ba28731ba906fab360a1df6030d2f4c4d34a591ec70339f8d81fb36d2db427d6ca046849a005fff7ecfcfc4fa684869455f597e38acecd0dbdef2b5a3613904
6
+ metadata.gz: 9ba49e79546492deec531f0ebef12e86e8458482740d20b3d0b3398a02aae220ea5fed476bee6489909bc2f62990fadcda2fff556fab2df69d30984a9d48435c
7
+ data.tar.gz: df6c5128d3f2b839068bd736946114a81dabf590b49d1d93d7053cf7368fa65d299515323396864c9a942f2e004a3cab73f36dc215ba5660c3d5213e41ee7cfd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2024-04-17
4
+
5
+ - Add verbose mode. It's useful to debug the test case.
6
+
7
+ ## [0.1.1] - 2024-04-14
8
+
9
+ - Change default worker from `:ractor` to `:none`
10
+
3
11
  ## [0.1.0] - 2024-04-13
4
12
 
5
13
  - Implement basic primitive arbitraries
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![Build Status](https://github.com/ohbarye/pbt/actions/workflows/main.yml/badge.svg)](https://github.com/ohbarye/pbt/actions/workflows/main.yml)
5
5
  [![RubyDoc](https://img.shields.io/badge/%F0%9F%93%9ARubyDoc-documentation-informational.svg)](https://www.rubydoc.info/gems/pbt)
6
6
 
7
- An experimental property-based testing tool for Ruby that allows you to run test cases in parallel.
7
+ A property-based testing tool for Ruby with experimental features that allow you to run test cases in parallel.
8
8
 
9
9
  PBT stands for Property-Based Testing.
10
10
 
@@ -107,7 +107,7 @@ There are many built-in arbitraries in `Pbt`. You can use them to generate rando
107
107
  #### Primitives
108
108
 
109
109
  ```ruby
110
- rng = Random.new(
110
+ rng = Random.new
111
111
 
112
112
  Pbt.integer.generate(rng) # => 42
113
113
  Pbt.integer(min: -1, max: 8).generate(rng) # => Integer between -1 and 8
@@ -139,6 +139,71 @@ Pbt.one_of(:a, 1, 0.1).generate(rng) # => :a or 1 or 0.1
139
139
 
140
140
  See [ArbitraryMethods](https://github.com/ohbarye/pbt/blob/main/lib/pbt/arbitrary/arbitrary_methods.rb) module for more details.
141
141
 
142
+ ## What if property-based tests fail?
143
+
144
+ Once a test fails it's time to debug. `Pbt` provides some features to help you debug.
145
+
146
+ ### How to reproduce
147
+
148
+ When a test fails, you'll see a message like below.
149
+
150
+ ```text
151
+ Pbt::PropertyFailure:
152
+ Property failed after 23 test(s)
153
+ { seed: 11001296583699917659214176011685741769 }
154
+ Counterexample: 0
155
+ Shrunk 3 time(s)
156
+ Got ZeroDivisionError: divided by 0
157
+ # and backtraces
158
+ ```
159
+
160
+ You can reproduce the failure by passing the seed to `Pbt.assert`.
161
+
162
+ ```ruby
163
+ Pbt.assert(seed: 11001296583699917659214176011685741769) do
164
+ Pbt.property(Pbt.integer) do |number|
165
+ # your test
166
+ end
167
+ end
168
+ ```
169
+
170
+ ### Verbose mode
171
+
172
+ You may want to know which values pass and which values fail. You can enable verbose mode by passing `verbose: true` to `Pbt.assert`.
173
+
174
+ ```ruby
175
+ Pbt.assert(verbose: true) do
176
+ Pbt.property(Pbt.array(Pbt.integer)) do |numbers|
177
+ # your failed test
178
+ end
179
+ end
180
+ ```
181
+
182
+ The verbose mode prints the results of each tested values.
183
+
184
+ ```text
185
+ Encountered failures were:
186
+ - [152477, 666997, -531468, -92182, 623948, 425913, 656138, 856463, -64529]
187
+ - [76239, 666997, -531468, -92182, 623948]
188
+ - [76239, 666997, -531468]
189
+ (snipped for README)
190
+ - [2, 163]
191
+ - [2, 11]
192
+
193
+ Execution summary:
194
+ . × [152477, 666997, -531468, -92182, 623948, 425913, 656138, 856463, -64529]
195
+ . . √ [152477, 666997, -531468, -92182, 623948]
196
+ . . √ [-64529]
197
+ . . × [76239, 666997, -531468, -92182, 623948, 425913, 656138, 856463, -64529]
198
+ . . . × [76239, 666997, -531468, -92182, 623948]
199
+ (snipped for README)
200
+ . . . . . . . . . . . . . . . . . √ [2, 21]
201
+ . . . . . . . . . . . . . . . . . × [2, 11]
202
+ . . . . . . . . . . . . . . . . . . √ []
203
+ . . . . . . . . . . . . . . . . . . √ [2, 1]
204
+ . . . . . . . . . . . . . . . . . . √ [2, 0]
205
+ ```
206
+
142
207
  ## Configuration
143
208
 
144
209
  You can configure `Pbt` by calling `Pbt.configure` before running tests.
@@ -148,8 +213,8 @@ Pbt.configure do |config|
148
213
  # Whether to print verbose output. Default is `false`.
149
214
  config.verbose = 100
150
215
 
151
- # The concurrency method to use. :ractor`, `:thread`, `:process` and `:none` are supported. Default is `:ractor`.
152
- config.worker = :ractor
216
+ # The concurrency method to use. `:ractor`, `:thread`, `:process` and `:none` are supported. Default is `:none`.
217
+ config.worker = :none
153
218
 
154
219
  # The number of runs to perform. Default is `100`.
155
220
  config.num_runs = 100
@@ -172,7 +237,7 @@ Pbt.assert(num_runs: 100, seed: 42) do
172
237
  end
173
238
  ```
174
239
 
175
- ## Concurrent methods
240
+ ## Concurrency methods
176
241
 
177
242
  One of the key features of `Pbt` is its ability to rapidly execute test cases in parallel or concurrently, using a large number of values (by default, `100`) generated by `Arbitrary`.
178
243
 
@@ -180,8 +245,12 @@ For concurrent processing, you can specify any of the three workers—`:ractor`,
180
245
 
181
246
  `Pbt` supports 3 concurrency methods and 1 sequential one. You can choose one of them by setting the `worker` option.
182
247
 
248
+ Be aware that the performance of each method depends on the test subject. For example, if the test subject is CPU-bound, `:ractor` may be the best choice. Otherwise, `:none` shall be the best choice for most cases. See [benchmarks](benchmark/README.md).
249
+
183
250
  ### Ractor
184
251
 
252
+ `:ractor` worker is useful for test cases that are CPU-bound. But it's experimental and has some limitations as described below. If you encounter any issues due to those limitations, consider using `:process` as workers whose benchmark is the most similar to `:ractor`.
253
+
185
254
  ```ruby
186
255
  Pbt.assert(worker: :ractor) do
187
256
  Pbt.property(Pbt.integer) do |n|
@@ -222,6 +291,8 @@ end
222
291
 
223
292
  ### Process
224
293
 
294
+ If you'd like to run test cases that are CPU-bound and `:ractor` is not available, `:process` becomes a good choice.
295
+
225
296
  ```ruby
226
297
  Pbt.assert(worker: :process) do
227
298
  Pbt.property(Pbt.integer) do |n|
@@ -232,6 +303,8 @@ end
232
303
 
233
304
  ### Thread
234
305
 
306
+ You may not need to run test cases with multi-threads.
307
+
235
308
  ```ruby
236
309
  Pbt.assert(worker: :thread) do
237
310
  Pbt.property(Pbt.integer) do |n|
@@ -242,6 +315,8 @@ end
242
315
 
243
316
  ### None
244
317
 
318
+ For most cases, `:none` is the best choice. It runs tests sequentially (without parallelism) but most test cases finishes within a reasonable time.
319
+
245
320
  ```ruby
246
321
  Pbt.assert(worker: :none) do
247
322
  Pbt.property(Pbt.integer) do |n|
@@ -266,10 +341,10 @@ Once this project finishes the following, we will release v1.0.0.
266
341
  - [x] Add better examples
267
342
  - [x] Arbitrary usage
268
343
  - [x] Configuration
269
- - [ ] Rich report like verbose mode
344
+ - [x] Benchmark
345
+ - [x] Rich report by verbose mode
270
346
  - [ ] Allow to use expectations and matchers provided by test framework in Ractor if possible.
271
347
  - It'd be so hard to pass assertions like `expect`, `assert` to a Ractor.
272
- - [ ] Benchmark
273
348
  - [ ] More parallelism or faster execution if possible
274
349
 
275
350
  ## Development
data/Rakefile CHANGED
@@ -8,3 +8,51 @@ RSpec::Core::RakeTask.new(:spec)
8
8
  require "standard/rake"
9
9
 
10
10
  task default: %i[spec standard]
11
+
12
+ namespace :benchmark do
13
+ task all: ["success:simple", "success:cpu_bound", "success:io_bound", "failure:simple"]
14
+
15
+ namespace :success do
16
+ task :simple do
17
+ puts "### Benchmark success:simple"
18
+ puts
19
+ puts "This runs a script that does not do any IO or CPU bound work."
20
+ puts
21
+ ENV["RUBYOPT"] = "-W:no-experimental"
22
+ sh "ruby", "benchmark/success_simple.rb"
23
+ puts
24
+ end
25
+
26
+ task :cpu_bound do
27
+ puts "### Benchmark success:cpu_bound"
28
+ puts
29
+ puts "This runs a script that does CPU bound work."
30
+ puts
31
+ ENV["RUBYOPT"] = "-W:no-experimental"
32
+ sh "ruby", "benchmark/success_cpu_bound.rb"
33
+ puts
34
+ end
35
+
36
+ task :io_bound do
37
+ puts "### Benchmark success:io_bound"
38
+ puts
39
+ puts "This runs a script that does IO bound work."
40
+ puts
41
+ ENV["RUBYOPT"] = "-W:no-experimental"
42
+ sh "ruby", "benchmark/success_io_bound.rb"
43
+ puts
44
+ end
45
+ end
46
+
47
+ namespace :failure do
48
+ task :simple do
49
+ puts "### Benchmark failure:simple"
50
+ puts
51
+ puts "This runs a script that fails and shrink happens."
52
+ puts
53
+ ENV["RUBYOPT"] = "-W:no-experimental"
54
+ sh "ruby", "benchmark/failure_simple.rb"
55
+ puts
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,97 @@
1
+ # Benchmark of concurrency methods
2
+
3
+ This benchmark compares the performance of different concurrency methods that `Pbt` provides.
4
+
5
+ ## Usage
6
+
7
+ ```shell
8
+ bundle exec rake benchmark:all
9
+ ```
10
+
11
+ ## Diagnosis
12
+
13
+ Based on benchmark results, it can be said that for most test cases, which are neither I/O-bound nor CPU-bound, concurrency is unnecessary. The overhead of implementing multithreading or multiprocessing outweighs the benefits. For the majority of users, the best strategy is to use `worker: :none`.
14
+
15
+ However, when the test subject involves CPU-bound processes, `worker: :ractor` emerges as the champion. That's because threads across Ractors run in parallel. It outperforms multithreading, which due to the GVL, only offers performance equivalent to serial processing, and it does so without the overhead associated with multiprocessing.
16
+
17
+ Interestingly, both multi-process (`worker: :process`) and multi-thread (`worker: :thread`) failed to emerge as the champion in any case.
18
+
19
+ ## Benchmarks
20
+
21
+ The following benchmarks are the results of running the benchmark suite.
22
+
23
+ - macOS 13.3.1, Apple M1 Pro 10 cores (8 performance and 2 efficiency)
24
+ - ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin22]
25
+ - pbt commit hash 6582b27105ef5e92197b3f52f9c7cf78d731e1e2
26
+
27
+ ---
28
+
29
+ ### Benchmark success:simple
30
+
31
+ This runs a script that does not do any IO or CPU bound work.
32
+
33
+ ruby benchmark/success_simple.rb
34
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin22]
35
+ Warming up --------------------------------------
36
+ ractor 20.000 i/100ms
37
+ process 3.000 i/100ms
38
+ thread 126.000 i/100ms
39
+ none 668.000 i/100ms
40
+ Calculating -------------------------------------
41
+ ractor 173.918 (±11.5%) i/s - 880.000 in 5.129007s
42
+ process 28.861 (± 3.5%) i/s - 147.000 in 5.100393s
43
+ thread 1.130k (± 5.5%) i/s - 5.670k in 5.031552s
44
+ none 6.534k (± 2.3%) i/s - 32.732k in 5.011885s
45
+
46
+ ### Benchmark success:cpu_bound
47
+
48
+ This runs a script that does CPU bound work.
49
+
50
+ ruby benchmark/success_cpu_bound.rb
51
+ Call tarai function with(9, 4, 0)
52
+
53
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin22]
54
+ Warming up --------------------------------------
55
+ ractor 3.000 i/100ms
56
+ process 2.000 i/100ms
57
+ thread 1.000 i/100ms
58
+ none 1.000 i/100ms
59
+ Calculating -------------------------------------
60
+ ractor 32.788 (± 6.1%) i/s - 165.000 in 5.057492s
61
+ process 22.098 (± 4.5%) i/s - 112.000 in 5.080410s
62
+ thread 7.439 (± 0.0%) i/s - 38.000 in 5.108195s
63
+ none 7.494 (± 0.0%) i/s - 38.000 in 5.070547s
64
+
65
+ ### Benchmark success:io_bound
66
+
67
+ This runs a script that does IO bound work.
68
+
69
+ ruby benchmark/success_io_bound.rb
70
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin22]
71
+ Warming up --------------------------------------
72
+ ractor 11.000 i/100ms
73
+ process 3.000 i/100ms
74
+ thread 17.000 i/100ms
75
+ none 22.000 i/100ms
76
+ Calculating -------------------------------------
77
+ ractor 82.488 (±14.5%) i/s - 407.000 in 5.054559s
78
+ process 35.403 (± 5.6%) i/s - 177.000 in 5.013818s
79
+ thread 143.022 (± 7.7%) i/s - 714.000 in 5.021129s
80
+ none 223.252 (± 9.0%) i/s - 1.122k in 5.071176s
81
+
82
+ ### Benchmark failure:simple
83
+
84
+ This runs a script that fails and shrink happens.
85
+
86
+ ruby benchmark/failure_simple.rb
87
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin22]
88
+ Warming up --------------------------------------
89
+ ractor 6.000 i/100ms
90
+ process 1.000 i/100ms
91
+ thread 9.000 i/100ms
92
+ none 815.000 i/100ms
93
+ Calculating -------------------------------------
94
+ ractor 62.770 (±15.9%) i/s - 306.000 in 5.009858s
95
+ process 1.783 (± 0.0%) i/s - 9.000 in 5.049606s
96
+ thread 85.218 (± 9.4%) i/s - 423.000 in 5.007178s
97
+ none 5.387k (± 3.3%) i/s - 27.710k in 5.149867s
@@ -0,0 +1,299 @@
1
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam sodales mi at velit sodales lobortis. Phasellus bibendum faucibus eros, id tincidunt orci bibendum id. Ut ultricies hendrerit nibh, mollis ultrices magna pretium in. Pellentesque rutrum dictum leo non tincidunt. Donec molestie diam vitae magna pretium, nec facilisis dui aliquet. Phasellus posuere est at lacinia accumsan. Proin faucibus ultricies massa, sit amet varius enim suscipit vel. Vestibulum sed rutrum mi, quis faucibus est. Maecenas quis odio nec neque egestas finibus quis nec quam. Aliquam porttitor, libero id faucibus rhoncus, lacus nibh lobortis leo, nec congue velit tortor non diam. Ut sit amet massa ac sem aliquam facilisis at pellentesque ipsum. Proin id tristique nisl. Sed blandit felis ac odio mollis tincidunt.
2
+
3
+ Donec pellentesque porta molestie. Vestibulum nisl purus, gravida finibus odio vel, vehicula accumsan elit. Cras sagittis, sapien id porttitor imperdiet, felis tortor blandit enim, sit amet mollis odio est eu lectus. Proin sit amet fermentum nunc. Nullam finibus neque urna, gravida ultricies elit sagittis sit amet. Nulla in nunc ligula. Vestibulum vitae eros orci. Fusce interdum odio a dolor pretium fringilla. Etiam porttitor porta venenatis. Vivamus ut massa magna. Quisque ultricies tellus purus, ac dignissim erat sagittis at. Aenean dapibus sem a urna cursus, quis tempus nulla imperdiet.
4
+
5
+ Integer tincidunt vestibulum tellus sit amet cursus. Nulla interdum magna sem, eu pulvinar metus iaculis tincidunt. Vestibulum pulvinar risus eget urna semper, eu sodales velit convallis. Aliquam hendrerit mauris et nunc vulputate, convallis euismod dolor viverra. Maecenas ex ipsum, malesuada vel ex ac, venenatis tincidunt dolor. Etiam ante mauris, bibendum non efficitur ac, rutrum non arcu. Phasellus ut ullamcorper massa. Suspendisse sollicitudin sem a lectus imperdiet, ut auctor ligula tempus. Donec mollis, ex euismod varius scelerisque, dolor sem bibendum libero, eget consectetur ligula ipsum nec tortor. In at ligula nulla. Ut nec sem eu tortor accumsan convallis a ac quam. Maecenas consectetur bibendum erat, mollis vehicula lorem sodales a. Mauris rutrum nulla dapibus nibh tristique, non aliquam magna posuere. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
6
+
7
+ Pellentesque id tempus tortor. Duis libero sapien, hendrerit vel placerat nec, tempor sed tortor. Quisque sit amet justo vehicula, blandit lacus sed, sagittis enim. In et eleifend leo, ut elementum felis. Aliquam non urna non sapien vulputate pretium. Cras ut ligula commodo, accumsan diam in, faucibus libero. Donec mattis lacus id scelerisque venenatis. Integer vel lacinia metus, vitae cursus mi. Phasellus leo tellus, ullamcorper id congue ac, dignissim vel dui. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
8
+
9
+ Cras lobortis tellus lorem. Morbi auctor enim nec erat posuere egestas. Quisque cursus accumsan cursus. Sed nec odio ut ex pretium luctus non vehicula erat. Proin et diam tortor. Maecenas porttitor imperdiet mi sed fermentum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; In eros dui, sodales et accumsan in, egestas ut purus. Praesent varius lacinia tortor porttitor maximus. Proin nunc felis, tempus ut est vitae, mollis rhoncus arcu. Curabitur in consequat lectus, blandit tristique lectus. Morbi nec convallis eros.
10
+
11
+ Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi magna lectus, dapibus ac aliquet in, egestas sed urna. Curabitur tempus gravida tortor. Suspendisse potenti. Integer congue diam enim, sed vestibulum orci feugiat eget. Proin ac lacinia nisl, eu ornare ligula. Fusce placerat metus nisl, vitae posuere quam bibendum sit amet. Proin aliquet suscipit lectus, non suscipit purus facilisis a. In hac habitasse platea dictumst. Quisque faucibus orci leo, et facilisis velit eleifend in. In sit amet semper tortor. Nam nec faucibus libero. Nam malesuada sapien at eros sollicitudin, nec dapibus ante egestas. Maecenas ornare enim sit amet nisi tincidunt, eget pharetra diam volutpat. Nulla nisi sem, blandit sit amet faucibus vitae, pretium a est. Etiam id ante ut ligula vestibulum ultricies ullamcorper sodales turpis.
12
+
13
+ Duis et elit urna. Vestibulum sem urna, pulvinar iaculis mattis vel, faucibus in erat. Morbi sed nisl eget sapien aliquet ullamcorper. Morbi ullamcorper turpis ipsum, ut tincidunt leo posuere at. Integer volutpat felis nec felis vestibulum dictum. Cras vitae lorem elit. In venenatis dui et orci laoreet dictum. Quisque eget lacinia felis, non euismod orci. Morbi at dignissim ligula.
14
+
15
+ Mauris blandit malesuada rhoncus. Morbi sed est semper, dictum tellus ut, suscipit ante. Duis quis quam est. Donec ante nisl, porta eget venenatis quis, ultricies congue neque. Maecenas lacus diam, placerat molestie imperdiet vel, semper quis nisi. Curabitur congue a nulla a tempor. Donec volutpat tristique congue. Vestibulum suscipit finibus arcu, nec tristique enim eleifend ut. Sed sodales dictum neque, in tincidunt eros varius id. Sed elementum est mauris, consectetur vulputate turpis auctor non. In ac odio eu purus consequat sagittis et a purus. Proin euismod efficitur tortor, non tristique massa vestibulum vitae. Morbi rutrum consectetur ligula. Donec aliquet tincidunt dolor nec fringilla. Etiam vel diam arcu.
16
+
17
+ Duis ultrices porta velit, at mollis massa tristique laoreet. Aenean iaculis urna at metus consequat sodales. Maecenas eget justo orci. Fusce lorem diam, fringilla ut libero luctus, varius mattis eros. Ut dapibus arcu nec suscipit aliquam. Nullam ultrices massa quis arcu tempor consectetur. Phasellus at quam porta, maximus nisl quis, tempor neque. Etiam a consectetur elit. In vestibulum magna non elit varius dignissim. In commodo arcu at mauris efficitur condimentum. Mauris auctor, erat sit amet consectetur gravida, tortor odio lacinia nisl, in venenatis magna arcu sit amet nulla. Quisque consectetur metus nec nibh pharetra, nec lobortis nibh maximus. Mauris in turpis in dolor faucibus vestibulum in vitae tortor. Nam quis consequat ligula, nec ultricies nisl. Nunc eget dui molestie, placerat felis eget, vehicula turpis.
18
+
19
+ Morbi vulputate nisi quis sapien dictum, nec feugiat nisl convallis. Vestibulum finibus eros tellus, vel pulvinar dolor pellentesque ac. Aliquam vel dolor vel eros posuere tempus quis eu eros. Mauris venenatis tempor enim ac egestas. Pellentesque ultricies vehicula tincidunt. Duis quis dui vitae urna volutpat commodo ullamcorper eu mauris. Cras consequat pharetra egestas. Suspendisse nec neque vitae metus fermentum lacinia. Maecenas eget lobortis leo, vitae euismod metus. Proin dignissim magna nec mauris iaculis consectetur. Sed eget blandit enim, sit amet interdum sem. Quisque viverra dolor a neque tincidunt volutpat. Aliquam orci velit, tempus eget dolor vestibulum, maximus vulputate lectus. Integer lobortis sollicitudin justo, vitae malesuada massa auctor in. Nunc interdum, enim non dignissim tempus, arcu odio euismod lorem, faucibus rutrum lectus leo a tellus. In elementum lacus ultricies condimentum aliquet.
20
+
21
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean feugiat velit id ipsum varius pretium. Curabitur pretium at arcu id ultricies. Morbi sed suscipit diam. Nullam gravida turpis ut nulla luctus, non tristique urna porta. Etiam nibh elit, luctus non sagittis eget, malesuada eu ligula. Pellentesque rhoncus felis pretium volutpat eleifend. Proin facilisis, metus nec euismod semper, lorem felis rutrum mi, in vulputate tellus tellus ac ex. Nunc gravida nec nunc in dignissim. Maecenas et urna dui. Sed iaculis dignissim convallis. Vivamus efficitur metus vel arcu tempor fringilla. Cras porta lorem ut dictum aliquam. Mauris lobortis metus odio, et bibendum diam convallis ac. Morbi congue euismod maximus.
22
+
23
+ Duis est augue, aliquet et posuere et, mattis at sapien. Donec ac ante vel quam accumsan iaculis eu vitae ligula. Aliquam erat volutpat. Vivamus nisi ipsum, ultricies volutpat enim vel, commodo pharetra libero. Donec a nisi ultricies, pharetra odio ut, faucibus nisi. Aenean nec mi pulvinar neque porta tempor vitae eu dui. Cras nec semper nibh, vel lacinia tortor. Curabitur sit amet semper neque. Curabitur non ipsum pharetra, maximus nibh non, luctus metus. Quisque a tempor lacus. Sed pulvinar libero ut velit fermentum, vitae sollicitudin ex aliquet. Suspendisse efficitur mauris eget quam fermentum dignissim eu ac lorem. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus interdum sapien ante, sed tincidunt diam luctus in. Quisque bibendum ante orci, vitae dictum orci maximus ut. Vestibulum posuere augue quis diam rhoncus hendrerit.
24
+
25
+ Quisque et elit varius, porta neque et, maximus ligula. Vestibulum tincidunt venenatis lacus, suscipit pharetra odio fermentum eget. Suspendisse convallis urna et tellus hendrerit ullamcorper eget vitae felis. Vivamus tempor quam et augue scelerisque, in semper turpis imperdiet. Nam in lorem accumsan, posuere metus vitae, auctor eros. Sed pretium urna id sollicitudin blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse tempor, ante et mattis aliquam, tellus velit cursus mauris, aliquet sodales sapien erat non est. Aliquam efficitur nunc vel nunc condimentum, a volutpat erat ultrices. Etiam vulputate dapibus finibus. Nunc at urna pellentesque, tempor est sed, tincidunt nibh. Nunc sed lacus non nisi eleifend ornare. Integer aliquam mi gravida tincidunt fermentum. Sed nunc nulla, efficitur nec elit non, luctus commodo est. Nunc nec consectetur enim, eu vulputate leo. Suspendisse dui sapien, ullamcorper sed justo in, blandit venenatis arcu.
26
+
27
+ Nullam at massa lorem. Nullam placerat sapien sit amet neque sollicitudin, vitae tincidunt tellus sollicitudin. In blandit pretium varius. Donec euismod interdum imperdiet. Curabitur varius ut mi a interdum. Ut non quam nec felis hendrerit rhoncus sed vel nibh. Cras non lectus eu dui pharetra auctor. Suspendisse sit amet ligula in erat pharetra accumsan. Mauris sed nisl non diam ullamcorper laoreet vel ut orci. Praesent a faucibus quam, eu volutpat felis. Nunc vitae neque erat.
28
+
29
+ Integer mollis aliquam turpis, mattis egestas nibh mollis at. Integer laoreet dictum faucibus. Mauris auctor ultrices tortor, in elementum arcu tincidunt in. Integer feugiat metus nisl, vel lacinia quam viverra ut. Nam pulvinar, magna ut mollis bibendum, urna ante consequat libero, at elementum nisl metus at urna. Ut pretium eros quis dapibus ultricies. Cras sit amet placerat ex. Proin pretium blandit arcu, vehicula pulvinar turpis egestas eget. Vivamus ut elit sed risus semper tempus. Nunc vel lorem ornare, tristique turpis quis, ultrices lacus. Pellentesque faucibus fermentum magna, ac volutpat nibh lacinia ac.
30
+
31
+ Proin id dui nulla. Suspendisse pretium nisi nibh, eget lacinia augue accumsan sed. Mauris maximus tempus tellus, ut scelerisque sapien sodales et. Etiam aliquam, mi vitae elementum sollicitudin, tellus nulla malesuada ipsum, vel imperdiet lacus ligula vitae ligula. Morbi at magna at tellus semper viverra. Nunc hendrerit velit quis molestie molestie. Proin eu quam molestie, mollis orci sed, tristique purus. Sed maximus ligula quis eleifend mollis. Morbi luctus aliquet nibh, et facilisis urna imperdiet nec. Maecenas eget imperdiet metus. Donec purus metus, tempor viverra mi suscipit, tempor euismod lorem. Curabitur quis ligula congue, scelerisque sapien nec, bibendum ligula.
32
+
33
+ Maecenas mollis eget neque convallis auctor. Fusce viverra nibh sollicitudin dictum auctor. Vivamus vitae tincidunt sapien. Phasellus nisi ipsum, ultricies eget volutpat eu, vehicula a velit. Vestibulum tincidunt nisl tellus, in interdum elit ullamcorper at. Donec ante quam, congue vel commodo in, interdum nec eros. Proin convallis lorem quis nisl commodo lacinia. Nullam eu vulputate metus, a eleifend nunc. Pellentesque pellentesque ex justo, id bibendum velit congue vitae. Duis et dignissim nunc. Morbi eu tempor turpis. Duis leo turpis, pellentesque in facilisis et, malesuada et massa. Ut rutrum mattis massa interdum consectetur. Aenean vel mattis ante, vitae blandit magna. Morbi sagittis pellentesque nibh.
34
+
35
+ Nunc non sodales odio, a egestas ante. Vestibulum ut ipsum placerat, aliquam sapien non, laoreet neque. Nam maximus tortor mauris, eu aliquam lectus lacinia at. Duis at auctor nulla. Maecenas malesuada erat nisl, sed interdum ipsum lacinia sit amet. Pellentesque tellus metus, condimentum sit amet purus vitae, lobortis tempus purus. Nam efficitur convallis eros, in convallis lorem. Fusce nec consectetur elit, a sollicitudin justo. Quisque ac magna eget erat vestibulum feugiat. Curabitur ut est volutpat, pellentesque lectus et, feugiat quam. Quisque nec neque metus. Maecenas ligula massa, facilisis ut mollis eget, aliquet eget eros. Praesent a metus sit amet nisi tempus ultricies vitae vitae nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi nibh dolor, laoreet aliquet nibh nec, laoreet lobortis mi.
36
+
37
+ Quisque hendrerit libero quis scelerisque convallis. Curabitur tincidunt ipsum id aliquet convallis. Sed fringilla quam a urna tempus aliquam. Phasellus sollicitudin vel felis gravida feugiat. Etiam ac elementum ex. Nunc efficitur sagittis nisl. Nulla eros quam, vehicula a sodales vitae, pretium ac nisl. Sed vel auctor dui. Nulla sit amet justo eget dolor mollis dictum sit amet non sem. Donec id metus feugiat, luctus erat vitae, lacinia orci. Suspendisse potenti.
38
+
39
+ In suscipit efficitur dolor at bibendum. Suspendisse ornare scelerisque bibendum. Sed iaculis ullamcorper vehicula. In ut nisi dolor. Integer in mauris ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque et luctus augue, hendrerit vehicula orci. Praesent auctor dui sem, vel semper turpis rhoncus eu. Pellentesque dapibus ac tortor quis cursus. Fusce consectetur tellus eu mauris laoreet pharetra. Etiam efficitur purus et mauris suscipit, at elementum mi molestie. Duis eget imperdiet erat, id feugiat velit. Praesent tincidunt sollicitudin accumsan.
40
+
41
+ Etiam finibus, erat quis feugiat tincidunt, nunc enim placerat massa, eget volutpat sapien nisi eget mauris. Etiam lectus nibh, accumsan in turpis a, suscipit egestas massa. In consectetur posuere iaculis. Curabitur tempus tempus nunc, eget blandit nisl convallis ut. Duis at tellus in nibh convallis venenatis. Nulla rutrum justo sit amet facilisis aliquam. Vestibulum sed elit sed nibh aliquam fringilla. Sed cursus neque dapibus quam placerat, vitae facilisis justo aliquet. Donec rutrum ullamcorper elementum. Nullam id tristique mauris. Suspendisse vel massa fermentum velit scelerisque porta. Suspendisse ac metus quam. Nunc et facilisis diam, ut lacinia tellus.
42
+
43
+ Curabitur porta luctus ante a laoreet. Curabitur nec sagittis dolor, ac interdum quam. Quisque nec leo sed justo convallis ultrices. Curabitur ex felis, accumsan a ante ut, dignissim efficitur lorem. Nam convallis egestas dictum. Cras eget ligula id nulla posuere scelerisque. Proin ut facilisis nisl, a tincidunt turpis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In iaculis pretium varius. Ut finibus nibh ut ante congue congue. Sed feugiat, leo sit amet accumsan viverra, ligula risus dapibus elit, at efficitur nibh sapien in est. Vivamus rhoncus congue elit sit amet posuere. Vivamus faucibus posuere lectus commodo laoreet. Donec vel risus ac justo vestibulum venenatis vitae vitae metus.
44
+
45
+ Cras posuere nunc ut blandit porta. Quisque condimentum, erat sit amet elementum interdum, mauris nisl lobortis velit, eget suscipit diam mauris eu nisl. Etiam ac pellentesque metus. Morbi et accumsan tortor. Aenean blandit justo ut lacus lacinia, vitae semper leo facilisis. Mauris fermentum, nunc non ultrices vulputate, enim ipsum tristique justo, ut facilisis purus magna in elit. Curabitur vitae laoreet ante.
46
+
47
+ Integer vel malesuada lectus, vel efficitur augue. Sed eu magna vel arcu consequat malesuada ut at ante. Donec neque nisl, sagittis id commodo ut, vulputate sit amet augue. Mauris aliquam, mauris at dignissim ullamcorper, sapien nunc dignissim turpis, sit amet condimentum nisi ipsum nec magna. Etiam fermentum dapibus mauris quis facilisis. Maecenas tempor leo a convallis faucibus. Aenean quis mattis dolor, vitae faucibus ante. Morbi accumsan iaculis libero, quis cursus enim consequat non.
48
+
49
+ In eleifend magna at justo ultricies, id iaculis lorem vehicula. Fusce tincidunt magna a lorem vulputate, non maximus odio commodo. Pellentesque fringilla cursus purus, id convallis ante. Cras vulputate turpis eu lectus cursus, at semper lectus blandit. Maecenas sed venenatis velit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas commodo in nibh eget egestas. Sed dictum iaculis lectus a semper. Etiam tempus odio eu elit dapibus luctus. Suspendisse in magna quis neque dignissim sagittis.
50
+
51
+ Morbi enim tellus, molestie vel nulla ac, auctor ultrices sem. Morbi maximus enim nec vestibulum rhoncus. Quisque in auctor lectus, non pellentesque lacus. Nulla congue ac augue at dapibus. Sed luctus dictum nibh vitae tristique. Pellentesque nec augue at turpis bibendum efficitur eu et felis. Proin efficitur vitae tortor non rutrum. Etiam a laoreet urna, in imperdiet metus. Cras aliquet lorem dolor, ac posuere justo convallis vitae. Nulla facilisi. Aenean tempus libero eu nisi finibus, sit amet pharetra nulla dignissim. Nulla leo urna, rhoncus non volutpat gravida, viverra in nulla. Cras et lectus imperdiet, lobortis ante vitae, porta dui. Suspendisse quis aliquam justo, ut molestie enim. Interdum et malesuada fames ac ante ipsum primis in faucibus.
52
+
53
+ Nulla facilisi. In nunc turpis, ultricies et erat id, accumsan placerat elit. Suspendisse potenti. Phasellus luctus dictum sem non pellentesque. Phasellus condimentum pellentesque ligula sit amet rhoncus. Vivamus tempus euismod nisl sed viverra. Sed aliquet massa ut orci finibus tincidunt. Sed auctor mauris a lacinia iaculis. Integer consectetur orci neque, nec sollicitudin libero sagittis sed. Integer iaculis aliquam dolor, id elementum dui tempus sit amet. Donec vehicula varius augue, blandit eleifend odio sollicitudin eu. Fusce mattis sollicitudin nunc a dapibus. Donec imperdiet dolor eu leo convallis, sed volutpat erat dignissim. Ut elementum diam non commodo porttitor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean finibus cursus massa, mattis vestibulum ante.
54
+
55
+ Pellentesque eu ante quis odio accumsan rutrum. Aliquam mattis ultrices diam sed consequat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed aliquet massa mi, quis cursus ex ultricies eu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Praesent laoreet lacinia porta. In luctus erat quam, non imperdiet libero tempus in. Proin ante odio, vehicula eget odio ac, sollicitudin rhoncus orci.
56
+
57
+ In in sollicitudin nisl, eget tristique tellus. Nullam sed accumsan nisl. Sed turpis ligula, tempor ut aliquam eu, sollicitudin ut justo. Aliquam tortor justo, porttitor sed augue ut, blandit vulputate lectus. Sed odio neque, pulvinar ac metus molestie, bibendum hendrerit augue. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum condimentum orci non maximus finibus.
58
+
59
+ Fusce ut sodales nisi, sed congue arcu. Donec a blandit nibh. Quisque at egestas lacus, in elementum orci. Morbi dignissim ornare sagittis. Aenean non congue justo. Donec mollis iaculis risus non consectetur. Nunc auctor ex nunc, et rhoncus lacus aliquam sit amet. Aliquam eget ex augue. Donec purus nisl, egestas nec fringilla quis, lobortis id lorem. Vivamus erat odio, pretium ac dolor ac, pulvinar ultricies erat. Cras a dui tellus. Fusce in purus scelerisque, scelerisque risus at, lobortis velit.
60
+
61
+ Sed accumsan fringilla eleifend. Fusce libero magna, euismod vel gravida in, iaculis et enim. Suspendisse fringilla pretium purus, id iaculis magna accumsan eu. In hac habitasse platea dictumst. Sed mollis in dolor in ultricies. Integer sit amet ante et diam bibendum pretium. Vivamus sagittis, erat et pretium tincidunt, ante tortor mattis lorem, non scelerisque sem risus eget quam. Nam lobortis quam in lacus sollicitudin ornare. Cras sit amet lacus hendrerit ligula porttitor vehicula. Nunc viverra iaculis eros ut gravida. Pellentesque mollis pellentesque diam id lacinia. Curabitur tempor posuere turpis a auctor. Pellentesque suscipit rhoncus turpis, eu sollicitudin tellus varius eu. Vestibulum cursus massa vulputate, finibus elit ac, mattis nibh. Suspendisse sit amet sapien erat.
62
+
63
+ Vivamus sed pellentesque ipsum, nec ornare felis. Suspendisse ante risus, congue a eleifend eu, fermentum id est. Duis ac augue faucibus, blandit mi venenatis, semper ipsum. Integer finibus fringilla dignissim. Quisque ultrices sagittis odio, nec molestie nisl tempus consequat. Etiam elit orci, varius ac maximus at, imperdiet nec dui. Phasellus facilisis ligula sed ante consectetur rutrum. Phasellus ac arcu mollis, laoreet dui sit amet, mattis dui. Fusce fringilla, tellus ut euismod tincidunt, justo nulla faucibus lorem, sed volutpat massa lectus eget ipsum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas vestibulum quam lectus, eu aliquet mi ultrices et. Vivamus condimentum ex non elit rutrum iaculis.
64
+
65
+ Pellentesque lectus odio, accumsan ac sem ut, tincidunt suscipit enim. Proin facilisis blandit velit sit amet suscipit. Nunc tincidunt convallis mauris dignissim maximus. Suspendisse faucibus auctor mauris, volutpat consectetur leo molestie vitae. Ut hendrerit nunc a justo porttitor, eu cursus tortor lacinia. Ut id sem in lorem faucibus porta at ut elit. Integer tempus quis libero at faucibus. Pellentesque id laoreet turpis, nec tempor magna. Aenean vitae felis interdum, convallis leo porttitor, dapibus tellus.
66
+
67
+ Nullam id tortor et erat posuere tempor. Nullam sit amet consectetur est. Etiam vitae tellus nec ante rutrum feugiat eu vitae ex. Nulla quis enim in elit eleifend volutpat ut non justo. In hac habitasse platea dictumst. Nunc ipsum nisl, tempor sed rutrum a, finibus nec nibh. Curabitur fringilla sapien eu dignissim porttitor. Sed tempor, urna sit amet semper fermentum, est magna lacinia tellus, gravida consequat nisi sapien sed libero. Cras vel nisl auctor, vestibulum velit id, sodales nulla. Donec eleifend quam sed vulputate cursus. Donec mollis sed ipsum sed aliquam. Nam at mattis nulla, eu posuere felis. Maecenas tristique elit vitae posuere laoreet.
68
+
69
+ Sed sodales tellus lorem, non dictum neque consectetur vel. Cras in iaculis orci, sed vehicula lorem. Pellentesque fermentum a ex eu suscipit. Nunc aliquet, lectus at dictum sagittis, ligula magna consectetur odio, vitae tempus nunc augue quis augue. Morbi congue velit eu odio semper, in auctor mauris scelerisque. Vestibulum sed turpis libero. Ut egestas felis sed hendrerit dictum. Cras ultricies, arcu ac faucibus sodales, dolor lacus iaculis nisl, nec fermentum orci libero eget enim. Nullam tempus erat sed tempus interdum. Sed facilisis diam quis orci porta, et tristique libero tristique. Curabitur eu finibus magna. Proin mollis turpis ut enim malesuada malesuada.
70
+
71
+ Nullam nulla nulla, interdum id auctor sit amet, pharetra vestibulum ipsum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec malesuada mauris non viverra auctor. Vivamus eget convallis ligula. Pellentesque at nibh congue, posuere mauris non, lacinia odio. Integer id scelerisque nulla. Etiam condimentum sem nec lectus eleifend, non venenatis odio euismod. Maecenas at metus vestibulum felis lobortis iaculis. Nulla diam justo, luctus laoreet leo eu, consequat lacinia tortor.
72
+
73
+ Sed at lectus nisl. Quisque tincidunt id enim non aliquet. Morbi dapibus neque ligula, pharetra dignissim ligula scelerisque nec. Etiam non ultricies nisi. Phasellus feugiat semper commodo. Integer non ligula non purus consectetur auctor sed viverra nunc. Praesent congue quis lacus vitae tempus. Cras eleifend gravida iaculis.
74
+
75
+ Aliquam vel metus ultricies, congue nisl non, mollis magna. Curabitur tristique elementum lorem ut pulvinar. Integer sagittis mi in metus rhoncus accumsan. Fusce congue magna vitae sagittis placerat. Aenean sit amet consectetur dolor. Morbi varius lorem massa, non vulputate tellus aliquam nec. Maecenas ac vulputate massa. Phasellus posuere venenatis sem. Duis nulla sapien, cursus in dictum sed, semper nec lacus. In posuere sapien vitae sapien posuere euismod. Cras a urna ac ipsum volutpat bibendum vel in felis. Nunc laoreet quam suscipit volutpat aliquam. Donec sit amet elementum magna. Pellentesque ac tellus posuere, aliquam augue vitae, ornare ex.
76
+
77
+ In non venenatis mauris. Nullam a viverra quam. Etiam mi mauris, convallis et orci ut, sagittis pharetra elit. Donec non placerat sem. Etiam blandit quam nec erat condimentum, non sollicitudin justo accumsan. Nunc finibus, eros vitae ultricies ultricies, quam eros condimentum dui, ut pulvinar nisi sem eget metus. In hac habitasse platea dictumst. Proin mauris quam, imperdiet a condimentum mollis, tincidunt vel dui. Proin mi turpis, suscipit quis feugiat non, lobortis eu risus.
78
+
79
+ Curabitur mauris turpis, dapibus in dui vitae, rutrum convallis lorem. Phasellus elementum, ligula nec egestas commodo, nisi quam fermentum magna, non auctor augue tortor interdum orci. In suscipit odio massa, et ullamcorper urna tincidunt sed. Curabitur vitae condimentum dui, vitae vestibulum nibh. Cras vitae nunc nunc. Phasellus ut lobortis velit, quis maximus dolor. Maecenas arcu felis, condimentum vitae consequat nec, ultricies a felis. Proin vitae nulla luctus, luctus risus at, aliquet risus. Vestibulum finibus hendrerit mauris nec pretium. Morbi tincidunt gravida tellus vel maximus. Phasellus vulputate quis justo vitae vulputate.
80
+
81
+ Integer porta nisl venenatis turpis fermentum, non egestas nunc ornare. Proin porttitor quam ipsum, at bibendum risus efficitur ut. Etiam feugiat nec sem in fermentum. Donec non pulvinar turpis. Curabitur quis posuere velit, at aliquam libero. Quisque faucibus imperdiet porta. Pellentesque tincidunt malesuada sem, nec interdum erat iaculis quis. In dictum faucibus sapien eu euismod. Nulla nec feugiat orci. Donec dignissim, augue vel pharetra vehicula, erat massa imperdiet ligula, id dictum justo turpis ut nibh. Cras placerat, orci sit amet sodales rutrum, nunc nibh bibendum turpis, a viverra nisi lectus vel eros. Donec eget dolor accumsan orci tincidunt tincidunt. Aenean at magna metus. In suscipit ornare molestie.
82
+
83
+ Donec fringilla commodo semper. Nulla varius ultrices lacus, ac lacinia diam mattis laoreet. Nullam euismod malesuada est, nec vestibulum metus aliquet sed. Nulla erat est, pulvinar et interdum ac, gravida ut mi. Nullam malesuada varius nisl eget facilisis. Proin quis mauris ut nibh mollis ullamcorper non eget metus. Quisque ut lacus eget dolor vestibulum laoreet.
84
+
85
+ Vestibulum tortor nunc, pretium nec est vitae, placerat suscipit nunc. Quisque vel sodales velit, vitae bibendum risus. Pellentesque elementum dapibus ultricies. Cras convallis volutpat ligula, nec placerat lectus faucibus et. Nulla pulvinar ultricies lacus a rutrum. Pellentesque fermentum tellus a malesuada consectetur. Cras accumsan arcu lectus. Etiam ac magna erat. Ut ut eros nunc. Mauris turpis nisi, ullamcorper ac varius vitae, fringilla vitae est. Suspendisse interdum lacus sapien. Aliquam sit amet tempus nulla. Morbi tincidunt luctus nunc quis blandit. Sed tempor, dolor ac consectetur finibus, velit enim fringilla dui, imperdiet dapibus massa mi vel velit.
86
+
87
+ Curabitur ac ante et nisl ullamcorper efficitur a eu purus. Maecenas ac finibus urna. Phasellus accumsan luctus aliquet. Phasellus placerat, nibh vel auctor malesuada, erat nisl blandit nulla, at volutpat lectus massa at tortor. Proin et eros mi. Nullam accumsan metus a fringilla porttitor. Nam varius, odio pellentesque pretium feugiat, nisl leo dignissim nulla, eget auctor odio ligula sit amet arcu. Quisque hendrerit sagittis pretium. Phasellus nec pretium arcu, at finibus lectus. Fusce massa lectus, varius non nunc sed, interdum tristique nisi. Maecenas gravida viverra ipsum, vulputate lacinia orci semper vel.
88
+
89
+ Vivamus rutrum mi quam, et volutpat est lacinia sed. Ut vel lobortis lectus. Praesent luctus iaculis pellentesque. Sed et metus feugiat, dictum lectus non, pulvinar orci. Maecenas at eros laoreet, fringilla nunc id, aliquet felis. Praesent sapien ligula, volutpat eget velit non, vestibulum volutpat lorem. Aenean vel erat ligula. Nulla facilisi. Aenean porttitor risus ut ipsum pulvinar eleifend. Sed euismod arcu eget tellus rhoncus ultricies. Sed dapibus neque vitae lectus tempus tempus. Maecenas suscipit nulla turpis, in viverra risus venenatis eu.
90
+
91
+ Nam efficitur mauris erat, eu euismod eros tincidunt vitae. Aenean laoreet pharetra volutpat. Donec in dignissim nulla, ac sollicitudin nisl. Praesent ut nunc eget dolor efficitur hendrerit. Cras imperdiet velit sed scelerisque suscipit. Pellentesque pulvinar dolor quis elit interdum, eu euismod augue gravida. Duis lorem lorem, elementum in feugiat pretium, facilisis quis nulla. Cras finibus hendrerit risus, eget imperdiet eros fringilla in.
92
+
93
+ Phasellus quis aliquet ligula, id gravida nibh. Aliquam vitae lorem hendrerit, maximus elit id, luctus nibh. Donec tempus mi ac efficitur bibendum. Aenean vel felis at ipsum accumsan condimentum convallis tempor dolor. Maecenas justo augue, viverra eu commodo id, viverra et augue. Suspendisse nunc tortor, eleifend in egestas in, aliquam non libero. Fusce laoreet quam ut est maximus venenatis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In quis ultricies arcu. Proin vel tempor neque. Donec gravida nisi sit amet leo viverra, non scelerisque ipsum accumsan. Morbi quis neque eu tortor efficitur mattis. Sed rutrum enim ac augue blandit, ut varius dui tincidunt. Praesent quis fringilla erat.
94
+
95
+ Donec ac felis vitae ipsum auctor efficitur ut at dolor. Praesent dictum massa ut libero semper hendrerit. Ut pharetra blandit leo, nec varius ex tristique nec. Aenean sed dolor non lectus vestibulum pulvinar. Integer vel rutrum ipsum, nec vestibulum purus. Nullam non nunc non dui hendrerit fringilla. Integer facilisis, nisi quis blandit varius, quam dolor porttitor erat, ac lacinia diam arcu et tortor. Integer rhoncus purus neque. Proin hendrerit eu elit vel faucibus.
96
+
97
+ Nulla a mi nibh. Etiam a dui leo. Nullam elementum dignissim risus id malesuada. Curabitur at enim augue. Proin id tellus tortor. Pellentesque dignissim turpis quis tristique feugiat. In venenatis efficitur enim sed molestie. Morbi erat ante, iaculis nec condimentum vitae, condimentum vestibulum quam. Vivamus luctus tempus felis id ornare. Pellentesque tempor quam porta tortor tempus scelerisque. Phasellus mattis massa velit, sed feugiat tortor convallis ut. Nulla ultrices neque nec erat rhoncus rhoncus. Maecenas iaculis suscipit dui. Nulla quis ultricies mi. Aenean risus lacus, aliquet in venenatis et, auctor nec mauris. Praesent sagittis justo vel felis commodo faucibus.
98
+
99
+ Ut quis urna sed metus fringilla posuere. Nam sodales viverra arcu, in tristique massa aliquam quis. Nulla eget sagittis leo. Sed ullamcorper luctus enim id rutrum. Nullam fermentum, dui in ultricies rutrum, odio metus tincidunt massa, at elementum felis dui eu turpis. Nullam tincidunt auctor rhoncus. Vivamus et dolor a leo porta tincidunt sit amet eu magna. Integer vel mauris augue. Ut non lobortis eros. Etiam tristique, dui venenatis interdum elementum, ante libero cursus lacus, vitae accumsan risus nunc eget velit. Sed convallis lobortis massa, at consequat justo pretium et.
100
+
101
+ Integer turpis mi, bibendum at nulla a, fermentum ornare quam. Nunc a magna sed elit suscipit interdum non sit amet enim. Sed dignissim fringilla nunc non laoreet. Maecenas eget tincidunt quam. Nullam fringilla est quis velit efficitur dapibus. Donec massa augue, malesuada ac leo et, mattis gravida tellus. Ut sed finibus leo.
102
+
103
+ Donec eu nulla placerat, lacinia ipsum quis, consectetur diam. Phasellus venenatis at velit at iaculis. In ut ex justo. Aenean orci lectus, eleifend sed ante ut, placerat placerat purus. Fusce ac tellus nec ligula pulvinar hendrerit nec sit amet felis. Nullam sed commodo massa. Nam mollis tortor eget odio egestas, et pulvinar arcu feugiat.
104
+
105
+ Nam ut massa a lectus eleifend consequat a id lacus. Suspendisse sed commodo orci. Nam in consectetur risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget nisi dapibus, maximus ex a, posuere lectus. Aliquam nec erat vel orci efficitur faucibus id quis leo. Vestibulum fringilla velit eu dapibus rhoncus.
106
+
107
+ Aenean sodales tortor at massa ultricies, sed tempus lorem accumsan. Cras mattis lectus purus, nec congue sapien commodo at. Aliquam nunc mauris, malesuada vehicula commodo condimentum, imperdiet quis quam. Nulla auctor scelerisque diam non blandit. Nullam iaculis neque id fermentum porttitor. Phasellus sed placerat tellus. Duis tincidunt turpis nec lectus dignissim, ut eleifend nibh rhoncus. Donec porta ut nisl in maximus.
108
+
109
+ Duis scelerisque mi ante, at sollicitudin ex placerat vel. Nulla at purus quis odio tempus mattis vitae at elit. Curabitur iaculis condimentum vestibulum. Donec vel tincidunt nunc. Aliquam aliquet mauris eget ornare commodo. Etiam laoreet vestibulum mi vitae posuere. Fusce suscipit sagittis ex, eget pellentesque mauris imperdiet quis. Etiam sit amet lacus fringilla tortor fermentum suscipit aliquam rutrum magna. Nunc est tortor, vulputate sed ex in, vulputate venenatis eros. Quisque massa nulla, lobortis quis massa vel, commodo placerat tortor. Curabitur egestas lectus ut elit tincidunt varius. Curabitur non fringilla ipsum.
110
+
111
+ Donec rutrum, dui eu accumsan malesuada, dolor metus blandit nulla, in aliquet turpis sem id ipsum. Mauris finibus turpis pellentesque tempor dictum. Pellentesque id libero lobortis, iaculis sem a, dapibus sem. Nam pharetra lectus ut interdum efficitur. Maecenas tincidunt arcu non urna pharetra, sed feugiat mauris facilisis. Nulla eu metus nulla. Proin nec orci vulputate, semper augue sed, fringilla erat. Sed bibendum odio nunc, vel rhoncus ex ullamcorper ut. Etiam vehicula, mi in volutpat pellentesque, tellus nibh malesuada ligula, ut pellentesque augue libero eget lacus. Aliquam quam enim, pretium id libero id, aliquet posuere sem. Donec mollis elit lectus, nec luctus purus dictum ut. Nunc et hendrerit purus. Nullam vel ipsum non nisi finibus pharetra ut sed leo. Nulla augue felis, blandit in sodales vitae, placerat quis lectus.
112
+
113
+ Nunc ut dolor libero. Mauris velit leo, varius ut efficitur ac, imperdiet non magna. Nulla non lacus vel tellus pellentesque viverra at sit amet mi. Vivamus id malesuada quam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Phasellus ultrices libero a erat commodo interdum. Mauris condimentum, mi sit amet luctus posuere, lacus augue iaculis metus, et mollis sapien tellus et orci. Cras feugiat lectus tellus. Suspendisse rutrum, nisl nec accumsan porttitor, metus elit egestas libero, ut luctus tellus nisl nec neque. Mauris eu felis risus.
114
+
115
+ Vestibulum blandit tincidunt nunc, vel condimentum ipsum consectetur sed. Vestibulum tristique, tortor feugiat ultrices auctor, purus nisl sollicitudin est, nec porta magna elit id neque. Suspendisse nec nisl sed lacus pretium pretium vel a eros. Suspendisse ac nisi a mauris tristique mattis nec sit amet elit. Quisque id sem vel nulla dapibus blandit sed ac sem. Aenean suscipit quam a purus laoreet, in accumsan tortor condimentum. Praesent tincidunt luctus varius. Suspendisse interdum nisl quis vestibulum maximus. Mauris a rhoncus metus. Aliquam varius nunc eget neque elementum, id varius quam blandit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum nisi est, blandit eu vehicula et, molestie eu nisl. Donec lacus ipsum, porta ut nibh sit amet, pulvinar eleifend nibh. Praesent vitae dignissim purus, non fermentum nibh.
116
+
117
+ Vivamus sodales lacinia nulla sit amet euismod. Sed gravida scelerisque aliquam. Nam vitae facilisis lorem. Donec sit amet blandit neque. Nullam posuere commodo dolor, eu cursus velit luctus quis. Praesent ut mi quis risus rutrum aliquam quis ac ex. Fusce porttitor dui massa, et pulvinar nulla dignissim a. Donec quis cursus urna. Ut non ex et neque commodo pulvinar nec eu quam. Aliquam id viverra purus.
118
+
119
+ In hac habitasse platea dictumst. Vestibulum ac lectus tristique, euismod velit sit amet, sodales felis. Aenean ut rhoncus odio. Donec velit quam, rutrum a vestibulum ut, suscipit in eros. Donec ut orci id ligula mattis porta. Pellentesque aliquam, orci sit amet tincidunt fringilla, lectus eros vulputate nisi, at vestibulum nibh urna sed nisi. Sed non gravida diam. Proin sit amet sapien tempus, accumsan eros id, rutrum tellus. Vivamus orci nulla, vulputate ac commodo non, viverra nec mi. Vestibulum sit amet mauris et ex feugiat lobortis. Nulla sit amet sem sit amet dui faucibus tincidunt et vitae nisi. Maecenas sagittis, tortor eget rhoncus condimentum, erat turpis tincidunt lacus, non vehicula turpis tortor eu urna. Vestibulum odio enim, malesuada scelerisque lacus eget, tempus lobortis eros. In convallis nunc venenatis ex condimentum tempor.
120
+
121
+ Ut id eros ullamcorper, rhoncus orci at, molestie augue. Donec malesuada maximus ipsum, non accumsan arcu elementum a. Etiam ac commodo nibh, laoreet suscipit nulla. Pellentesque gravida velit a diam porttitor, accumsan gravida augue laoreet. Phasellus pretium odio nibh, at viverra orci tempor quis. Pellentesque et risus ut arcu interdum gravida ac vel tellus. Vestibulum rutrum, quam in lobortis consectetur, nisl lectus fringilla metus, in euismod sapien dui ut ipsum. In ante lacus, blandit sed mi sed, aliquam vulputate elit. Aliquam ultricies dignissim orci euismod consectetur. Donec nisi nulla, vulputate in nulla eget, volutpat posuere sapien. Nunc quis volutpat lectus. Ut eget pellentesque arcu, a pellentesque tellus. Nulla id pellentesque erat. Maecenas auctor pharetra nulla, vitae varius neque. Sed pretium hendrerit imperdiet. Vivamus elementum orci id cursus pharetra.
122
+
123
+ Cras feugiat, neque eget accumsan congue, ex sem tincidunt erat, at interdum dui tortor vel ipsum. Aenean ut dolor in risus blandit interdum vel vitae velit. Aenean consequat tincidunt scelerisque. Ut sed tortor efficitur, ornare sem ut, vestibulum urna. Sed vitae felis justo. Maecenas a placerat lacus. Maecenas suscipit leo at enim ultrices pharetra. In consequat sem sed quam ultricies venenatis. Nunc congue, leo at posuere finibus, tellus risus ullamcorper dui, in pulvinar nisi eros elementum massa.
124
+
125
+ Fusce pharetra felis vel orci cursus, eu euismod velit pulvinar. Proin vel est a ipsum blandit dictum in vitae purus. Ut viverra finibus enim, quis convallis urna euismod sed. Mauris sed sem convallis, euismod arcu nec, placerat urna. Duis id pharetra augue, vel pharetra dolor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam turpis lectus, tristique sit amet justo sit amet, feugiat ultrices erat. Proin porttitor tempor lobortis. Nulla porttitor lectus nec lacus dapibus placerat. Duis porttitor vestibulum mauris. Aliquam blandit diam vitae cursus cursus. Nam augue magna, vehicula id ipsum sit amet, lacinia efficitur justo. Sed placerat sed leo in auctor. Nullam tellus metus, interdum nec justo sed, varius tempor risus.
126
+
127
+ Cras fermentum, neque eget tristique elementum, ex risus dictum mauris, non pellentesque nisl mauris vel velit. Ut aliquam mi ex, eget rhoncus nulla volutpat non. Etiam molestie erat quis tellus condimentum, nec tristique ipsum egestas. In commodo lectus nec aliquam efficitur. Sed quis vulputate enim. Pellentesque rhoncus leo vel lectus elementum luctus. Aliquam dignissim volutpat massa eu imperdiet. Duis non lacus congue, malesuada magna sit amet, tempor nibh. Nunc porttitor tincidunt diam ac convallis. Nam ullamcorper felis sapien, a ornare erat hendrerit eget. Sed faucibus sodales odio nec tempus.
128
+
129
+ Etiam ac iaculis sapien. Nulla non dolor sed nulla varius posuere non quis leo. Donec porta et libero et vehicula. Sed rutrum neque ac ipsum vestibulum lobortis. Duis tristique pellentesque lobortis. Sed a mi eget ipsum lobortis consectetur. Nulla accumsan ornare ipsum, non blandit nisl. Duis pulvinar accumsan mauris et blandit. Mauris scelerisque magna sed lacus pellentesque, sed maximus tellus ornare. Donec eget gravida mi. Vivamus lacinia enim quis pellentesque lobortis. Donec ac ultrices ligula.
130
+
131
+ Vivamus risus diam, dignissim sed ullamcorper a, eleifend eu ipsum. Nulla cursus nisl a risus semper ornare. Curabitur ultrices condimentum tortor, vel blandit ante ullamcorper vel. Sed eu porttitor metus. Proin id posuere magna. Integer venenatis erat eget erat efficitur auctor. Suspendisse potenti. Morbi vehicula, arcu sit amet pretium scelerisque, mauris est ullamcorper mi, eget dapibus libero est in ipsum. Integer ut risus nibh.
132
+
133
+ Sed at consectetur turpis, a finibus ipsum. Donec vel ultrices ex. Suspendisse ut mi et velit maximus finibus. Praesent fermentum vestibulum congue. Donec egestas diam ex, nec vulputate lectus fringilla a. Nullam nulla elit, aliquam ac imperdiet eget, blandit sed nisi. Quisque ex massa, accumsan in convallis in, scelerisque in sem. Duis dictum arcu ut magna consequat, quis consectetur augue viverra. Fusce et consectetur turpis, non tincidunt magna. Maecenas porttitor tortor hendrerit dui gravida fringilla.
134
+
135
+ Etiam quis placerat tellus, sit amet sodales dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas ullamcorper, augue sit amet interdum pulvinar, nisl elit tincidunt tortor, id fermentum sapien nulla sed arcu. Morbi imperdiet velit quis tortor sollicitudin scelerisque. Sed sagittis gravida bibendum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed placerat orci quis arcu sodales congue id tempor libero. Aliquam consectetur orci magna, sed sodales sapien euismod vitae. Aenean id sodales dolor.
136
+
137
+ In auctor finibus orci, vel interdum ligula egestas vitae. Ut at rutrum risus, vitae imperdiet justo. Suspendisse nec ligula velit. Sed suscipit ac magna id aliquet. Pellentesque interdum rhoncus suscipit. Nam suscipit dui leo, consequat blandit dui feugiat ac. In vel metus vitae velit hendrerit venenatis. Sed sed lectus sed tortor mattis posuere nec eu nisi. Maecenas volutpat non justo eget sollicitudin. Nulla a aliquet ante, eget interdum libero. Sed varius maximus diam, quis vehicula dolor egestas a.
138
+
139
+ Mauris sem erat, pharetra quis venenatis nec, porttitor vitae arcu. Donec sagittis eros sed consequat ullamcorper. Cras feugiat purus ut mauris convallis, eu hendrerit mi fringilla. Etiam non hendrerit metus. Nullam quis viverra nisi, a pulvinar lacus. Nullam sollicitudin turpis vel leo ullamcorper, tempor accumsan sapien porttitor. Vestibulum vel facilisis est, eget posuere dui. Donec id est magna. In magna nisl, fringilla sit amet fringilla in, euismod nec est. Nunc viverra nibh metus, in convallis odio interdum nec. Duis orci odio, tristique ac eros varius, feugiat consectetur nibh. Nullam sodales magna convallis, vestibulum nisl eget, elementum lectus. Nulla facilisi.
140
+
141
+ Aenean dictum ligula lectus, sit amet dignissim ex dignissim id. Cras iaculis blandit ultricies. Praesent urna turpis, feugiat sit amet vestibulum quis, varius et nunc. Praesent euismod auctor magna, a eleifend dui euismod eget. Donec sollicitudin, nisl sed sollicitudin vulputate, nunc ex maximus risus, a consectetur ipsum augue ac metus. Proin sit amet arcu lectus. Sed varius lobortis justo, quis imperdiet mi molestie ac. Quisque consequat sit amet ex nec vulputate. Donec ullamcorper porta mi, vel iaculis odio blandit vitae. Nulla sed sapien lorem.
142
+
143
+ Cras sagittis vestibulum turpis, at vestibulum turpis porttitor sed. Phasellus sit amet imperdiet mi, non porta neque. Maecenas pulvinar nisi a ligula euismod, sed fringilla nulla pharetra. Quisque eget sollicitudin tellus. Aenean mattis ut sem at condimentum. Etiam velit nisi, faucibus ac facilisis ut, posuere eu turpis. Sed consectetur, lectus ut consectetur rhoncus, nibh augue pulvinar dolor, in malesuada quam neque id mi. In convallis a mi vitae semper. Nunc gravida maximus nunc, ut varius ante dapibus elementum. Integer efficitur orci nec augue faucibus, at eleifend sapien facilisis. Vivamus at cursus elit. Mauris in finibus est. Sed non laoreet erat, a condimentum arcu. Mauris non ultrices erat, et consequat lacus.
144
+
145
+ Aenean imperdiet eros ac rutrum tincidunt. Etiam elementum magna justo, id lobortis dolor pretium id. Suspendisse sit amet consectetur justo. Vivamus aliquet ipsum et nisi facilisis, id mattis augue ornare. Proin id enim ac nibh tristique mollis id eu nunc. Suspendisse imperdiet ex gravida, porttitor dui ut, hendrerit tellus. Praesent et interdum nisi. In magna lectus, ultricies non gravida sed, pellentesque eu quam.
146
+
147
+ Quisque sagittis sem varius ante pellentesque, a mollis justo dignissim. Nam mollis commodo leo, eget gravida turpis. Curabitur eget dignissim nunc. Aenean feugiat congue augue. Nulla aliquet enim enim, vitae dignissim lacus scelerisque vel. Proin vitae leo egestas, iaculis erat eu, blandit sem. Phasellus imperdiet ligula magna, eu ullamcorper dolor dignissim vitae. Nunc luctus, metus in convallis convallis, neque nisl ultrices sem, vel ultrices orci mi vel mauris. Maecenas sagittis iaculis ante quis iaculis. Donec auctor tincidunt venenatis. Nulla vehicula, augue eget tincidunt bibendum, felis magna rhoncus libero, at egestas ante felis nec odio. Ut ut porta felis. Curabitur neque justo, consequat fringilla faucibus sed, efficitur id leo. Sed mi lacus, congue id nisi at, sodales tincidunt erat. Vestibulum ultrices finibus felis quis ultrices. Proin dictum convallis nulla, et finibus nunc consectetur laoreet.
148
+
149
+ Etiam aliquam bibendum tellus, nec tempor mi dapibus ac. Ut nibh turpis, condimentum et metus in, auctor laoreet nulla. Curabitur sit amet felis diam. Maecenas leo tortor, pharetra non feugiat ac, vehicula eget sem. Sed nulla leo, interdum tincidunt lobortis in, gravida eget dolor. Cras aliquam quam nec suscipit gravida. Integer eleifend eros tempus lectus sodales pharetra. Pellentesque ante augue, lobortis eget risus sit amet, efficitur suscipit purus. In sed arcu in lacus elementum sollicitudin in euismod ante. Sed condimentum, arcu at elementum fermentum, ligula dui gravida purus, eget hendrerit justo augue at tellus. Aenean laoreet a mauris id rutrum. Nulla tristique nec purus in efficitur. Donec ultrices, nisi ac laoreet tristique, tortor nisl bibendum arcu, non facilisis orci magna eleifend massa. Vivamus eros purus, finibus vel augue sit amet, feugiat imperdiet turpis. Morbi et risus ut elit lobortis accumsan.
150
+
151
+ Morbi feugiat quam tempor commodo ultrices. Curabitur ornare dui ac nisi finibus euismod. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas nec risus malesuada, pellentesque justo sed, tristique dui. In venenatis id turpis vel fermentum. Vivamus eu interdum ligula. Duis ultricies velit nec est convallis lacinia ut ut nisi. Sed lectus nulla, euismod at convallis nec, molestie eleifend lorem. Maecenas mattis, lacus ut tempor lacinia, felis odio aliquam ante, eu aliquam velit urna sit amet metus. Proin rhoncus nisl ac viverra condimentum. Vestibulum porttitor eros justo, eu laoreet velit suscipit at. Aliquam erat volutpat. Aliquam at erat eu dui lacinia sollicitudin. Sed iaculis leo at mi fringilla mollis. Curabitur facilisis risus vel sollicitudin ornare. Morbi pretium eros sem, nec fermentum ante aliquet eu.
152
+
153
+ Duis ac euismod urna, et fermentum nunc. Donec congue aliquet fringilla. In tempus, ex a tempus pulvinar, felis turpis cursus lorem, vitae suscipit leo sem vel dui. Suspendisse imperdiet nisi imperdiet augue mattis aliquam. Nunc eleifend, felis vitae tempus commodo, nulla tellus fringilla ipsum, sit amet egestas lorem ligula et diam. Integer velit velit, tincidunt vel velit eu, semper egestas ipsum. Phasellus hendrerit lacus in nunc aliquet, sit amet vehicula sapien feugiat. Donec sit amet suscipit quam. Fusce sagittis quam in efficitur dignissim. Aenean auctor feugiat tempor.
154
+
155
+ Duis non eros porta, sodales nunc in, efficitur diam. Suspendisse potenti. Proin ullamcorper augue ut odio molestie elementum. Nam sodales massa sapien, et blandit felis elementum nec. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a consequat nibh. Vivamus blandit, neque et varius commodo, neque nunc convallis neque, in porta ligula nulla vitae leo. Integer tincidunt condimentum tortor ac tristique. Integer quis metus sit amet metus interdum semper. Morbi consequat sem pellentesque, consequat erat sed, tincidunt diam. Nulla massa massa, accumsan in sem at, rhoncus pulvinar urna. Duis a diam at nisi consectetur imperdiet vitae sit amet elit. In hac habitasse platea dictumst. Nulla auctor mauris in quam malesuada ullamcorper. Nulla in enim velit.
156
+
157
+ Mauris vel justo quis massa posuere suscipit. Pellentesque fermentum enim elit. Phasellus laoreet risus sed feugiat volutpat. Fusce nec condimentum erat. In lorem nisl, dictum et quam vel, mattis aliquam libero. Donec magna eros, aliquam ac elementum ac, faucibus non justo. Nam sit amet libero tincidunt, dapibus sapien vitae, bibendum lorem. Mauris at elit in mauris semper fermentum. Proin tempor lectus sed orci auctor fringilla. Pellentesque urna augue, pellentesque ac magna ac, mattis molestie ex.
158
+
159
+ In non posuere lectus, quis pretium augue. Aliquam tincidunt, dui vitae placerat ultricies, felis diam lobortis ligula, a iaculis tortor augue nec felis. Fusce mattis, tellus sed blandit maximus, libero massa tristique ex, eget dapibus ante turpis ac sem. Curabitur fermentum, sapien et malesuada eleifend, tellus magna eleifend sapien, sed placerat magna quam id lorem. Proin vel nulla id justo porttitor fermentum. Nunc erat ante, elementum vel blandit nec, consequat a quam. Curabitur id metus nunc. In ut nibh placerat, sagittis nulla congue, tincidunt justo. Suspendisse blandit massa nec nulla gravida, vitae facilisis dolor ultrices.
160
+
161
+ Pellentesque pharetra nunc ut velit rutrum, vitae tempus ipsum bibendum. Suspendisse potenti. Praesent viverra efficitur tellus, eu convallis ex laoreet suscipit. Phasellus volutpat ante nisl, in rhoncus urna ultrices tincidunt. Donec eget mi non turpis interdum rutrum quis sit amet dolor. Aenean tincidunt venenatis elit at volutpat. Vivamus magna sapien, interdum bibendum fringilla tincidunt, dapibus quis lorem. Aliquam aliquet, urna vel laoreet dictum, nisi arcu fermentum lectus, a venenatis nisl enim congue diam. Praesent faucibus urna sit amet dapibus consequat. Suspendisse vulputate quam mauris, non efficitur diam pulvinar vitae. Pellentesque at tincidunt dui. Suspendisse aliquam, risus nec semper placerat, orci arcu faucibus leo, a aliquam lacus ante id magna. Aenean posuere mi libero, ut interdum nisi varius non.
162
+
163
+ Pellentesque aliquet mauris a interdum volutpat. Nulla dictum mattis libero, non iaculis justo porta a. In hac habitasse platea dictumst. Aenean eget purus in odio commodo convallis. Sed sagittis sapien vel nisi auctor gravida. Vivamus rutrum at lorem non tincidunt. Aenean malesuada lobortis magna, a posuere dui semper id.
164
+
165
+ Integer eu velit ligula. Nulla feugiat fringilla justo et tincidunt. Nunc efficitur nulla sed elit posuere pretium. Fusce aliquet sed ex ut pulvinar. Ut non congue mauris, eget ornare eros. Maecenas lacinia ex non augue aliquet sagittis. Quisque sed velit sed elit feugiat luctus et vitae dui. Vivamus dignissim quam et dapibus finibus.
166
+
167
+ Aenean a sapien sed augue tempus tempus non et risus. Cras a mi sed nulla fermentum egestas. Vivamus turpis neque, tempus vel porttitor vel, venenatis vitae metus. Nam condimentum tincidunt imperdiet. Morbi sed nisl quam. Integer vitae consequat enim, eu fermentum elit. Praesent nunc ante, elementum nec lectus non, dignissim luctus diam. Curabitur vulputate accumsan nulla eu malesuada. Suspendisse in lorem volutpat, finibus tortor sit amet, venenatis neque. Vivamus vel placerat massa. Nulla vitae mi in massa luctus hendrerit.
168
+
169
+ Duis dapibus nibh non augue ornare, nec lobortis nulla dignissim. Sed dapibus tortor non sem feugiat, vitae elementum lacus lobortis. Donec sagittis egestas orci, convallis accumsan dolor vehicula viverra. Nullam blandit ante ligula, id dignissim ipsum eleifend vitae. Proin ullamcorper lectus at nibh eleifend ullamcorper. Aenean odio ipsum, volutpat blandit mi quis, lacinia accumsan lorem. Mauris ultrices lacinia nibh, in sodales ligula volutpat eu. Phasellus lobortis eu ipsum ac scelerisque. Cras velit lectus, cursus sed nisl ut, sollicitudin malesuada eros. Etiam fermentum tortor in massa dignissim convallis. Proin in sapien id purus scelerisque malesuada ut interdum dolor.
170
+
171
+ Ut tristique vestibulum metus. Donec non cursus nunc. Vivamus vehicula metus sit amet velit tempus aliquam. Curabitur pellentesque nisi sed ex maximus placerat. Curabitur elit dolor, laoreet sed lacus nec, tempor facilisis mi. Aliquam urna ante, fermentum quis congue ac, luctus vel nunc. Sed vel magna sollicitudin, commodo lacus ac, ullamcorper lectus.
172
+
173
+ Donec molestie, ligula eu convallis efficitur, velit mi consectetur sem, ut congue quam nulla et felis. Nunc fringilla lacus quis suscipit laoreet. Quisque vel tempor tortor. Integer luctus mauris vitae sapien luctus, vel suscipit urna malesuada. Vestibulum bibendum sollicitudin ipsum, et pellentesque velit venenatis a. In eu sapien quis est euismod rhoncus vitae sed massa. Duis efficitur mauris ut mollis sollicitudin. Nunc non lectus vel diam vehicula convallis at eleifend leo. In cursus ex quam, ac vehicula elit sagittis eu. Nullam fermentum lacinia bibendum. Sed quis nulla eget magna feugiat congue. Praesent a lacus quis leo maximus tincidunt. Pellentesque scelerisque dignissim mauris sed tempor.
174
+
175
+ Nam non metus nec est scelerisque laoreet. Sed non sem quis nisl hendrerit consequat. Nunc mattis lorem at lectus convallis, eu dapibus est suscipit. Etiam vitae viverra magna. Fusce sit amet ex ut ex venenatis ultrices. Aenean porttitor augue turpis, in scelerisque massa placerat ac. Vestibulum malesuada orci dignissim tortor porttitor, vitae bibendum erat sollicitudin. Aliquam nulla leo, varius at ipsum a, commodo hendrerit ligula. Phasellus iaculis ac sem sit amet mattis. Suspendisse blandit vitae lectus et commodo. Sed turpis orci, iaculis id ante at, venenatis pulvinar neque. Etiam efficitur mi arcu, vel feugiat metus viverra sit amet. Proin malesuada rutrum ligula, et ultricies purus gravida sit amet. Vestibulum luctus ullamcorper risus id sollicitudin.
176
+
177
+ Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras commodo lacus non sodales rutrum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed ac malesuada lacus. Praesent bibendum libero sem, non tincidunt tortor cursus sed. Cras ac ipsum id ipsum condimentum sodales vitae tincidunt velit. Nam volutpat mollis augue id faucibus. In finibus, sem sit amet molestie mollis, ante tortor mattis erat, euismod sagittis odio nibh vel lectus. Morbi sollicitudin, lorem et vehicula blandit, risus diam iaculis nisl, vel finibus massa neque tempor velit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque dignissim in neque sit amet faucibus. Phasellus sit amet ultrices sem. Donec dui enim, porta in diam at, ullamcorper ornare dolor. Cras dignissim sapien nisi, at auctor odio venenatis ut. Donec pharetra dui ac nisl semper mattis.
178
+
179
+ Pellentesque finibus diam sit amet accumsan viverra. Donec accumsan lacinia interdum. In consequat nisl id velit auctor, ac congue nunc elementum. Integer et arcu nec ligula commodo pretium. Maecenas rhoncus justo sed dolor ornare, ut posuere dolor consectetur. Pellentesque non sapien vel neque ullamcorper venenatis ac eget massa. Ut sed magna erat. In vel aliquet purus. Phasellus suscipit lacus vel lacus lobortis, sit amet auctor arcu rhoncus.
180
+
181
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam euismod eros finibus posuere efficitur. Nunc viverra massa in urna venenatis pharetra. Donec sed eros quis sem porttitor maximus non vitae diam. Etiam eget condimentum odio, at dictum purus. Vestibulum vehicula mauris at felis pulvinar, in aliquet purus molestie. Nullam quis ante rhoncus, feugiat felis at, bibendum mi. Sed iaculis ante quis nisl faucibus interdum. Pellentesque ut nulla sed neque luctus lacinia condimentum sed ante. Proin in lorem sagittis, blandit diam sed, dictum nibh. Suspendisse luctus lacus elit. Nunc nec enim a nunc consectetur faucibus eget quis leo.
182
+
183
+ Pellentesque felis est, tincidunt nec ex dictum, lacinia bibendum est. Praesent convallis massa risus, vitae laoreet velit accumsan suscipit. Nullam nec eros nec quam mattis aliquet. Proin vel molestie odio. Nulla quis eros non odio tincidunt accumsan at vitae enim. Vivamus et tellus turpis. Proin ac rutrum velit. Vivamus in neque molestie, elementum enim a, lacinia felis. Suspendisse potenti. Morbi id nisi pharetra dolor pellentesque vulputate vitae nec est. Morbi dolor eros, tincidunt id nibh a, eleifend hendrerit mi. Vivamus sit amet libero orci. Suspendisse non sapien sit amet odio sagittis interdum. Maecenas at leo augue.
184
+
185
+ In hac habitasse platea dictumst. Phasellus erat mi, sagittis eu nunc et, tristique cursus sem. Duis tellus elit, condimentum non est sit amet, vehicula lacinia massa. Mauris tincidunt, urna in rutrum bibendum, odio mi rutrum eros, in dapibus nisi neque non odio. Maecenas in odio ac erat auctor elementum nec id erat. Ut finibus dictum condimentum. Donec dapibus auctor sem et iaculis. Suspendisse potenti. In at ipsum sit amet est sagittis euismod. Proin ut nunc nec lectus pharetra euismod nec faucibus sem. Vestibulum venenatis facilisis euismod. Pellentesque eget augue at mauris varius varius. Nunc erat quam, sollicitudin id mollis id, dictum ut purus. Integer nec neque eget odio tincidunt facilisis ac sed nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
186
+
187
+ Pellentesque pulvinar mi varius, euismod turpis a, dapibus neque. Mauris id metus non ante ultricies faucibus sit amet vel enim. Vestibulum fringilla dictum pellentesque. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Mauris iaculis finibus neque ut molestie. Maecenas at volutpat lorem. Sed vitae scelerisque sem, porta viverra diam. Maecenas nec condimentum sapien. Nulla facilisi. Nullam non sem id nisi aliquet viverra. Vestibulum pretium massa ac ornare blandit. Vivamus egestas ante non velit commodo vulputate. Duis pretium nulla dolor, sit amet ullamcorper metus aliquam id. Quisque vulputate eu lorem eu tincidunt.
188
+
189
+ Vivamus nec lorem nisl. Suspendisse euismod metus eu nunc euismod interdum. Sed a arcu porttitor, cursus mauris quis, faucibus neque. Suspendisse id ultrices tortor. Morbi finibus nec massa at semper. Vivamus et fermentum risus. Morbi eu tempus massa. Donec in risus rhoncus, varius metus eget, dapibus massa. Suspendisse non sem ac est facilisis cursus. Vestibulum pellentesque nibh aliquet facilisis molestie. Pellentesque et odio auctor, iaculis quam ut, porta dui. Nunc lobortis purus ac ornare molestie. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
190
+
191
+ Vestibulum vel justo ante. Etiam ligula neque, dignissim ut erat vel, iaculis suscipit quam. Mauris erat lacus, rutrum eget auctor non, facilisis auctor tortor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras tristique ac purus id fermentum. Curabitur commodo lectus eu urna fringilla, eu cursus risus feugiat. Vestibulum et faucibus massa. Fusce scelerisque in nisi quis maximus. Aliquam ornare velit orci, et egestas lorem convallis a.
192
+
193
+ Nullam vitae turpis neque. Proin cursus euismod quam, eu fermentum purus dapibus et. Nulla sed justo lobortis, pellentesque tellus eu, iaculis purus. Nulla rhoncus urna sit amet arcu commodo molestie ut at ipsum. Nullam mattis bibendum quam, eu rutrum diam malesuada at. Pellentesque ullamcorper malesuada leo et sollicitudin. Maecenas vulputate consectetur enim et ullamcorper. Proin nec dignissim massa, non tristique lorem. Donec mattis non nunc sit amet consectetur. Cras id egestas risus. Vestibulum nec convallis tortor, quis sagittis libero. Sed sapien ipsum, molestie in vulputate in, scelerisque id orci.
194
+
195
+ Duis consectetur neque vitae purus fermentum tincidunt ac ut est. In hendrerit congue nisi vel dictum. Sed interdum ullamcorper nisl sit amet varius. Duis lobortis aliquet rutrum. Mauris elit ante, mollis sit amet euismod eu, malesuada vitae mi. Etiam quis dignissim nisl, quis feugiat quam. Aliquam eu purus elit. Phasellus ut arcu feugiat, rhoncus risus vitae, tempor eros. Donec suscipit vulputate nibh, at faucibus dolor egestas in. In id quam blandit, eleifend quam sed, suscipit tellus.
196
+
197
+ Donec eu mattis dolor. Proin fermentum lobortis lorem, et suscipit risus iaculis quis. Duis egestas rutrum lacus blandit semper. Sed eget bibendum ante. Curabitur id arcu pharetra, feugiat erat nec, convallis risus. Nunc mollis magna gravida, fringilla erat sit amet, vulputate magna. In pulvinar turpis a ligula sagittis, vitae pharetra dui gravida.
198
+
199
+ Pellentesque a fermentum tortor. Ut consectetur posuere sagittis. Quisque vestibulum eros dolor, vitae suscipit est sagittis eu. Quisque elementum mollis maximus. Cras at arcu sit amet erat volutpat lobortis. Aenean et bibendum libero, eu placerat nisi. Curabitur felis orci, molestie quis arcu vitae, hendrerit commodo nunc. Nam nisi odio, maximus non dolor id, maximus malesuada nisl. Nam ut quam metus. Cras porta, ipsum et mollis pretium, ex sem finibus lorem, a cursus ligula felis vitae turpis. Donec auctor pretium nulla, vitae consectetur enim lacinia et. Quisque placerat mi massa, eu cursus velit eleifend vel. Sed pulvinar dolor vel lorem lobortis hendrerit sed ac lorem. Phasellus luctus in ante ac ornare. Nullam rhoncus at lacus id iaculis.
200
+
201
+ Pellentesque bibendum nec risus eget malesuada. Proin mattis eget odio nec rutrum. Donec viverra, enim non imperdiet tristique, quam ipsum imperdiet diam, ac consequat felis odio in turpis. Nunc imperdiet risus urna, a fermentum mauris mattis nec. Ut eget luctus urna. Sed a nibh lobortis, facilisis risus in, laoreet diam. Duis ultricies sed ligula eget pellentesque.
202
+
203
+ Donec consectetur vulputate arcu sed cursus. Cras scelerisque mauris dolor, non molestie sapien dictum et. Duis elementum justo purus, quis pretium nunc pellentesque eu. Nulla facilisi. Cras in malesuada mi, ut sodales nisl. Ut metus lacus, porta nec vehicula euismod, ultrices ac tortor. Phasellus sit amet turpis eu lacus imperdiet malesuada. Vivamus porta libero sed tincidunt ultrices. Mauris lacinia faucibus ante quis volutpat.
204
+
205
+ Quisque interdum commodo metus ac tempor. Mauris nisl odio, euismod vel mi vel, porta facilisis orci. Nam vehicula turpis arcu. Suspendisse tempor est eu quam molestie facilisis. Donec vel lacinia est. Morbi elementum quam sed tempus tempus. Pellentesque sed eros augue. Vestibulum semper odio venenatis sapien finibus, eget semper justo consectetur. In venenatis molestie rhoncus. In hac habitasse platea dictumst. Vivamus accumsan tristique orci placerat sagittis. Vivamus venenatis, nisl nec rhoncus dignissim, urna ex sodales ex, id gravida diam lorem vitae libero. Aenean sed lacus velit. Quisque dapibus congue nibh, et efficitur ante. Nullam sed nisi et purus bibendum suscipit. Praesent erat tellus, elementum quis nisi vitae, pretium vulputate sem.
206
+
207
+ Phasellus imperdiet vestibulum tortor sit amet tristique. Aenean arcu arcu, iaculis eget tincidunt a, convallis finibus turpis. Phasellus vulputate nunc et turpis fermentum, id accumsan metus pulvinar. Donec in tristique neque. Quisque dui massa, fringilla eget pharetra in, pulvinar nec urna. Etiam sollicitudin luctus tortor eget sagittis. Phasellus viverra sodales urna, sit amet tempus quam molestie a. Sed sed vulputate dolor. Duis enim nulla, porttitor ut mollis et, dictum quis arcu. Suspendisse potenti. Maecenas sit amet mi dignissim, aliquet est nec, lobortis turpis. Maecenas semper mollis urna ac tincidunt. Aliquam posuere, metus nec rhoncus dapibus, quam ante sollicitudin massa, id ornare metus enim et nulla. Praesent nec ipsum et augue fermentum bibendum. Vivamus nec aliquet dui.
208
+
209
+ Aenean vehicula erat fermentum faucibus dapibus. Donec feugiat bibendum lacus vitae tristique. Donec eu nisi ut mi commodo suscipit a vel purus. Curabitur commodo quam eget quam gravida suscipit. Sed nec mollis velit. Fusce mi erat, hendrerit ac hendrerit sed, mollis sit amet dolor. Sed vitae rhoncus magna, quis iaculis ligula. Nullam accumsan est eu pellentesque ultrices. Nunc consectetur, ligula in porta congue, nunc nulla iaculis massa, et pharetra ante eros non massa. Donec pellentesque pulvinar porttitor. Donec vel efficitur risus. Nulla facilisi. Curabitur ultricies sagittis nisl, vel consequat mi ultrices at.
210
+
211
+ Suspendisse lectus justo, imperdiet in diam ac, posuere varius eros. Nunc pretium convallis auctor. Vivamus sit amet dictum libero, eget porta lectus. Donec non congue enim, ac vulputate nibh. Nulla posuere eros in odio venenatis, nec hendrerit libero pulvinar. Duis in nibh orci. Praesent odio metus, suscipit et metus at, ultrices tristique nulla.
212
+
213
+ Donec tellus urna, imperdiet in odio eu, consequat ultrices metus. Sed non mi magna. Nunc sit amet ultrices est. Sed libero ipsum, pretium tristique mi et, rutrum tristique magna. Nunc odio nisi, ultrices quis elementum non, ornare nec arcu. Quisque luctus rhoncus tortor, et venenatis augue semper ac. Donec non sapien ac neque tempor rutrum vitae eu nulla. Etiam hendrerit, tellus in venenatis pulvinar, mi ante blandit massa, venenatis suscipit nunc lectus at erat. Ut interdum nibh dolor, eget vestibulum sapien accumsan sed. Sed pretium convallis felis ac vestibulum. Suspendisse vel sem maximus, porta nulla vitae, tristique magna. Vivamus volutpat blandit elit, quis feugiat arcu laoreet at. Curabitur velit est, vulputate ac lectus eu, euismod maximus lacus. Aenean maximus nisi non felis aliquam, et viverra eros imperdiet.
214
+
215
+ Aenean id scelerisque ipsum, nec feugiat ex. Vivamus porta sem dolor, id ultrices massa dictum nec. Donec ex lacus, pretium sed imperdiet auctor, facilisis et tellus. Phasellus eu enim tincidunt, maximus velit ac, rutrum nibh. Vivamus urna erat, fringilla nec viverra et, mattis sed lorem. Aenean ornare consequat eros, at feugiat metus. Sed in varius libero. Praesent laoreet fermentum tincidunt. In hac habitasse platea dictumst. Morbi vehicula nisl vitae ex vulputate, pulvinar mollis erat lacinia.
216
+
217
+ Curabitur a tellus gravida, sodales neque nec, volutpat erat. Suspendisse vehicula eleifend aliquam. Morbi rhoncus nisl dolor, condimentum dapibus quam feugiat eget. Nam posuere lacus aliquam risus porta, nec accumsan libero rutrum. Integer vehicula diam urna. Vivamus eu odio sit amet nibh mattis tincidunt sed et metus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis tristique neque sed lacus ornare, in ultricies mauris mattis. Sed imperdiet, ante quis posuere cursus, urna ex commodo purus, sed sollicitudin neque mauris vitae nisi. Vestibulum nec iaculis nisi. Etiam sed orci ultricies, ornare lorem eget, ullamcorper est. Aliquam erat volutpat. Sed consequat porttitor ipsum et rhoncus. Vivamus a interdum elit. Etiam quis mi elit.
218
+
219
+ Etiam eros mauris, tincidunt non augue at, maximus cursus purus. Quisque feugiat ligula non arcu aliquet, quis ultrices sem semper. Proin varius est erat, id sodales purus ultricies sit amet. Sed et euismod sapien. Donec ut vehicula leo. Donec congue libero sed lectus fringilla, quis aliquam odio dapibus. Nullam at lorem nisl. Vivamus tristique est mauris, ac lobortis urna tincidunt eu. Proin laoreet tristique facilisis. Nulla facilisi. Donec quis enim quis odio egestas sagittis eget a elit. Mauris est nulla, mollis eget lacus a, ornare congue metus.
220
+
221
+ Sed molestie elit eu nisl interdum, et cursus quam viverra. Aenean mollis libero sit amet congue maximus. Quisque in ante tincidunt, rhoncus neque vel, faucibus lorem. Vivamus sed massa neque. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi eleifend massa sed elit luctus, nec rhoncus ante hendrerit. Sed hendrerit vulputate quam, quis dictum metus venenatis maximus.
222
+
223
+ Cras sed porta lorem. Etiam a est ipsum. Cras semper molestie mi nec porttitor. Suspendisse eu convallis sem, ut ultricies ligula. Integer interdum ante eget sem mollis, nec feugiat augue euismod. Maecenas et nisi tristique, consequat risus vitae, luctus nisl. Phasellus felis purus, egestas non velit in, eleifend ullamcorper sem. Aliquam non ullamcorper diam, eu viverra enim.
224
+
225
+ Vestibulum vel nisi magna. Proin ornare odio urna, in iaculis mauris dictum sit amet. In ultricies velit in lectus bibendum, in euismod ante consequat. Vestibulum porttitor accumsan elit. Donec suscipit semper ex vel gravida. Nam pretium convallis orci ut efficitur. Curabitur dictum dui vitae est aliquam, at faucibus quam molestie. Nam vel bibendum ex. Duis luctus ex in odio sagittis venenatis. Curabitur consectetur velit nulla, eu elementum erat mattis quis.
226
+
227
+ Sed suscipit odio et ante ultricies, sed egestas tortor vehicula. Aliquam quis metus non nunc sodales molestie. Praesent laoreet eu quam non egestas. Phasellus pulvinar, mi a luctus accumsan, ex lorem consectetur massa, nec facilisis est leo in sapien. Nam gravida libero id venenatis mattis. Nunc tincidunt dui quis dolor accumsan, id ornare velit luctus. Suspendisse mattis vehicula malesuada. Aenean eu turpis non libero tincidunt ultrices. In non dapibus nisl. Ut ut lobortis eros. Nulla scelerisque sem tellus, id lacinia magna feugiat id. Proin at odio vitae magna congue feugiat. Vestibulum magna massa, condimentum ac semper a, pellentesque vitae lectus. Nulla eget nunc at neque sagittis egestas. Nunc pretium luctus leo, hendrerit sagittis lacus pellentesque vitae. Phasellus at libero id lectus efficitur molestie.
228
+
229
+ Curabitur efficitur finibus diam ac volutpat. Nam lobortis hendrerit magna a ultrices. Quisque molestie lobortis gravida. Cras a scelerisque dolor, vitae tristique dolor. Pellentesque nec molestie risus. Pellentesque tortor orci, hendrerit sit amet tortor vitae, bibendum consectetur urna. Vestibulum tempus molestie sapien in viverra. Interdum et malesuada fames ac ante ipsum primis in faucibus. Aliquam placerat est vel sodales semper. Vestibulum et turpis enim. Integer egestas laoreet suscipit. Aliquam nisl odio, viverra non volutpat non, iaculis sed neque. Nam aliquet ipsum non urna aliquam, vitae mattis lorem placerat. Praesent in faucibus eros. Fusce molestie nec tellus eu egestas. Suspendisse dictum vestibulum felis, ut scelerisque quam pulvinar at.
230
+
231
+ Duis bibendum vel justo nec condimentum. Nam sit amet tempor ex. Suspendisse turpis elit, tincidunt quis sollicitudin at, faucibus in nulla. Proin eget vulputate dui, vitae convallis sem. Mauris a congue lectus. Sed eget metus eu magna posuere vulputate ac non risus. In id augue eget neque bibendum vehicula. Nullam at tempus urna, eget dapibus odio. Aliquam quis gravida velit. Quisque dapibus lectus eu diam tempor, sit amet ullamcorper leo viverra. Donec vulputate orci velit, vel dapibus leo rhoncus eu.
232
+
233
+ Donec scelerisque non ipsum eget porta. Ut ac nisi quis libero laoreet venenatis. Etiam viverra ornare ex, volutpat maximus risus gravida et. Donec lobortis pellentesque risus sit amet ornare. Proin pellentesque accumsan dui eu ullamcorper. Vestibulum vel arcu ex. Nulla facilisi. Maecenas fringilla velit sed eros auctor sodales. Morbi at ultricies augue.
234
+
235
+ Fusce eu pharetra nulla. Quisque sed nulla non tortor fermentum semper. Maecenas porta magna non odio pulvinar gravida. Duis a nisi sit amet ante tincidunt tristique. Aliquam iaculis scelerisque massa at dapibus. Suspendisse at tortor lectus. Sed non lacus purus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris aliquet ante eu quam feugiat, sit amet laoreet elit finibus. Donec ac massa et enim mollis ultricies vitae et eros. Vivamus mauris purus, mattis id gravida eget, iaculis a nisi. Nulla at sapien id purus tincidunt ultrices pulvinar a risus.
236
+
237
+ Phasellus placerat ipsum nec urna finibus fringilla. Duis accumsan odio mi, in tempus ante finibus eu. Nulla facilisi. Aenean augue nisi, interdum ut nibh in, laoreet vehicula ligula. Fusce eget lorem nunc. Morbi ut ultricies nisi, id viverra quam. Quisque non malesuada mi, sit amet dignissim felis. Nunc ornare vitae est in feugiat. Phasellus erat libero, suscipit in nisi a, pretium accumsan sem.
238
+
239
+ Maecenas ultrices fringilla hendrerit. Fusce id risus non sapien fermentum vulputate. Cras in lectus nec lorem elementum mollis nec id mauris. Phasellus sit amet tortor id mi egestas aliquam et sed est. Ut ultricies mollis iaculis. Fusce orci ex, consectetur vel faucibus id, mattis semper turpis. Donec dapibus dapibus euismod. Duis sed tincidunt nisl. Sed ultrices neque quis nunc gravida, in ultrices lorem posuere. Phasellus justo mauris, blandit quis diam nec, pulvinar elementum nisi. Curabitur pharetra tincidunt auctor. Donec in semper orci, et pulvinar purus. Etiam convallis elit ac finibus sollicitudin. Fusce purus nibh, pharetra at lacus eu, venenatis lacinia massa. Donec elit erat, fringilla sed auctor ut, bibendum non ante.
240
+
241
+ Vestibulum neque justo, egestas id lacinia ut, euismod ac arcu. Nullam justo nibh, interdum at purus ut, aliquet dignissim risus. Phasellus a justo ornare urna tempus hendrerit eget quis lectus. Nunc bibendum quam quis ligula sodales, et vestibulum leo pharetra. Mauris rutrum nisl et libero consectetur dapibus. Sed porta tincidunt laoreet. Quisque id enim sed mi pellentesque auctor. Nam volutpat ultricies arcu sed dictum. Quisque sollicitudin sed sapien ut lacinia. Morbi dictum lorem a massa ultricies feugiat. Nulla eu massa et odio convallis porttitor.
242
+
243
+ Fusce et pulvinar sapien, at ultricies nulla. Aliquam posuere arcu non viverra condimentum. Phasellus aliquet molestie massa, in molestie massa consectetur eu. Vivamus eu risus laoreet, vehicula elit eu, ultrices eros. In molestie, risus at sodales tincidunt, sem sapien venenatis metus, eu ornare lectus ligula sed urna. Praesent varius tortor tellus, id scelerisque ex commodo sit amet. Sed dictum lacus ex, nec vestibulum nulla egestas vel. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eget feugiat diam.
244
+
245
+ Duis erat ante, semper et lacus et, egestas ultricies lectus. Nullam enim felis, rutrum sed faucibus eget, dictum ut justo. Vivamus venenatis diam sit amet felis luctus interdum. Maecenas facilisis nec est ac bibendum. Donec scelerisque quis velit ac ornare. Quisque lorem felis, dignissim sit amet diam sed, egestas egestas ipsum. Suspendisse potenti. Suspendisse faucibus vulputate mauris, sit amet blandit ex porta a. Praesent venenatis non elit quis feugiat. Phasellus purus sem, volutpat ac velit et, laoreet faucibus lectus. Ut facilisis sed ligula eget porttitor. Duis mi lorem, ullamcorper a mi vitae, pulvinar mollis dolor.
246
+
247
+ Ut quis sollicitudin dui. Donec vehicula porttitor libero, sit amet viverra magna consectetur vitae. Donec viverra luctus ante et egestas. Donec sodales aliquet nulla, in mollis purus lobortis vel. Proin vitae faucibus turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed nec sagittis tellus. Vestibulum porttitor lacinia augue, et rutrum orci dignissim eget. Duis vulputate aliquam tortor nec ornare. Etiam et varius diam. Aenean sit amet lectus efficitur velit scelerisque aliquam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
248
+
249
+ Suspendisse nisl eros, suscipit quis lacus feugiat, hendrerit vulputate ante. Donec vestibulum lectus vel maximus vulputate. Vivamus suscipit est ac tellus fringilla, tempus bibendum dolor fringilla. Phasellus facilisis mi eu enim tincidunt dignissim. Phasellus aliquet, est tempus imperdiet suscipit, massa orci sodales lectus, eu vulputate purus massa a tortor. Morbi pellentesque lectus eu ex efficitur, a rutrum leo suscipit. Pellentesque vel risus at ipsum aliquet varius ut eu ligula. Vivamus luctus lacus mi, eu dapibus tellus accumsan at.
250
+
251
+ Phasellus ut egestas odio. Ut eget elit malesuada, iaculis massa id, consequat ex. Duis eget rhoncus leo. Nullam lobortis vestibulum velit, sit amet consequat mi dapibus consectetur. Sed a rhoncus ipsum, eu pulvinar nisl. Pellentesque risus lacus, condimentum vitae luctus quis, eleifend tempor libero. Donec tempor quam vitae odio aliquam, a tincidunt sapien tristique. Ut laoreet fermentum ipsum vitae sollicitudin. Pellentesque sit amet lacus at turpis accumsan condimentum sit amet id libero. Nam vehicula sem tellus, ut ullamcorper sapien tincidunt non.
252
+
253
+ Nam laoreet bibendum velit sed consequat. In hac habitasse platea dictumst. Sed placerat maximus dolor et suscipit. Fusce condimentum nisl non orci facilisis finibus. Nullam a semper leo. Pellentesque ligula arcu, condimentum in gravida eget, eleifend ut felis. Nam mollis leo in turpis viverra, iaculis pretium odio tempor. Vivamus accumsan purus hendrerit ex ultrices iaculis dictum sed lorem. Quisque ultricies pretium hendrerit. Proin finibus consectetur orci, at fermentum ex lobortis suscipit. Sed scelerisque, sapien vitae auctor dapibus, purus dui iaculis sapien, ut volutpat magna nunc a lectus. Etiam vel sollicitudin neque. Fusce consectetur mi sed orci auctor, non lacinia risus gravida. Sed sit amet euismod risus. Curabitur condimentum massa felis, ut dignissim mi lobortis eget.
254
+
255
+ Nam ut laoreet lacus, at maximus metus. Quisque vestibulum varius turpis, et mollis dui varius accumsan. Donec consectetur condimentum placerat. Donec eu lectus sollicitudin, porttitor felis in, ultrices dolor. Maecenas nec risus a nibh varius aliquet eget non mi. Sed sit amet pellentesque mi. Etiam vitae erat ac turpis eleifend tristique. Mauris ac justo nisi. Cras faucibus, metus ut rhoncus bibendum, elit diam gravida mauris, vel volutpat sem orci ac orci. Aenean imperdiet purus et hendrerit facilisis.
256
+
257
+ Aliquam pellentesque, mi eget scelerisque lacinia, tortor diam lacinia augue, sed dignissim purus metus lobortis mauris. Quisque ante lacus, tempor eget tristique sit amet, lacinia vel ex. Aliquam vel quam et mi lacinia malesuada in id ligula. In at ipsum elementum, imperdiet ligula vel, volutpat dui. Nulla facilisi. Nam efficitur malesuada bibendum. Mauris sem turpis, ultricies sed est et, sodales mattis nisi. Quisque semper turpis ac mollis tempus. Aliquam vel molestie erat. Curabitur consectetur turpis ex, sit amet suscipit nulla ullamcorper at. Morbi congue gravida fermentum. Curabitur mattis dui eu interdum facilisis. Praesent vitae enim lectus. Aliquam diam risus, porttitor sed lobortis id, gravida nec velit. Proin laoreet elementum sagittis.
258
+
259
+ Pellentesque sit amet dui nec ante dignissim lobortis. In hac habitasse platea dictumst. Proin ullamcorper erat lorem, in fringilla ipsum sagittis sed. Sed ultrices ac ligula ac sagittis. Curabitur commodo ligula eget quam eleifend gravida et vel arcu. Praesent dapibus leo sit amet tincidunt volutpat. Sed euismod odio sed sem pulvinar pretium. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vestibulum posuere odio diam, in vulputate turpis blandit vitae. Donec in bibendum odio, vel placerat mi. Donec lacinia condimentum semper.
260
+
261
+ In feugiat euismod tellus, non pharetra dui dapibus sodales. Nulla tincidunt urna in metus suscipit pellentesque. Curabitur et nulla et quam dapibus lobortis sed a sem. Praesent at nunc ac purus scelerisque fringilla a at quam. Donec quis augue molestie, elementum enim eget, tempus tellus. Quisque venenatis at odio eget semper. Phasellus nec commodo leo. Sed interdum dignissim justo, et fermentum lacus vestibulum vel. Morbi scelerisque egestas sapien ut sollicitudin. Etiam vulputate nisl erat, id placerat lectus dictum sit amet. Pellentesque sollicitudin nisi sed justo tincidunt, at ullamcorper mauris hendrerit. Curabitur posuere bibendum arcu, eget ultrices magna elementum eu. Aliquam et lectus arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae;
262
+
263
+ Praesent auctor imperdiet purus id pretium. Etiam malesuada maximus dictum. Pellentesque ullamcorper enim non dolor viverra faucibus. Praesent enim urna, malesuada vitae vulputate in, efficitur vitae ante. Vivamus condimentum hendrerit sem, quis imperdiet libero hendrerit et. Integer non sodales leo. Sed nec mi id justo mattis ultricies sit amet ut velit. Quisque velit odio, suscipit vitae lectus ac, tincidunt scelerisque turpis. Etiam vitae tortor nisi. Nulla vulputate eu sem sed faucibus. Aliquam quis ligula ac diam egestas pulvinar. Ut euismod erat sapien, nec eleifend metus ullamcorper nec. Phasellus lorem est, tristique non tellus id, efficitur laoreet lacus. Aliquam ac semper quam.
264
+
265
+ In tincidunt ac dui varius placerat. Nullam porttitor vitae lorem sit amet efficitur. Donec placerat id felis sit amet egestas. Aliquam erat volutpat. Pellentesque elit dolor, posuere sit amet est finibus, posuere porta nibh. Aenean faucibus hendrerit tortor, et scelerisque dui finibus sed. Nullam vel suscipit nunc, vel molestie ex. Suspendisse varius ultricies nulla at dignissim. Suspendisse potenti. Praesent nec enim in lorem posuere sodales at nec metus.
266
+
267
+ Pellentesque dolor odio, tincidunt et rhoncus non, volutpat quis massa. Nunc iaculis elit arcu, non porta odio varius at. Vestibulum eu arcu in ante semper suscipit sit amet vitae velit. Praesent ac congue nulla. Sed euismod nisi id placerat vestibulum. Nam ultrices ipsum quis lectus tempor, eget sollicitudin lectus facilisis. Maecenas eleifend est in nisl fermentum, viverra imperdiet nisl lobortis. Praesent mauris nulla, bibendum nec varius at, posuere sit amet urna. Integer sit amet lectus augue. Morbi imperdiet sit amet ex vitae vulputate. Sed in libero mattis, tincidunt orci vestibulum, mattis urna. Mauris vehicula felis tortor, quis fermentum urna imperdiet quis. Ut in libero in nunc tempus pellentesque eu elementum nisi. Aliquam fermentum mi quis urna blandit finibus.
268
+
269
+ Fusce vitae ligula feugiat, aliquet turpis et, molestie eros. Praesent at augue risus. Donec tempus nisl lorem, at efficitur tellus faucibus id. Phasellus ultrices lectus vel velit luctus placerat. Duis ac imperdiet urna, a facilisis nisl. Nam lacinia dapibus vulputate. Duis viverra ac ligula et porttitor. Nunc sit amet lectus vel est efficitur luctus non in enim. Cras sed felis nec dolor suscipit luctus. Nullam sodales eu eros non sodales. In ut urna sit amet dolor rhoncus pretium et vel eros. Ut sit amet neque velit. Pellentesque a vestibulum sem. Sed ultricies nec elit ac cursus.
270
+
271
+ Quisque sed est malesuada, vehicula odio eu, dapibus odio. Suspendisse eget enim bibendum, egestas lectus tempor, egestas nunc. Nulla at condimentum odio, vel congue nisi. Sed pharetra dolor sit amet sodales euismod. In vestibulum augue a est egestas, sed fringilla erat aliquet. Nunc laoreet vitae lectus ut vestibulum. Vivamus placerat purus nec rhoncus bibendum. Vivamus nisl metus, hendrerit nec mollis posuere, sollicitudin eu odio. Donec id feugiat ex, congue blandit lorem. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vestibulum interdum sit amet augue sit amet accumsan.
272
+
273
+ Sed condimentum posuere odio at elementum. Proin at sem laoreet, congue turpis nec, facilisis ex. Integer pharetra sem ut nisl maximus, a ultrices metus gravida. Quisque lobortis leo ac ipsum gravida porta. Nam a urna sed lorem ullamcorper consequat id eu augue. Nullam mauris odio, fringilla sit amet venenatis nec, tincidunt quis nisl. Morbi mollis hendrerit purus at dictum. In facilisis sagittis nulla, nec posuere dolor varius at. Aenean metus nisi, sagittis vel sodales quis, maximus a ante. Integer sagittis aliquet lectus sit amet posuere. Nullam ullamcorper ante vel lorem dignissim, sit amet egestas tortor rutrum. Maecenas in elementum urna. Vestibulum dapibus, nulla in molestie sodales, dolor quam pharetra massa, vel lacinia diam ex in dui. Suspendisse potenti. Suspendisse potenti. Ut condimentum interdum augue, et lobortis odio varius ac.
274
+
275
+ Suspendisse nibh est, pharetra congue ornare sed, laoreet eget dui. Ut eget faucibus mi. Integer sed blandit diam, vitae laoreet lectus. Quisque ullamcorper rhoncus sagittis. Nam sed risus ex. Nunc dictum et nibh non suscipit. Quisque luctus feugiat nulla et egestas. Sed finibus mollis lectus, tempus tincidunt dolor dignissim eu. Sed eu urna tempor, fringilla nisl at, semper est. Nulla facilisi. Praesent auctor odio velit, in pulvinar elit bibendum ut. Sed pretium consectetur lorem, sed euismod enim mollis vel. Proin id aliquet massa, ut consequat nibh. In hac habitasse platea dictumst. Nunc et urna lorem.
276
+
277
+ Sed vitae consectetur metus, non hendrerit dolor. Praesent bibendum non ligula quis pretium. Fusce sem neque, hendrerit ut orci at, tempor varius odio. In lacinia luctus lorem et tincidunt. Sed pretium tempus ex, sit amet dictum velit fringilla non. Curabitur nec massa at dui vestibulum tincidunt. Nam quis pharetra lectus. Nunc scelerisque quam ut dolor facilisis, et finibus magna rutrum.
278
+
279
+ Vestibulum nisl orci, tincidunt in diam quis, tristique tristique nibh. Pellentesque faucibus sed nunc interdum cursus. Ut in risus vestibulum, suscipit risus id, congue massa. Donec mattis posuere magna et vehicula. Vivamus rhoncus pellentesque mauris quis finibus. Etiam at tellus ex. Integer sagittis vehicula sollicitudin. Nullam dapibus porta placerat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur at suscipit enim. Sed tempus, felis eu consequat scelerisque, ligula lectus mattis nibh, sed interdum nisi turpis ac sapien. Mauris lobortis tellus at enim porttitor, et tempor turpis mattis.
280
+
281
+ Mauris nec mi laoreet, molestie lectus vel, congue nisl. Morbi quis maximus neque. Nunc interdum, enim in vulputate rutrum, lacus ex aliquam erat, sit amet semper nulla mauris sed odio. Morbi dignissim sollicitudin tellus vel tristique. Nam aliquam consectetur sem, eget malesuada ipsum mollis eget. Donec at risus quam. Cras eget dapibus turpis, quis consectetur erat. In porttitor lectus a justo placerat commodo. Nam at mauris quis nulla viverra laoreet. Fusce pellentesque libero ante, eget luctus sem blandit nec. Nullam rutrum gravida dui, in dictum sem condimentum a. Nam vestibulum dolor quis massa facilisis volutpat. Aliquam egestas metus leo. Nunc eleifend ante quis turpis pellentesque suscipit. Morbi sollicitudin varius vestibulum.
282
+
283
+ Aliquam laoreet interdum ornare. Vivamus in diam dapibus, lacinia magna at, faucibus nisi. Fusce facilisis neque sed augue euismod, sit amet efficitur purus ultrices. Duis fermentum ipsum magna, in convallis urna porttitor sed. Aenean scelerisque lorem at orci eleifend ullamcorper. Etiam in mollis eros. Morbi fermentum venenatis leo vitae cursus. Suspendisse nisl libero, tempus nec bibendum eu, iaculis sed sem. Nunc iaculis erat non sapien tristique, at iaculis est sodales. Curabitur gravida arcu pretium, faucibus urna eget, rutrum ex. In ut magna in ligula rutrum feugiat ac volutpat orci. Nullam elit orci, faucibus in fermentum non, sollicitudin ac nulla.
284
+
285
+ Praesent sollicitudin magna arcu, a porttitor metus vulputate sit amet. Suspendisse vestibulum, mauris at hendrerit rutrum, tortor nisl consectetur tellus, sit amet blandit libero mi et libero. Donec non nulla scelerisque, consequat est at, bibendum nisi. Praesent eu eros id purus interdum congue. Pellentesque sit amet enim in elit auctor lacinia id at ipsum. Proin vel lacus et lorem molestie iaculis eu ac orci. Nulla ac ex at ex condimentum volutpat in in erat.
286
+
287
+ Cras nisl neque, faucibus vulputate euismod non, hendrerit et ante. Morbi cursus eget nisl eu condimentum. Phasellus consectetur tortor ut tempor feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas sollicitudin, orci quis aliquam imperdiet, nulla lectus faucibus felis, a congue sem nunc sit amet lectus. Suspendisse mollis ut lectus eget dapibus. Proin vitae mattis elit. Quisque mollis malesuada mauris, ac dapibus orci fringilla ac. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut varius in felis nec tempus. Nullam scelerisque ex at faucibus semper. Duis ultrices egestas risus, non imperdiet lacus congue in.
288
+
289
+ Mauris hendrerit, augue non scelerisque volutpat, metus nunc consectetur turpis, convallis pellentesque nisi quam sit amet felis. Fusce pharetra eu lacus non bibendum. Donec dictum, est ac aliquam accumsan, mauris lacus elementum nibh, et ullamcorper justo nulla at purus. Etiam tristique neque nisl, at sollicitudin nibh venenatis varius. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc turpis metus, tincidunt sed lectus in, pretium convallis tellus. Donec dapibus elit id odio interdum, sit amet ultrices lectus dapibus. Suspendisse lobortis sapien est, vitae mattis odio varius eget. Phasellus vestibulum dignissim justo at sollicitudin. Proin gravida odio ac neque faucibus congue a non felis. Nam semper neque quam.
290
+
291
+ Cras dapibus ante id interdum tincidunt. Quisque varius pharetra quam consequat hendrerit. Quisque id tristique magna. Vivamus ex justo, aliquam nec finibus a, semper non tortor. Etiam interdum diam eget augue dapibus, at sodales felis sodales. Phasellus mauris nisl, condimentum nec vulputate quis, consequat ut tortor. Sed et urna nulla. Nulla mollis, ante in molestie tincidunt, erat nibh accumsan mauris, lacinia sagittis tellus augue ac lacus.
292
+
293
+ Fusce blandit accumsan lorem, in faucibus ante pellentesque non. Cras laoreet massa et iaculis vehicula. Duis posuere augue nunc, in malesuada dui dapibus vitae. Nunc sagittis quis felis sit amet sodales. In lectus augue, hendrerit eget quam a, rutrum tincidunt turpis. Donec euismod ex in enim tempor viverra. Sed id accumsan risus.
294
+
295
+ Donec at rutrum felis, et aliquam neque. Nullam vulputate sed odio sit amet congue. In hac habitasse platea dictumst. Proin luctus posuere est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras feugiat consectetur condimentum. Phasellus quis rhoncus sapien. Ut gravida tellus libero, nec finibus justo dictum non. Sed placerat auctor purus, pulvinar congue elit feugiat vitae. Suspendisse sit amet facilisis enim. Vestibulum arcu velit, elementum aliquet eleifend vel, pharetra eget nisl. Nunc eget purus accumsan, feugiat ante ac, fringilla erat. In scelerisque orci id congue scelerisque. Duis nec augue porta, malesuada dolor eu, commodo tellus. Aenean sit amet tortor tempus, hendrerit ligula semper, gravida arcu.
296
+
297
+ Quisque tellus massa, convallis a viverra at, malesuada eget tortor. Donec in porta est, vitae malesuada est. Nulla massa nulla, fermentum quis ipsum et, tempor tempus elit. Phasellus vel condimentum felis. Sed efficitur lacinia diam a scelerisque. Nunc sagittis tellus ligula, a imperdiet nulla molestie vel. Sed ut feugiat est.
298
+
299
+ Morbi a ante odio. Vivamus sit amet porttitor massa. Vestibulum gravida feugiat semper. In eu augue eget purus rutrum aliquam. Donec orci quam, mollis vitae accumsan nec, placerat ullamcorper mi. Nam nisl mi, congue id lectus vel, iaculis pulvinar nisi. Mauris bibendum massa placerat nisi convallis, nec congue odio pretium. Quisque quis dui in risus finibus varius. Donec ac feugiat odio. Sed tempor vehicula elementum. Fusce sit amet magna in enim fermentum scelerisque. Curabitur dignissim ante ut diam convallis, consectetur volutpat ligula imperdiet. Proin tortor ex, placerat id magna eu, eleifend faucibus ipsum. Vestibulum fringilla convallis erat eu venenatis.
@@ -0,0 +1,47 @@
1
+ require "pbt"
2
+ require "benchmark/ips"
3
+
4
+ # With this seed, the 4th case fails and it shrinks happens 13 times.
5
+ seed = 17243810592888013452170775373100387856
6
+
7
+ Benchmark.ips do |x|
8
+ x.report("ractor") do
9
+ Pbt.assert(worker: :ractor, seed:) do
10
+ Pbt.property(Pbt.integer) do |x|
11
+ raise if x > 100
12
+ end
13
+ end
14
+ rescue Pbt::PropertyFailure
15
+ # noop
16
+ end
17
+
18
+ x.report("process") do
19
+ Pbt.assert(worker: :process, seed:) do
20
+ Pbt.property(Pbt.integer) do |x|
21
+ raise if x > 100
22
+ end
23
+ end
24
+ rescue Pbt::PropertyFailure
25
+ # noop
26
+ end
27
+
28
+ x.report("thread") do
29
+ Pbt.assert(worker: :thread, seed:) do
30
+ Pbt.property(Pbt.integer) do |x|
31
+ raise if x > 100
32
+ end
33
+ end
34
+ rescue Pbt::PropertyFailure
35
+ # noop
36
+ end
37
+
38
+ x.report("none") do
39
+ Pbt.assert(worker: :none, seed:) do
40
+ Pbt.property(Pbt.integer) do |x|
41
+ raise if x > 100
42
+ end
43
+ end
44
+ rescue Pbt::PropertyFailure
45
+ # noop
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ require "pbt"
2
+ require "benchmark/ips"
3
+
4
+ # tarai function with
5
+ # (x=10, y=5, z=0) calls 343073 times.
6
+ # (x=10, y=4, z=0) calls 271097 times.
7
+ # (x=9, y=5, z=0) calls 71973 times.
8
+ # (x=9, y=4, z=0) calls 55229 times.
9
+ # (x=8, y=4, z=0) calls 12605 times.
10
+ # (x=8, y=3, z=0) calls 305 times.
11
+ def tarai(x, y, z)
12
+ (x <= y) ? y : tarai(tarai(x - 1, y, z),
13
+ tarai(y - 1, z, x),
14
+ tarai(z - 1, x, y))
15
+ end
16
+
17
+ a, b, c = [9, 4, 0]
18
+
19
+ puts "Call tarai function with(#{a}, #{b}, #{c})"
20
+ puts
21
+
22
+ Benchmark.ips do |x|
23
+ x.report("ractor") do
24
+ Pbt.assert(worker: :ractor) do
25
+ Pbt.property(Pbt.constant(a), Pbt.constant(b), Pbt.constant(c)) do |x, y, z|
26
+ tarai(x, y, z)
27
+ end
28
+ end
29
+ end
30
+
31
+ x.report("process") do
32
+ Pbt.assert(worker: :process) do
33
+ Pbt.property(Pbt.constant(a), Pbt.constant(b), Pbt.constant(c)) do |x, y, z|
34
+ tarai(x, y, z)
35
+ end
36
+ end
37
+ end
38
+
39
+ x.report("thread") do
40
+ Pbt.assert(worker: :thread) do
41
+ Pbt.property(Pbt.constant(a), Pbt.constant(b), Pbt.constant(c)) do |x, y, z|
42
+ tarai(x, y, z)
43
+ end
44
+ end
45
+ end
46
+
47
+ x.report("none") do
48
+ Pbt.assert(worker: :none) do
49
+ Pbt.property(Pbt.constant(a), Pbt.constant(b), Pbt.constant(c)) do |x, y, z|
50
+ tarai(x, y, z)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,44 @@
1
+ require "pbt"
2
+ require "benchmark/ips"
3
+
4
+ # Read file generated by https://www.lipsum.com/
5
+ # 150 paragraphs, 13689 words, 92206 bytes.
6
+ def read_file(str)
7
+ File.read(File.join(__dir__, "example.txt")) + str
8
+ end
9
+
10
+ seed = 17243810592888013452170775373100387856
11
+
12
+ Benchmark.ips do |x|
13
+ x.report("ractor") do
14
+ Pbt.assert(worker: :ractor, seed:) do
15
+ Pbt.property(Pbt.ascii_string) do |str|
16
+ read_file(str)
17
+ end
18
+ end
19
+ end
20
+
21
+ x.report("process") do
22
+ Pbt.assert(worker: :process, seed:) do
23
+ Pbt.property(Pbt.ascii_string) do |str|
24
+ read_file(str)
25
+ end
26
+ end
27
+ end
28
+
29
+ x.report("thread") do
30
+ Pbt.assert(worker: :thread, seed:) do
31
+ Pbt.property(Pbt.ascii_string) do |str|
32
+ read_file(str)
33
+ end
34
+ end
35
+ end
36
+
37
+ x.report("none") do
38
+ Pbt.assert(worker: :none, seed:) do
39
+ Pbt.property(Pbt.ascii_string) do |str|
40
+ read_file(str)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,38 @@
1
+ require "pbt"
2
+ require "benchmark/ips"
3
+
4
+ seed = 17243810592888013452170775373100387856
5
+
6
+ Benchmark.ips do |x|
7
+ x.report("ractor") do
8
+ Pbt.assert(worker: :ractor, seed:) do
9
+ Pbt.property(Pbt.integer) do |x|
10
+ x + 1
11
+ end
12
+ end
13
+ end
14
+
15
+ x.report("process") do
16
+ Pbt.assert(worker: :process, seed:) do
17
+ Pbt.property(Pbt.integer) do |x|
18
+ x + 1
19
+ end
20
+ end
21
+ end
22
+
23
+ x.report("thread") do
24
+ Pbt.assert(worker: :thread, seed:) do
25
+ Pbt.property(Pbt.integer) do |x|
26
+ x + 1
27
+ end
28
+ end
29
+ end
30
+
31
+ x.report("none") do
32
+ Pbt.assert(worker: :none, seed:) do
33
+ Pbt.property(Pbt.integer) do |x|
34
+ x + 1
35
+ end
36
+ end
37
+ end
38
+ end
@@ -12,13 +12,13 @@ module Pbt
12
12
  keyword_init: true
13
13
  ) do
14
14
  # @param verbose [Boolean] Whether to print verbose output. Default is `false`.
15
- # @param worker [Symbol] The concurrency method to use. :ractor`, `:thread`, `:process` and `:none` are supported. Default is `:ractor`.
15
+ # @param worker [Symbol] The concurrency method to use. :ractor`, `:thread`, `:process` and `:none` are supported. Default is `:none`.
16
16
  # @param num_runs [Integer] The number of runs to perform. Default is `100`.
17
17
  # @param seed [Integer] The seed to use for random number generation. It's useful to reproduce failed test with the seed you'd pick up from failure messages. Default is a random seed.
18
18
  # @param thread_report_on_exception [Boolean] Whether to report exceptions in threads. It's useful to suppress error logs on Ractor that reports many errors. Default is `false`.
19
19
  def initialize(
20
20
  verbose: false,
21
- worker: :ractor,
21
+ worker: :none,
22
22
  num_runs: 100,
23
23
  seed: Random.new.seed,
24
24
  thread_report_on_exception: false
@@ -51,7 +51,7 @@ module Pbt
51
51
  @next_values = @property.shrink(c.val)
52
52
  else
53
53
  # successful run
54
- @run_execution.record_success
54
+ @run_execution.record_success(c)
55
55
  end
56
56
  end
57
57
  end
@@ -75,19 +75,36 @@ module Pbt
75
75
  runner = Check::RunnerIterator.new(source_values, property, config[:verbose])
76
76
  while runner.has_next?
77
77
  case config[:worker]
78
+ in :none
79
+ run_it_in_sequential(property, runner)
78
80
  in :ractor
79
81
  run_it_in_ractors(property, runner)
80
82
  in :process
81
83
  run_it_in_processes(property, runner)
82
84
  in :thread
83
85
  run_it_in_threads(property, runner)
84
- in :none
85
- run_it_in_sequential(property, runner)
86
86
  end
87
87
  end
88
88
  runner.run_execution
89
89
  end
90
90
 
91
+ # @param property [Proc]
92
+ # @param runner [RunnerIterator]
93
+ # @return [void]
94
+ def run_it_in_sequential(property, runner)
95
+ runner.each_with_index do |val, index|
96
+ c = Case.new(val:, index:)
97
+ begin
98
+ property.run(val)
99
+ runner.handle_result(c)
100
+ rescue => e
101
+ c.exception = e
102
+ runner.handle_result(c)
103
+ break # Ignore the rest of the cases. Just pick up the first failure.
104
+ end
105
+ end
106
+ end
107
+
91
108
  # @param property [Proc]
92
109
  # @param runner [RunnerIterator]
93
110
  # @return [void]
@@ -146,23 +163,6 @@ module Pbt
146
163
  end
147
164
  end
148
165
 
149
- # @param property [Proc]
150
- # @param runner [RunnerIterator]
151
- # @return [void]
152
- def run_it_in_sequential(property, runner)
153
- runner.each_with_index do |val, index|
154
- c = Case.new(val:, index:)
155
- begin
156
- property.run(val)
157
- runner.handle_result(c)
158
- rescue => e
159
- c.exception = e
160
- runner.handle_result(c)
161
- break # Ignore the rest of the cases. Just pick up the first failure.
162
- end
163
- end
164
- end
165
-
166
166
  # Load Parallel gem. If it's not installed, raise an error.
167
167
  # @see https://github.com/grosser/parallel
168
168
  # @raise [InvalidConfiguration]
@@ -14,6 +14,7 @@ module Pbt
14
14
  :error_instance,
15
15
  :failures,
16
16
  :verbose,
17
+ :execution_summary,
17
18
  :run_configuration,
18
19
  keyword_init: true
19
20
  )
@@ -16,24 +16,85 @@ module Pbt
16
16
  def report_run_details
17
17
  if @run_details.failed
18
18
  message = []
19
-
20
- message << <<~EOS
21
- Property failed after #{@run_details.num_runs} test(s)
22
- { seed: #{@run_details.seed} }
23
- Counterexample: #{@run_details.counterexample}
24
- Shrunk #{@run_details.num_shrinks} time(s)
25
- Got #{@run_details.error_instance.class}: #{@run_details.error_message}
26
- EOS
27
-
28
- if @run_details.verbose
29
- message << " \n#{@run_details.error_instance.backtrace_locations.join("\n ")}"
30
- message << "\nEncountered failures were:"
31
- message << @run_details.failures.map { |f| "- #{f.val}" }
19
+ message << format_error_message
20
+ message << error_backtrace
21
+ message << if @run_details.verbose
22
+ verbose_details
23
+ else
24
+ hint
32
25
  end
33
26
 
34
27
  raise PropertyFailure, message.join("\n") if message.size > 0
35
28
  end
36
29
  end
30
+
31
+ private
32
+
33
+ # @return [String]
34
+ def format_error_message
35
+ <<~MSG.chomp
36
+ Property failed after #{@run_details.num_runs} test(s)
37
+ { seed: #{@run_details.seed} }
38
+ Counterexample: #{@run_details.counterexample}
39
+ Shrunk #{@run_details.num_shrinks} time(s)
40
+ Got #{@run_details.error_instance.class}: #{@run_details.error_message}
41
+ MSG
42
+ end
43
+
44
+ def error_backtrace
45
+ i = @run_details.verbose ? -1 : 10
46
+ " #{@run_details.error_instance.backtrace_locations[..i].join("\n ")}"
47
+ end
48
+
49
+ # @return [String]
50
+ def verbose_details
51
+ [
52
+ "\nEncountered failures were:",
53
+ @run_details.failures.map { |f| "- #{f.val}" },
54
+ format_execution_summary
55
+ ].join("\n")
56
+ end
57
+
58
+ # @return [String]
59
+ def format_execution_summary
60
+ summary_lines = []
61
+ remaining_trees_and_depth = []
62
+
63
+ @run_details.execution_summary.reverse_each do |tree|
64
+ remaining_trees_and_depth << {depth: 1, tree:}
65
+ end
66
+
67
+ until remaining_trees_and_depth.empty?
68
+ current_tree_and_depth = remaining_trees_and_depth.pop
69
+
70
+ # format current tree according to its depth and result
71
+ current_tree = current_tree_and_depth[:tree]
72
+ current_depth = current_tree_and_depth[:depth]
73
+ result_icon = case current_tree.result
74
+ in :success
75
+ "\x1b[32m\u221A\x1b[0m" # green "√"
76
+ in :failure
77
+ "\x1b[31m\u00D7\x1b[0m" # red "×"
78
+ end
79
+ left_padding = ". " * current_depth
80
+ summary_lines << "#{left_padding}#{result_icon} #{current_tree.value}"
81
+
82
+ # push its children to the queue
83
+ current_tree.children.reverse_each do |tree|
84
+ remaining_trees_and_depth << {depth: current_depth + 1, tree:}
85
+ end
86
+ end
87
+
88
+ "\nExecution summary:\n#{summary_lines.join("\n")}\n"
89
+ end
90
+
91
+ # @return [String]
92
+ def hint
93
+ [
94
+ "\nHint: Set `verbose: true` in order to check the list of all failing values encountered during the run.",
95
+ "Hint: Set `seed: #{@run_details.seed}` in order to reproduce the failed test case with the same values."
96
+ ].join("\n")
97
+ end
37
98
  end
38
99
  end
39
100
  end
@@ -6,6 +6,14 @@ module Pbt
6
6
  module Reporter
7
7
  # Represents the result of a single run of a property test.
8
8
  class RunExecution
9
+ # A tree node of the execution for verbose output.
10
+ ExecutionTreeNode = Struct.new(
11
+ :result,
12
+ :value,
13
+ :children,
14
+ keyword_init: true
15
+ )
16
+
9
17
  # @param verbose [Boolean] Whether to print verbose output.
10
18
  def initialize(verbose)
11
19
  @verbose = verbose
@@ -13,12 +21,18 @@ module Pbt
13
21
  @failure = nil
14
22
  @failures = []
15
23
  @num_successes = 0
24
+ @root_execution_trees = []
25
+ @current_level_execution_trees = @root_execution_trees
16
26
  end
17
27
 
18
28
  # Record a failure in the run.
19
29
  #
20
30
  # @param c [Pbt::Check::Case]
21
31
  def record_failure(c)
32
+ if @verbose
33
+ current_tree = append_execution_tree_node(:failure, c.val)
34
+ @current_level_execution_trees = current_tree.children
35
+ end
22
36
  @path_to_failure << c.index
23
37
  @failures << c
24
38
 
@@ -29,8 +43,12 @@ module Pbt
29
43
 
30
44
  # Record a successful run.
31
45
  #
46
+ # @param c [Pbt::Check::Case]
32
47
  # @return [void]
33
- def record_success
48
+ def record_success(c)
49
+ if @verbose
50
+ append_execution_tree_node(:success, c.val)
51
+ end
34
52
  @num_successes += 1
35
53
  end
36
54
 
@@ -58,6 +76,7 @@ module Pbt
58
76
  error_instance: nil,
59
77
  failures: @failures,
60
78
  verbose: @verbose,
79
+ execution_summary: @root_execution_trees,
61
80
  run_configuration: config
62
81
  )
63
82
  else
@@ -72,10 +91,22 @@ module Pbt
72
91
  error_instance: @failure,
73
92
  failures: @failures,
74
93
  verbose: @verbose,
94
+ execution_summary: @root_execution_trees,
75
95
  run_configuration: config
76
96
  )
77
97
  end
78
98
  end
99
+
100
+ private
101
+
102
+ # @param result [Symbol] The result of the current node.
103
+ # @param value [Object] The value to test.
104
+ # @return [Hash] The current execution tree.
105
+ def append_execution_tree_node(result, value)
106
+ current_tree = ExecutionTreeNode.new(result:, value:, children: [])
107
+ @current_level_execution_trees << current_tree
108
+ current_tree
109
+ end
79
110
  end
80
111
  end
81
112
  end
data/lib/pbt/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pbt
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pbt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ohbarye
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-13 00:00:00.000000000 Z
11
+ date: 2024-04-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -24,6 +24,12 @@ files:
24
24
  - LICENSE.txt
25
25
  - README.md
26
26
  - Rakefile
27
+ - benchmark/README.md
28
+ - benchmark/example.txt
29
+ - benchmark/failure_simple.rb
30
+ - benchmark/success_cpu_bound.rb
31
+ - benchmark/success_io_bound.rb
32
+ - benchmark/success_simple.rb
27
33
  - lib/pbt.rb
28
34
  - lib/pbt/arbitrary/arbitrary.rb
29
35
  - lib/pbt/arbitrary/arbitrary_methods.rb