textangular
Version:
A radically powerful Text-Editor/Wysiwyg editor for Angular.js
479 lines (455 loc) • 201 kB
JavaScript
var triggerKeyup;
describe('taBind', function () {
'use strict';
beforeEach(module('textAngular'));
beforeEach(inject(function($rootScope, $timeout){
triggerKeyup = function(element, options, skipTimeout){
var event;
if(angular.element === jQuery){
event = jQuery.Event('keyup');
angular.extend(event, options);
element.triggerHandler(event);
}else{
element.triggerHandler('keyup', options);
}
$rootScope.$digest();
if(!skipTimeout) $timeout.flush();
};
}));
afterEach(inject(function($document){
$document.find('body').html('');
}));
var $rootScope;
it('should require ngModel', inject(function ($compile, $rootScope) {
expect(function () {
$compile('<div ta-bind></div>')($rootScope);
$rootScope.$digest();
}).toThrow();
}));
it('should add ta-bind class', inject(function ($compile, $rootScope) {
var element = $compile('<div ta-bind ng-model="test"></div>')($rootScope);
$rootScope.$digest();
expect(element.hasClass('ta-bind')).toBe(true);
}));
describe('should function as an WYSIWYG div', function () {
var $rootScope, element;
beforeEach(inject(function (_$compile_, _$rootScope_) {
$rootScope = _$rootScope_;
$rootScope.html = '<p>Test Contents</p>';
element = _$compile_('<div ta-bind contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$rootScope.$digest();
}));
it('should display model contents', function () {
expect(element.html()).toBe('<p>Test Contents</p>');
});
it('should update model from keyup', function () {
element.html('<div>Test 2 Content</div>');
triggerKeyup(element, {});
$rootScope.$digest();
expect($rootScope.html).toBe('<div>Test 2 Content</div>');
});
it('should update model from update function', function () {
element.html('<div>Test 2 Content</div>');
$rootScope.updateTaBind();
$rootScope.$digest();
expect($rootScope.html).toBe('<div>Test 2 Content</div>');
});
it('should update display from model change', function () {
$rootScope.html = '<div>Test 2 Content</div>';
$rootScope.$digest();
expect(element.html()).toBe('<div>Test 2 Content</div>');
});
it('should update display from model change while focussed', inject(function ($timeout) {
element.triggerHandler('focus');
$rootScope.$digest();
$rootScope.html = '<div>Test 2 Content</div>';
$rootScope.$digest();
$timeout.flush();
expect(element.html()).toBe('<div>Test 2 Content</div>');
}));
it('should wrap content from model change', function () {
$rootScope.html = 'Test 2 Content';
$rootScope.$digest();
expect(element.html()).toBe('<p>Test 2 Content</p>');
});
it('should prevent links default event', function () {
$rootScope.html = '<div><a href="test">Test</a> 2 Content</div>';
$rootScope.$digest();
element.find('a').on('click', function(e){
expect(e.isDefaultPrevented());
});
jQuery(element.find('a')[0]).trigger('click');
});
it('should ensure cursor is correctly placed', inject(function($document, taSelection){
$document.find('body').append(element);
taSelection.getSelection = function(){
return {
start: {
element: element[0],
offset: 0
},
end: {
element: element[0],
offset: 0
},
container: element[0]
};
};
var selectedElement;
taSelection.setSelectionToElementStart = function(el){
selectedElement = el;
};
element.triggerHandler('mouseup');
$rootScope.$digest();
expect(selectedElement.innerHTML).toBe(element.children()[0].innerHTML);
}));
describe('should trim empty content', function(){
it('returns undefined when <p></p>', function(){
element.html('<p></p>');
$rootScope.updateTaBind();
$rootScope.$digest();
expect($rootScope.html).toBe('');
});
it('returns undefined when <p><br/></p>', function(){
element.html('<p><br/></p>');
$rootScope.updateTaBind();
$rootScope.$digest();
expect($rootScope.html).toBe('');
});
it('returns undefined when single whitespace', function(){
element.html('<p> </p>');
$rootScope.updateTaBind();
$rootScope.$digest();
expect($rootScope.html).toBe('');
});
it('returns undefined when single ', function(){
element.html('<p> </p>');
$rootScope.updateTaBind();
$rootScope.$digest();
expect($rootScope.html).toBe('');
});
it('returns undefined when multiple ', function(){
element.html('<p> </p>');
$rootScope.updateTaBind();
$rootScope.$digest();
expect($rootScope.html).toBe('');
});
it('returns undefined whith mixed and whitespace', function(){
element.html('<p> </p>');
$rootScope.updateTaBind();
$rootScope.$digest();
expect($rootScope.html).toBe('');
});
});
describe('should respect the ta-default-wrap value', function(){
describe('on focus', function(){
it('default to p element', inject(function($rootScope, $compile){
$rootScope.html = '';
element = $compile('<div ta-bind contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$rootScope.$digest();
element.triggerHandler('focus');
$rootScope.$digest();
expect(element.html()).toBe('<p><br></p>');
}));
it('set to other value', inject(function($rootScope, $compile){
$rootScope.html = '';
element = $compile('<div ta-bind ta-default-wrap="div" contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$rootScope.$digest();
element.triggerHandler('focus');
$rootScope.$digest();
expect(element.html()).toBe('<div><br></div>');
}));
it('set to blank should not wrap', inject(function($rootScope, $compile){
$rootScope.html = '';
element = $compile('<div ta-bind ta-default-wrap="" contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$rootScope.$digest();
element.triggerHandler('focus');
$rootScope.$digest();
expect(element.html()).toBe('');
}));
});
describe('on keyup', function(){
it('default to p element', inject(function($rootScope, $compile){
$rootScope.html = '';
element = $compile('<div ta-bind contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$rootScope.$digest();
triggerKeyup(element, {});
$rootScope.$digest();
expect(element.html()).toBe('<p><br></p>');
}));
it('set to other value', inject(function($rootScope, $compile){
$rootScope.html = '';
element = $compile('<div ta-bind ta-default-wrap="div" contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$rootScope.$digest();
triggerKeyup(element, {});
$rootScope.$digest();
expect(element.html()).toBe('<div><br></div>');
}));
it('set to blank should not wrap', inject(function($rootScope, $compile){
$rootScope.html = '';
element = $compile('<div ta-bind ta-default-wrap="" contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$rootScope.$digest();
triggerKeyup(element, {});
$rootScope.$digest();
expect(element.html()).toBe('');
}));
});
describe('on ignoring keys press', function() {
it('should ignore blocked keys events', inject(function($rootScope, $compile, $window, $document, taSelection) {
var BLOCKED_KEYS = [19,20,27,33,34,35,36,37,38,39,40,45,46,112,113,114,115,116,117,118,119,120,121,122,123,144,145],
eventSpy = spyOn(taSelection, 'setSelectionToElementStart').andCallThrough(),
event;
$rootScope.html = '<p><br></p>';
element = $compile('<div ta-bind ta-default-wrap="b" contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$document.find('body').append(element);
$rootScope.$digest();
var range = $window.rangy.createRangyRange();
range.selectNodeContents(element.children()[0]);
$window.rangy.getSelection().setSingleRange(range);
BLOCKED_KEYS.forEach(function(key) {
triggerKeyup(element, {keyCode: key}, true);
$rootScope.$digest();
expect(eventSpy).not.toHaveBeenCalled();
});
element.remove();
}));
});
describe('on enter press', function(){
it('replace inserted with default wrap', inject(function($rootScope, $compile, $window, $document){
$rootScope.html = '<p><br></p>';
element = $compile('<div ta-bind ta-default-wrap="b" contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$document.find('body').append(element);
$rootScope.$digest();
var range = $window.rangy.createRangyRange();
range.selectNodeContents(element.children()[0]);
$window.rangy.getSelection().setSingleRange(range);
triggerKeyup(element, {keyCode: 13});
$rootScope.$digest();
expect(element.html()).toBe('<b><br></b>');
element.remove();
}));
it('NOT replace inserted with default wrap when shift', inject(function($rootScope, $compile, $window, $document){
$rootScope.html = '<p><br></p>';
element = $compile('<div ta-bind ta-default-wrap="b" contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$document.find('body').append(element);
$rootScope.$digest();
var range = $window.rangy.createRangyRange();
range.selectNodeContents(element.children()[0]);
$window.rangy.getSelection().setSingleRange(range);
triggerKeyup(element, {keyCode: 13, shiftKey: true});
$rootScope.$digest();
expect(element.html()).toBe('<p><br></p>');
element.remove();
}));
it('NOT replace inserted with default wrap when a li', inject(function($rootScope, $compile, $window, $document){
$rootScope.html = '<li><br></li>';
element = $compile('<div ta-bind ta-default-wrap="b" contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$document.find('body').append(element);
$rootScope.$digest();
var range = $window.rangy.createRangyRange();
range.selectNodeContents(element.children()[0]);
$window.rangy.getSelection().setSingleRange(range);
triggerKeyup(element, {keyCode: 13});
$rootScope.$digest();
expect(element.html()).toBe('<li><br></li>');
element.remove();
}));
it('NOT replace inserted with default wrap when nested in a li', inject(function($rootScope, $compile, $window, $document){
$rootScope.html = '<li><i><br></i></li>';
element = $compile('<div ta-bind ta-default-wrap="b" contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$document.find('body').append(element);
$rootScope.$digest();
var range = $window.rangy.createRangyRange();
range.selectNodeContents(element.children()[0].childNodes[0]);
$window.rangy.getSelection().setSingleRange(range);
triggerKeyup(element, {keyCode: 13});
$rootScope.$digest();
expect(element.html()).toBe('<li><i><br></i></li>');
element.remove();
}));
it('should replace inserted with default wrap when empty', inject(function($rootScope, $compile, $window, $document){
$rootScope.html = '<p><br></p>';
element = $compile('<div ta-bind ta-default-wrap="b" contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$document.find('body').append(element);
$rootScope.$digest();
element[0].innerHTML = '';
triggerKeyup(element, {});
$rootScope.$digest();
expect(element.html()).toBe('<b><br></b>');
element.remove();
}));
it('should escape blockquote when only empty element', inject(function($rootScope, $compile, $window, $document){
$rootScope.html = '<blockquote><p><br></p></blockquote>';
element = $compile('<div ta-bind contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$document.find('body').append(element);
$rootScope.$digest();
var range = $window.rangy.createRangyRange();
range.selectNodeContents(element.find('p')[0]);
$window.rangy.getSelection().setSingleRange(range);
var event;
if(angular.element === jQuery){
event = jQuery.Event('keydown');
event.keyCode = 13;
element.triggerHandler(event);
}else{
event = {keyCode: 13};
element.triggerHandler('keydown', event);
}
$rootScope.$digest();
expect(element.html()).toBe('<p><br></p>');
element.remove();
}));
});
});
});
describe('should function as an textarea', function () {
var $rootScope, element;
beforeEach(inject(function (_$compile_, _$rootScope_) {
$rootScope = _$rootScope_;
$rootScope.html = '<p>Test Contents</p>';
element = _$compile_('<textarea ta-bind ng-model="html"></textarea>')($rootScope);
$rootScope.$digest();
}));
it('should display model contents', function () {
expect(element.val()).toBe('<p>Test Contents</p>');
});
it('should update model from change', function () {
element.val('<div>Test 2 Content</div>');
element.triggerHandler('blur');
$rootScope.$digest();
expect($rootScope.html).toBe('<div>Test 2 Content</div>');
});
it('should update model from update function', function () {
element.val('<div>Test 2 Content</div>');
$rootScope.updateTaBind();
$rootScope.$digest();
expect($rootScope.html).toBe('<div>Test 2 Content</div>');
});
it('should update display from model change', function () {
$rootScope.html = '<div>Test 2 Content</div>';
$rootScope.$digest();
expect(element.val()).toBe('<div>Test 2 Content</div>');
});
});
describe('should function as an input', function () {
var $rootScope, element;
beforeEach(inject(function (_$compile_, _$rootScope_) {
$rootScope = _$rootScope_;
$rootScope.html = '<p>Test Contents</p>';
element = _$compile_('<input ta-bind ng-model="html"/>')($rootScope);
$rootScope.$digest();
}));
it('should display model contents', function () {
expect(element.val()).toBe('<p>Test Contents</p>');
});
it('should update model from change', function () {
element.val('<div>Test 2 Content</div>');
element.triggerHandler('blur');
$rootScope.$digest();
expect($rootScope.html).toBe('<div>Test 2 Content</div>');
});
it('should update model from update function', function () {
element.val('<div>Test 2 Content</div>');
$rootScope.updateTaBind();
$rootScope.$digest();
expect($rootScope.html).toBe('<div>Test 2 Content</div>');
});
it('should update display from model change', function () {
$rootScope.html = '<div>Test 2 Content</div>';
$rootScope.$digest();
expect(element.val()).toBe('<div>Test 2 Content</div>');
});
});
describe('should create the updateTaBind function on parent scope', function () {
describe('without id', function () {
it('should exist', inject(function (_$compile_, _$rootScope_) {
_$rootScope_.html = '<p>Test Contents</p>';
_$compile_('<textarea ta-bind ng-model="html"></textarea>')(_$rootScope_);
_$rootScope_.$digest();
expect(_$rootScope_.updateTaBind).toBeDefined();
}));
});
describe('with id', function () {
it('should exist', inject(function (_$compile_, _$rootScope_) {
_$rootScope_.html = '<p>Test Contents</p>';
_$compile_('<textarea id="Test" ta-bind ng-model="html"></textarea>')(_$rootScope_);
_$rootScope_.$digest();
expect(_$rootScope_.updateTaBindTest).toBeDefined();
}));
});
});
describe('custom renderers', function () {
describe('function in display mode', function () {
beforeEach(inject(function(taCustomRenderers){
taCustomRenderers.push({
// Parse back out: '<div class="ta-insert-video" ta-insert-video src="' + urlLink + '" allowfullscreen="true" width="300" frameborder="0" height="250"></div>'
// To correct video element. For now only support youtube
selector: 'a',
renderLogic: function(_element){
_element.replaceWith(angular.element('<b></b>'));
}
});
taCustomRenderers.push({
// Parse back out: '<div class="ta-insert-video" ta-insert-video src="' + urlLink + '" allowfullscreen="true" width="300" frameborder="0" height="250"></div>'
// To correct video element. For now only support youtube
customAttribute: 'href',
renderLogic: function(_element){
_element.replaceWith(angular.element('<i></i>'));
}
});
}));
afterEach(inject(function(taCustomRenderers){
taCustomRenderers.pop();
taCustomRenderers.pop();
}));
it('should replace with custom code for video renderer', inject(function ($compile, $rootScope) {
$rootScope.html = '<p><img class="ta-insert-video" ta-insert-video="http://www.youtube.com/embed/2maA1-mvicY" src="" allowfullscreen="true" width="300" frameborder="0" height="250"/></p>';
var element = $compile('<div ta-bind ng-model="html"></div>')($rootScope);
$rootScope.$digest();
expect(element.find('img').length).toBe(0);
expect(element.find('iframe').length).toBe(1);
}));
it('should not replace with custom code for normal img', inject(function ($compile, $rootScope) {
$rootScope.html = '<p><img src=""/></p>';
var element = $compile('<div ta-bind ng-model="html"></div>')($rootScope);
$rootScope.$digest();
expect(element.find('img').length).toBe(1);
expect(element.find('iframe').length).toBe(0);
}));
it('should replace for selector only', inject(function ($compile, $rootScope) {
$rootScope.html = '<p><a></a></p>';
var element = $compile('<div ta-bind ng-model="html"></div>')($rootScope);
$rootScope.$digest();
expect(element.find('a').length).toBe(0);
expect(element.find('b').length).toBe(1);
}));
it('should replace for attribute only', inject(function ($compile, $rootScope) {
$rootScope.html = '<p><span href></span><b href></b></p>';
var element = $compile('<div ta-bind ng-model="html"></div>')($rootScope);
$rootScope.$digest();
expect(element.find('span').length).toBe(0);
expect(element.find('b').length).toBe(0);
expect(element.find('i').length).toBe(2);
}));
});
describe('not function in edit mode', function () {
it('should exist', inject(function ($compile, $rootScope) {
$rootScope.html = '<p><img class="ta-insert-video" ta-insert-video="http://www.youtube.com/embed/2maA1-mvicY" src="" allowfullscreen="true" width="300" frameborder="0" height="250"/></p>';
var element = $compile('<div ta-bind contenteditable="true" ng-model="html"></div>')($rootScope);
$rootScope.$digest();
expect(element.find('img').length).toBe(1);
expect(element.find('iframe').length).toBe(0);
}));
});
});
/* Ignored due to being far too variable across platforms.
describe('performance tests', function(){
it('should be fast', inject(function ($compile, $rootScope) {
// Massive lorem ipsum...
var start = 0;
runs(function(){
$rootScope.html = '';
var element = $compile('<div ta-bind contenteditable="contenteditable" ng-model="html"></div>')($rootScope);
$rootScope.$digest();
start = new Date().getTime();
element.html('<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque faucibus ante ut finibus malesuada. Curabitur eu vehicula nibh. Quisque sit amet magna quis diam gravida consectetur. Sed at dui tristique, tempor ligula et, dapibus diam. Etiam a lorem sollicitudin, pellentesque ligula vel, ultrices turpis. Quisque commodo nunc purus, sed accumsan magna finibus ac. Fusce ut lacinia metus, tincidunt tristique magna. Phasellus quis elementum leo. Duis non velit ultricies, vehicula nisi sit amet, tempus magna. In sit amet fringilla lorem. Quisque sem sapien, facilisis quis lorem at, sollicitudin tempus nunc. Sed a fringilla urna, sed volutpat justo. Nunc et velit felis. Aliquam tincidunt a orci eget dapibus. Praesent rhoncus augue nec dolor vehicula tempor. Ut pulvinar sed lorem sit amet iaculis. Nunc blandit sagittis odio non mattis. Duis eget magna eu elit fringilla viverra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In euismod nulla ligula, quis dictum odio blandit non. Nunc suscipit consectetur pretium. Donec eleifend nulla pretium ipsum maximus, nec condimentum magna posuere. Suspendisse sollicitudin felis purus, eget iaculis ipsum tempor tincidunt. Vivamus iaculis at est nec laoreet. Vivamus iaculis vehicula molestie. Phasellus magna arcu, pellentesque molestie dignissim ac, congue ac lacus. In id lorem dolor. Etiam ultrices fermentum hendrerit. Etiam posuere lacus nibh, eu maximus magna vulputate eu. Curabitur non molestie sem. Proin dapibus gravida vehicula. Suspendisse porttitor, risus et imperdiet pulvinar, ante felis mollis ante, a sodales dui orci id quam. Proin quis lorem ante. Donec mollis metus nibh, ac feugiat nisi tempus placerat. Aenean quis est lorem. Suspendisse scelerisque metus vel orci maximus tempus. Vivamus nec turpis velit. Ut justo nunc, hendrerit sit amet nisl feugiat, sollicitudin congue metus. Fusce vestibulum laoreet imperdiet. Morbi augue nisi, viverra vitae scelerisque ut, tincidunt sit amet turpis. Proin lacus dui, pharetra blandit tincidunt ut, bibendum vel mauris. Morbi ultrices, felis in blandit tempus, odio leo semper mi, non sagittis lectus erat vel nibh. Donec malesuada massa eu elit rhoncus vulputate. Morbi quis lorem elit. Curabitur ac nisl in lorem malesuada finibus. Morbi molestie id quam consectetur facilisis. Donec congue quam eget leo interdum tristique eu vitae felis. Aliquam in sem ut lorem mollis maximus eu nec velit. Nam viverra eros vitae felis tempor, eget eleifend massa mattis. Proin volutpat luctus risus sit amet pellentesque. Donec efficitur vel enim sit amet rutrum. Sed ac ligula sed velit finibus commodo. Suspendisse potenti. Nam in aliquet ligula, sit amet imperdiet nisi. Cras sed rhoncus lorem. Nunc finibus viverra nulla et lobortis. Aenean sed sapien molestie, pellentesque massa sed, volutpat ipsum. Integer id interdum dolor. Aliquam eget tristique ex, in elementum mauris. Donec vitae lacinia lacus, sit amet ullamcorper ipsum. Curabitur et faucibus sem, eu bibendum felis. Cras lacinia ante sit amet dolor pulvinar feugiat. Integer venenatis magna et purus accumsan, in pellentesque felis vestibulum. Cras vulputate leo metus, ut tristique nunc faucibus a. Fusce euismod libero sed massa feugiat pellentesque. Sed a tincidunt eros. Integer ac nibh blandit, pellentesque lectus quis, pretium metus. Donec a tincidunt urna, non fringilla dolor. Nunc dictum auctor tortor eget facilisis. Nunc facilisis turpis sed enim lacinia, in tristique mi dapibus. Mauris suscipit velit sit amet augue iaculis, at congue felis semper. Mauris nec felis feugiat, scelerisque sapien non, egestas dolor. Curabitur pellentesque, nibh sit amet egestas tincidunt, erat nulla fermentum tortor, et dictum est diam at magna. Aliquam erat volutpat. Sed blandit varius enim, non dapibus diam. Aenean malesuada elit dui, vitae pellentesque turpis accumsan eget. Sed laoreet dui vel arcu blandit luctus. Vestibulum feugiat commodo sem in eleifend. Sed elementum ut nisi a hendrerit. Quisque at lobortis erat, a iaculis risus. Ut felis dolor, eleifend ut nisl at, convallis venenatis dolor. Nullam sit amet tempus sem. Phasellus id ipsum nulla. Aenean consequat consectetur bibendum. Maecenas laoreet lacus vel sagittis ultricies. Sed mollis egestas semper. Cras diam urna, vestibulum ut mattis sed, eleifend vel diam. Curabitur eget risus ut ligula pharetra eleifend eu eu augue. Nam ornare ex ac urna porttitor pulvinar. In faucibus euismod lacus eget sagittis. Sed ac velit mauris. Sed metus est, accumsan at lacus eget, interdum cursus est. Sed in lacinia orci. Donec vitae sapien tristique, placerat ipsum vel, interdum massa. Praesent enim est, rhoncus eget gravida vel, lacinia nec tellus. Vivamus nec dui non sem molestie molestie. Nam ac maximus lorem, a pharetra odio. Aliquam erat volutpat. In pretium consectetur eros, consectetur lacinia enim sollicitudin vel. Donec varius, odio nec fermentum elementum, nisi ex pretium nulla, eget accumsan risus velit ut enim. Sed sodales arcu diam, quis hendrerit sapien rhoncus quis. Donec malesuada ex sodales mauris faucibus bibendum. Nulla non eleifend ex. Mauris vitae blandit diam, sed aliquam lacus. Suspendisse quis erat in nulla imperdiet porttitor eget non nibh. Ut enim nunc, pharetra sit amet libero eget, ornare finibus velit. Nunc odio sapien, pretium imperdiet auctor at, semper eget libero. Suspendisse potenti. Sed tellus tortor, lobortis eget mi eget, consectetur sollicitudin justo. In hac habitasse platea dictumst. Suspendisse eget sem ut eros sagittis sagittis. Nullam a ex ornare, scelerisque dui sit amet, porta libero. Duis bibendum auctor neque ac efficitur. Curabitur vitae diam at lorem placerat cursus. Integer mollis vestibulum nisl sed cursus. Nam rhoncus mi vel aliquet tempus. Integer volutpat iaculis turpis, non egestas libero accumsan quis. Quisque consectetur libero eu pellentesque hendrerit. Nullam condimentum orci eu nunc varius, et egestas diam hendrerit. Aliquam consectetur rutrum neque, non porta elit maximus sit amet. Integer vel volutpat metus. Ut tincidunt vestibulum mollis. Duis est mauris, feugiat nec est eget, luctus faucibus dolor. In dui odio, commodo eget ipsum elementum, viverra pellentesque odio. In tristique scelerisque turpis, sed laoreet mi facilisis nec. Suspendisse luctus quam mauris, sed vulputate metus molestie eu. Maecenas sit amet dolor quam. Donec enim magna, scelerisque in ipsum sit amet, posuere mollis arcu. Sed aliquet tortor sit amet dapibus consectetur. Vivamus non imperdiet sapien. Nam auctor tincidunt lectus, non ultrices velit cursus nec. Ut vel aliquam leo. Mauris vulputate nulla sed massa rutrum imperdiet. Sed pellentesque mi ipsum. Morbi tincidunt id orci hendrerit aliquam. Aliquam tempor nibh in dignissim efficitur. Nullam ut lectus facilisis, ullamcorper nulla quis, faucibus ex. Donec eros nunc, facilisis non ipsum non, consectetur elementum nibh. Pellentesque eleifend venenatis turpis, non blandit ex interdum at. Nunc dictum placerat est, a sodales felis vestibulum non. Aenean in laoreet elit. Sed luctus sed ex eget viverra. Etiam porttitor, arcu condimentum sollicitudin faucibus, sem metus laoreet metus, non pellentesque augue odio quis purus. Mauris commodo libero vel erat ullamcorper viverra. Sed vitae pharetra augue. In laoreet nisi at varius dictum. Aliquam et lacus a diam dapibus tristique. Nunc luctus, nisi vitae pulvinar cursus, quam erat ullamcorper velit, ut feugiat tellus metus a neque. Etiam id quam vel elit pulvinar tincidunt. Vestibulum hendrerit, leo et egestas aliquet, diam tellus pellentesque sapien, id fringilla velit tellus vel dui. Proin tristique facilisis sem, non lacinia lectus interdum ac. Morbi vel dignissim eros. Curabitur at elit leo. Vivamus aliquet ex quam, non fringilla justo sollicitudin et. Quisque elit lacus, gravida sed viverra in, porta quis enim. Phasellus orci elit, iaculis vel finibus eu, rhoncus ac ante. Etiam non leo sit amet lacus sagittis eleifend. Nulla malesuada et massa quis ultricies. In id tellus neque. Etiam non erat sit amet erat consequat commodo. Pellentesque lobortis mauris ultrices massa placerat, id sollicitudin nisi pretium. Praesent a tortor ut nisi malesuada fringilla eget nec justo. Nullam varius, sem quis egestas pretium, purus magna posuere sem, et porta ipsum nibh quis lectus. Nulla pretium hendrerit nulla ut dapibus. Vivamus nec aliquam lorem. Vivamus molestie convallis turpis, id posuere est. Sed venenatis consectetur volutpat. Nunc imperdiet lectus vel risus tempor imperdiet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed magna velit, faucibus quis ultricies sit amet, molestie in magna. Nulla posuere molestie dolor ut pellentesque. Integer ullamcorper accumsan nibh. Morbi feugiat mollis turpis, vel fermentum mi iaculis ac. Nullam sed nisl venenatis, sodales nisi ut, efficitur odio. Morbi et finibus tellus, et accumsan tortor. Etiam eu elit in arcu laoreet molestie. Mauris ac malesuada ex, sed sagittis enim. Vivamus suscipit sit amet diam nec sodales. Curabitur et mi congue, malesuada est in, dapibus tortor. Duis porta, lectus et eleifend vulputate, ex magna condimentum odio, eu rhoncus libero magna vel justo. Fusce aliquet, leo ut faucibus efficitur, dolor nisl eleifend odio, blandit fermentum ante nisi at felis. Cras eu ante non augue malesuada scelerisque. Integer sodales nibh in ex tristique rhoncus. In hac habitasse platea dictumst. Morbi ullamcorper libero sed aliquet condimentum. Nulla sed purus vel nisl ornare placerat nec ut sapien. Donec scelerisque arcu ligula, sed sodales lacus vestibulum accumsan. Aenean in egestas urna. Fusce efficitur vel leo id convallis. In hac habitasse platea dictumst. Quisque at pulvinar ipsum. Pellentesque suscipit quis est eu imperdiet. Fusce lacinia at mi nec malesuada. In rutrum aliquam ullamcorper. Donec magna urna, laoreet eget arcu sed, imperdiet molestie diam. Donec hendrerit tristique mauris, et pellentesque ex euismod sed. Fusce eu ligula sagittis, pharetra felis id, vulputate eros. Vivamus pharetra nec leo nec volutpat. Curabitur eu fermentum velit. Suspendisse egestas aliquam ante eu congue. Proin eget euismod ipsum. Mauris nibh enim, sodales porttitor mi a, pellentesque tincidunt est. Fusce fermentum dignissim porta. Curabitur vel fermentum dolor. Aliquam bibendum luctus metus. Maecenas ut dolor lobortis odio rhoncus mattis vel sed purus. Sed viverra lacus non tempus porttitor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla lobortis rutrum placerat. Maecenas lectus risus, molestie vitae diam in, lacinia iaculis mauris. Pellentesque volutpat ligula nibh, in laoreet quam maximus sit amet. Curabitur non consequat est. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam lorem felis, mattis dictum iaculis a, suscipit eu lectus. Suspendisse potenti. Vivamus nunc quam, mattis a augue sodales, condimentum efficitur est. Donec sit amet nulla mi. Nam sit amet turpis laoreet, varius augue et, dapibus justo. Vestibulum ut nunc consequat, dictum diam vitae, facilisis nisl. Aliquam pellentesque tempor consequat. Etiam laoreet nisi at dapibus tincidunt. Phasellus in ante nibh. Fusce vel dui luctus, pretium sapien id, finibus tortor. Phasellus non vestibulum metus. Sed at convallis mauris, ut sollicitudin diam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur cursus, lectus in mollis eleifend, lacus ante luctus dolor, id euismod massa augue ac eros. Quisque luctus lobortis ex, ac auctor mi interdum nec. Maecenas non scelerisque sapien. Fusce eleifend ac tellus vitae venenatis. Nunc posuere hendrerit risus nec condimentum. Donec non auctor lorem. Vestibulum et vehicula purus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum imperdiet quis sem sed pellentesque. Nunc massa libero, maximus eu interdum in, ultricies id urna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi facilisis id leo et porttitor. Integer vel feugiat nulla. Vivamus malesuada tortor ac nulla finibus vulputate. Nam pretium felis at sem eleifend, dignissim lacinia enim rhoncus. Mauris ante diam, volutpat in fermentum id, volutpat ac risus. Suspendisse et ex nec ante eleifend rutrum eu eget augue. Fusce mollis diam ut nibh auctor sagittis. Donec sed nunc vitae neque bibendum suscipit. Nam placerat vel nisl quis luctus. Duis egestas neque in purus faucibus, eget porta dolor feugiat. Mauris vitae neque nec tellus dictum pulvinar sed a lacus. Fusce sollicitudin tellus ut tincidunt rutrum. Vestibulum suscipit erat a tortor tristique, et posuere nibh interdum. Suspendisse pharetra imperdiet volutpat. Vivamus tincidunt risus a pharetra viverra. Nunc non commodo diam, sit amet tincidunt quam. Duis hendrerit est nec viverra faucibus. Morbi auctor, nisl id pharetra placerat, turpis risus porta ipsum, sed lobortis diam eros vel purus. In vitae purus tincidunt, porttitor quam nec, fringilla eros. Etiam a imperdiet magna. Morbi dictum venenatis diam, sed sodales purus gravida vitae. Phasellus non libero non tellus bibendum elementum. Phasellus gravida lacinia orci eu venenatis. Vivamus nunc orci, pellentesque vitae tincidunt in, tincidunt vel massa. Integer maximus sem non velit ullamcorper semper. Praesent mollis ultrices est, in volutpat turpis euismod blandit. Ut sit amet diam quam. Morbi a egestas quam. Duis at nulla sit amet ante pharetra malesuada. Donec auctor in ex quis tempor. Curabitur eget leo volutpat, condimentum felis eget, ultricies magna. Mauris id dignissim enim. Suspendisse interdum tristique elit, vitae bibendum lectus imperdiet at. Morbi sodales accumsan erat quis tincidunt. Vivamus vulputate ex posuere varius ullamcorper. In vulputate dictum lectus. Sed commodo eu urna vitae fringilla. Sed gravida erat quis sodales auctor. Fusce at luctus ante, non posuere justo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla facilisi. Suspendisse viverra, lectus in vestibulum tincidunt, nisi ipsum convallis nibh, porttitor molestie mi ex a urna. Vivamus non luctus leo. Nullam commodo nisl eget nisl finibus laoreet. Vestibulum vestibulum sollicitudin lorem, id bibendum magna tristique in. Vestibulum sit amet tincidunt purus, ut dictum tortor. Maecenas congue venenatis accumsan. Praesent tincidunt commodo leo a fermentum. Donec vulputate gravida dictum. Nulla facilisi. Morbi quam nisl, mattis quis odio id, finibus malesuada massa. Nullam in tempus nulla. Duis tempor porta consectetur. Ut sed quam suscipit, lobortis leo ut, vestibulum dui. Donec sit amet lectus a urna vulputate lacinia. Phasellus orci turpis, blandit at imperdiet tempor, suscipit at turpis. Duis ut urna eu odio tristique porttitor vel nec dolor. Fusce sed ipsum dapibus, porta metus vel, luctus libero. Phasellus metus risus, consectetur id tempus eu, consectetur non tellus. Pellentesque felis est, pellentesque in fringilla id, ornare vel lectus. Vestibulum pulvinar, lorem in condimentum bibendum, orci lectus fermentum nulla, nec malesuada elit nisi et turpis. Ut consectetur, ex facilisis euismod euismod, est justo scelerisque sem, vitae placerat felis justo a dui. Sed ut felis id odio sodales pharetra sit amet et ligula. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer vitae consequat magna, sed laoreet massa. Vivamus lobortis ligula ac varius pulvinar. Curabitur a suscipit neque. Phasellus ac quam in sem fringilla facilisis. Morbi eu odio neque. Pellentesque vehicula dictum placerat. Vestibulum at quam non justo rhoncus mollis nec at nunc. Aliquam sollicitudin molestie mauris, in mattis metus lobortis at. Sed eget nisl sit amet risus mollis rutrum vitae ac quam. Nam nec sem neque. Donec sit amet erat quis sem varius lacinia. Morbi viverra ac sapien vel fermentum. Donec in lacus ut est semper ultricies nec pulvinar purus. Morbi at tincidunt tortor. Nullam quis pulvinar quam. Sed dui eros, egestas et mi ut, viverra bibendum lorem. Vivamus mollis, massa nec commodo hendrerit, ex est vulputate dui, vitae porttitor tellus nulla in libero. Vestibulum imperdiet dolor ligula. Nunc finibus felis at velit lobortis finibus. Phasellus ut ante sodales, malesuada nulla vel, rutrum purus. Aliquam in eleifend neque, vitae imperdiet leo. Sed vitae felis mi. Phasellus risus eros, scelerisque a facilisis et, rhoncus eget massa. Vivamus ultricies sagittis ex, ut volutpat dui pulvinar nec. Vivamus eget massa at tortor tincidunt vulputate sit amet eu felis. Aliquam erat volutpat. Morbi sed ex eget mi blandit facilisis. Cras aliquet nulla justo, ut tincidunt massa pretium eget. Integer dapibus, quam a semper suscipit, risus orci vulputate enim, ac pretium lectus nisl vel ante. Cras fringilla nunc id nunc accumsan finibus. Curabitur pretium velit elementum, volutpat eros sit amet, aliquet nunc. Aliquam erat volutpat. Curabitur ut risus facilisis lorem efficitur lobortis in vitae velit. Phasellus vel volutpat ipsum, in posuere ante. Praesent tincidunt tempor sem, vitae congue tortor varius non. Nam tincidunt arcu sit amet suscipit ultrices. Nullam a viverra lectus. Curabitur risus magna, convallis ac dolor sit amet, aliquam faucibus urna. Donec mattis finibus diam a aliquet. Donec eget aliquet nisl. Aenean eu est euismod, condimentum libero id, ullamcorper tortor. Donec leo orci, elementum nec turpis at, ornare venenatis nisi. Donec cursus justo nec eros sodales, vel eleifend augue finibus. Donec malesuada ultricies sem sed fringilla. In hac habitasse platea dictumst. Praesent tempus eleifend leo, eleifend molestie nulla tincidunt nec. Donec purus libero, elementum sed lorem nec, interdum feugiat nulla. Fusce sed hendrerit tortor. In hac habitasse platea dictumst. Quisque feugiat pretium luctus. Phasellus in mauris id nibh bibendum hendrerit. Proin sem justo, rhoncus sit amet mi eget, gravida faucibus arcu. Quisque sollicitudin eu lorem sit amet congue. Vestibulum in laoreet orci. Phasellus sit amet dignissim ante, quis scelerisque lorem. Sed non maximus mauris, sed gravida libero. Duis mi nulla, gravida vitae ex faucibus, hendrerit dignissim dui. In non tempor mauris, id euismod enim. Phasellus sed elementum magna. Pellentesque et aliquam nisl. Vestibulum sed erat sed ipsum rutrum congue. Nullam ullamcorper hendrerit leo, id condimentum nibh finibus non. Proin porttitor tellus a tellus dignissim, eu dapibus ante commodo. Sed eget arcu sodales, rhoncus mauris et, ultricies dui. Morbi eget libero nibh. Aenean ullamcorper imperdiet metus, ac feugiat velit. Mauris id mi tortor. Fusce dolor erat, ullamcorper at metus eget, rhoncus malesuada neque. Praesent pellentesque nulla cursus, ornare mauris vel, sagittis ipsum. Vestibulum feugiat porttitor lorem, in placerat nisl accumsan vel. Pellentesque in lobortis nulla, ac sodales neque. Morbi pellentesque magna a hendrerit aliquam. Pellentesque commodo dapibus mattis. Aliquam ut pulvinar dolor. Cras nec sem bibendum, elementum quam ut, euismod tortor. Ut ut efficitur ipsum, ut efficitur ante. Curabitur suscipit, purus at euismod consequat, sem erat semper dolor, vel eleifend ex neque vel neque. Ut bibendum accumsan enim quis molestie. Pellentesque a interdum nunc, quis condimentum dolor. Praesent at diam pellentesque justo fringilla aliquet. Cras quis justo facilisis, vestibulum lectus id, accumsan diam. Vestibulum et magna risus. Donec iaculis mauris et mauris efficitur rhoncus. Pellentesque pellentesque justo et semper rutrum. Praesent tellus metus, volutpat ut placerat vel, porttitor nec nulla. Morbi et quam vitae lorem eleifend iaculis quis eget metus. Nunc gravida lectus tincidunt nibh pellentesque, tincidunt accumsan magna pellentesque. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus eu purus ac risus luctus consequat quis at nulla. Integer quis orci dolor. Vivamus elementum velit quis volutpat ultricies. Mauris vulputate risus sed quam feugiat, id scelerisque ligula auctor. Vestibulum euismod justo quis eros consectetur faucibus. Sed tristique ac tortor vel viverra. Cras consequat faucibus sapien eu finibus. Nunc vitae lacus orci. Pellentesque condimentum interdum sodales. Aenean feugiat efficitur nulla, eget auctor neque ultrices non. Praesent dapibus ut ligula sit amet dapibus. Donec eu tellus pellentesque, sollicitudin ante quis, lacinia tellus. Pellentesque tincidunt gravida ipsum non porta. Nullam venenatis commodo turpis, ut interdum risus fringilla ac. Cras quis nulla eu enim tempus pulvinar. Quisque ultricies dictum diam, et porta eros sagittis ac. Etiam sed dolor eget purus tincidunt tempor ut a sapien. Phasellus efficitur facilisis ipsum ut fringilla. Vestibulum vulputate sapien et accumsan euismod. Aenean posuere egestas turpis vel consectetur. Integer magna turpis, luctus a mattis et, mattis eu libero. In molestie interdum egestas. Aliquam aliquam quis ex ornare porta. Mauris nisi dui, posuere nec sem et, efficitur sodales justo. Sed dictum arcu tellus, eget vulputate erat faucibus eget. Nunc lectus justo, sagittis in scelerisque vitae, pellentesque malesuada nisi. Duis viverra elementum eros, ac gravida ex luctus quis. Aliquam eu lorem nisl. Nullam sagittis neque vel ornare aliquet. Sed bibendum orci et sodales tristique. Phasellus cursus volutpat tellus sit amet ullamcorper. Nullam placerat lorem eget cursus commodo. Mauris nec urna nibh. Mauris dignissim vitae urna at gravida. Sed nulla nisi, pharetra sed consequat venenatis, vehicula vitae velit. Morbi rutrum lorem finibus ligula hendrerit auctor. Duis ac quam eget sem luctus vulputate non eu est. Sed vel facilisis diam. Donec in velit quis lacus efficitur porttitor ac nec metus. Ut lacinia vestibulum quam, et euismod dolor. Nulla est arcu, semper at nisl in, malesuada porta mauris. Vivamus commodo dolor non iaculis porta. Donec ac erat finibus leo varius sagittis at suscipit libero. Praesent interdum venenatis lacus, at aliquam tellus suscipit vitae. Ut lacus lacus, vestibulum et efficitur eget, malesuada id tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque tempor elementum fringilla. Morbi mollis euismod sapien et lobortis. Cras efficitur eros eros, eu facilisis ipsum aliquam quis. Mauris a ante sed tellus molestie molestie at ac elit. Mauris sit amet libero iaculis, dignissim nunc tincidunt, imperdiet ex. In vel arcu felis. Curabitur viverra felis eget tincidunt vulputate. Nullam tempus vitae erat eu fringilla. Vestibulum est magna, vulputate ac felis ac, maximus ullamcorper lorem. Sed fermentum a mauris eu blandit. Aliquam erat volutpat. Donec finibus sagittis iaculis. Curabitur sagittis libero vitae ultricies porttitor. Vivamus vitae pretium erat. In id massa vel felis bibendum euismod sit amet non diam. Proin viverra, mi a lobortis tristique, orci lacus lacinia dolor, quis mollis est nibh eget mi. Donec gravida nibh purus, sit amet dapibus nisi pulvinar a. Mauris a nunc et lectus pharetra imperdiet. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas vitae volutpat turpis. Fusce sed feugiat massa. Nam faucibus orci nisi, non aliquet lectus auctor id. Nullam non diam lacus. Vivamus mattis arcu ac felis accumsan posuere. Vestibulum sed ullamcorper dui. Ut ex nulla, dictum sit amet nisl luctus, venenatis ultrices ex. Praesent cursus nibh ac dapibus feugiat. Suspendisse libero orci, interdum eget hendrerit non, tempus eu ligula. Integer interdum augue convallis, commodo nisl nec, auctor nulla. Praesent non elit dignissim, consequat lacus a, rutrum nisl. Phasellus convallis elit tortor, eget auctor libero bibendum nec. Aenean eget lectus id eros facilisis porta. Fusce non sagittis lacus, eget pulvinar est. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis vitae nulla ac risus ultrices euismod. Proin eu mi sodales, rutrum leo eget, pretium metus. Nunc sagittis convallis cursus. Integer ut libero sagittis, molestie purus vel, porttitor massa. Maecenas rhoncus nunc ut lacus aliquam pretium. Pellentesque scelerisque enim nec accumsan blandit. Morbi erat risus, vehicula sit amet fermentum vel, dignissim ac purus. Fusce sagittis suscipit ligula, vitae ornare dolor fringilla ac. Maecenas dignissim diam diam, id ornare augue sagittis ut. Curabitur et eros nulla. Sed blandit ex et tellus ullamcorper gravida. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam fermentum lorem porttitor, porta augue quis, maximus nulla. Sed molestie leo nisi, nec luctus orci pretium vitae. Donec faucibus augue nec sodales congue. Integer ut dolor vel arcu vestibulum feugiat. Mauris eget accumsan ipsum. Proin auctor est et dui vulputate, id accumsan quam maximus. Mauris pulvinar lorem vitae risus maximus, id dictum mi varius. Ut fringilla, nisi eu laoreet hendrerit, felis ligula tempor sapien, sit amet commodo mi ipsum nec quam. Aliquam a commodo leo. Sed fringilla pretium lectus, nec auctor orci viverra et. Nulla facilisi. Duis accumsan turpis eget molestie egestas. Morbi ullamcorper libero arcu, et facilisis augue efficitur vitae. Integer vitae volutpat lacus, in dignissim elit. Praesent ac augue nunc. Nullam eget libero maximus magna bibendum facilisis. Cras volutpat nibh rhoncus, mattis odio at, blandit neque. Sed consequat felis non malesuada auctor. Phasellus sit amet aliquet dolor. Nam pellentesque at magna sit amet convallis. Suspendisse eleifend magna eros, quis molestie est fringilla ut. Proin blandit gravida sapien, id maximus eros rutrum nec. Duis cursus tristique egestas. Nunc malesuada arcu interdum nibh feugiat, nec placerat tellus mollis. Nulla placerat, mauris eget porttitor malesuada, metus libero auctor diam, ac sodales elit justo vitae dui. Sed congue massa in vehicula egestas. Duis iaculis est maximus tortor malesuada, sit amet ullamcorper massa tempor. Duis venenatis nisl nec nulla ultrices tempor. Aliquam auctor, quam vel imperdiet posuere, urna est sollicitudin nisl, mattis tempus quam eros ac mi. Proin aliquet odio at purus consequat efficitur ac nec augue. Proin ac metus in massa malesuada ornare. Proin a dui tortor. Nam molestie elit ut urna fringilla, id volutpat metus molestie. Nam cursus mattis tincidunt. Ut risus enim, imperdiet quis semper sed, pellentesque at purus. Suspendisse tempus porta tortor, ut condimentum justo fermentum nec. Quisque vitae dapibus nisi. Morbi dolor nisi, vulputate quis leo a, consectetur consectetur elit. Integer auctor sapien vel augue euismod placerat. Sed quis lacus est. Sed tincidunt nunc vel ultrices sodales. Fusce tempus egestas fringilla. Etiam egestas volutpat nunc in commodo. Nullam id facilisis magna. Vestibulum quis quam magna. Nulla gravida luctus sapien, vel pharetra turpis maximus quis. In hac habitasse platea dictumst. Morbi arcu magna, ornare vitae lacinia a, finibus nec urna. Sed et rutrum justo. Duis tincidunt purus orci, nec lobortis enim molestie vitae. Phasellus sed nisl quis lacus accumsan consectetur. Etiam luctus purus dui, ut vestibulum turpis eleifend ut. Nullam at diam et sem euismod varius pharetra ut urna. Maecenas finibus fringilla turpis, at semper lacus luctus sed. Nulla a odio vitae sem vestibulum euismod. Sed in eros arcu. Phasellus pharetra gravida sem, ut bibendum lacus rhoncus ac. Vivamus eleifend nec urna eget euismod. Maecenas et rhoncus nibh. Donec commodo augue felis, vel laoreet orci lacinia vitae. Nullam ut imperdiet elit. Praesent mi turpis, varius eget justo vel, tristique commodo nibh. Suspendisse tellus erat, interdum ac pellentesque sit amet, venenatis ac felis. Fusce sagittis magna velit, non pharetra urna sollicitudin sed. Donec a viverra massa, at cursus neque. Nam pretium sit amet risus ac volutpat. In lacinia, eros eu malesuada facilisis, eros neque porta nisi, in fermentum lectus nisl consequat leo. Sed eleifend, magna ut convallis fermentum, urna libero vehicula arcu, ut tempus quam orci ut nibh. Cras rutrum ex in hendrerit imperdiet. Integer egestas vitae elit fringilla fringilla. Proin ut lobortis massa. Phasellus commodo, ligula molestie lobortis viverra, metus odio porta ex, eu elementum neque quam id metus. Maecenas sollicitudin justo tristique efficitur accumsan. Pellentesque quis magna non nulla sodales semper sed eu dolor. Morbi urna magna, facilisis in enim ac, hendrerit rhoncus sapien. Sed et augue sit amet libero imperdiet accumsan at eget enim. Nullam ac finibus nisi, et viverra lorem. Phasellus egestas viverra lacus et scelerisque. Quisque et porttitor augue. Nulla facilisi. Vestibulum tincidunt eleifend faucibus. In fringilla aliquet iaculis. Proin eu bibendum mi, sit amet faucibus nulla. Pellentesque pulvinar lacus id augue feugiat facilisis. Suspendisse ac nunc tincidunt elit egestas interdum id vel nisi. Cras eu condimentum elit. Mauris eu arcu dignissim mauris condimentum auctor a sit amet ipsum. Integer euismod sit amet est sed sagittis. Praesent fringilla et mi vitae porta. Integer eget massa at elit venenatis pretium. Sed sit amet maximus enim. Fusce justo sapien, molestie vel augue vel, suscipit consectetur augue. Pellentesque tempor eu libero sed aliquet. Aenean vel consequat diam, at vulputate ex. Proin tristique ligula ut tempor efficitur. Phasellus sollicitudin nunc sit amet pulvinar imperdiet. Cras consequat lobortis urna, eu faucibus justo cursus ut. Fusce lectus nulla, fermentum vel nisi id, rhoncus aliquet leo. Fusce ac leo imperdiet, luctus elit vel, lobortis nibh. Sed in euismod mi. Aliquam rutrum sed nisi eget tincidunt. Donec quis sapien non tellus faucibus sollicitudin. Etiam luctus eget dolor ac fringilla. Donec lectus mi, ultrices vitae felis ut, blandit facilisis sapien. Mauris euismod erat sodales, tristique risus non, ultrices lacus. Curabitur tempor hendrerit elit. Etiam ac tempus sem, quis eleifend nulla. Curabitur commodo efficitur lorem in pretium. Nam dolor enim, feugiat eget leo ut, commodo auctor mi. Nullam vestibulum, justo a volutpat tempus, odio risus cursus nulla, vitae aliquet metus urna id tellus. Proin facilisis a sapien sed ultricies. Morbi efficitur quam in euismod ornare. Suspendisse aliquet leo sed porta dignissim. Curabitur id gravida purus. Praesent eu nunc a nibh accumsan tincidunt. Nam accumsan ultricies ligula et ullamcorper. Integer dapibus lobortis mauris, non pharetra massa sollicitudin eu. Aenean sagittis risus ac augue cursus, pretium commodo nisi bibendum. Donec quis diam eu tellus interdum dignissim. Duis ante nulla, aliquet quis risus sed, aliquet luctus arcu. Duis ultrices ac libero ut lacinia. Donec iaculis ante quis aliquet volutpat. Cras eu orci dui. Mauris sollicitudin turpis a orci faucibus bibendum. Sed varius consectetur lectus nec ornare. Sed ultrices, tortor sit amet pulvinar vehicula, nisi nibh pretium diam, a eleifend lac