loremipsum.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. // Copyright 2009 The Closure Library Authors. All Rights Reserved.
  2. /**
  3. * @fileoverview A generator of lorem ipsum text based on the python
  4. * implementation at http://code.google.com/p/lorem-ipsum-generator/.
  5. *
  6. */
  7. goog.provide('goog.text.LoremIpsum');
  8. goog.require('goog.array');
  9. goog.require('goog.math');
  10. goog.require('goog.string');
  11. goog.require('goog.structs.Map');
  12. goog.require('goog.structs.Set');
  13. /**
  14. * Generates random strings of "lorem ipsum" text, based on the word
  15. * distribution of a sample text, using the words in a dictionary.
  16. * @constructor
  17. */
  18. goog.text.LoremIpsum = function() {
  19. this.generateChains_(this.sample_);
  20. this.generateStatistics_(this.sample_);
  21. this.initializeDictionary_(this.dictionary_);
  22. };
  23. /**
  24. * Delimiters that end sentences.
  25. * @type {Array<string>}
  26. * @private
  27. */
  28. goog.text.LoremIpsum.DELIMITERS_SENTENCES_ = ['.', '?', '!'];
  29. /**
  30. * Regular expression for spliting a text into sentences.
  31. * @type {RegExp}
  32. * @private
  33. */
  34. goog.text.LoremIpsum.SENTENCE_SPLIT_REGEX_ = /[\.\?\!]/;
  35. /**
  36. * Delimiters that end words.
  37. * @type {Array<string>}
  38. * @private
  39. */
  40. goog.text.LoremIpsum.DELIMITERS_WORDS_ = [',', '.', '?', '!'];
  41. /**
  42. * Regular expression for spliting text into words.
  43. * @type {RegExp}
  44. * @private
  45. */
  46. goog.text.LoremIpsum.WORD_SPLIT_REGEX_ = /\s/;
  47. /**
  48. * Words that can be used in the generated output.
  49. * Maps a word-length to a list of words of that length.
  50. * @type {goog.structs.Map}
  51. * @private
  52. */
  53. goog.text.LoremIpsum.prototype.words_;
  54. /**
  55. * Chains of three words that appear in the sample text
  56. * Maps a pair of word-lengths to a third word-length and an optional
  57. * piece of trailing punctuation (for example, a period, comma, etc.).
  58. * @type {goog.structs.Map}
  59. * @private
  60. */
  61. goog.text.LoremIpsum.prototype.chains_;
  62. /** @private {!Object<string, !Array>} */
  63. goog.text.LoremIpsum.prototype.chainKeys_;
  64. /**
  65. * Pairs of word-lengths that can appear at the beginning of sentences.
  66. * @type {Array}
  67. */
  68. goog.text.LoremIpsum.prototype.starts_;
  69. /**
  70. * Averange sentence length in words.
  71. * @type {number}
  72. * @private
  73. */
  74. goog.text.LoremIpsum.prototype.sentenceMean_;
  75. /**
  76. * Sigma (sqrt of variance) for the sentence length in words.
  77. * @type {number}
  78. * @private
  79. */
  80. goog.text.LoremIpsum.prototype.sentenceSigma_;
  81. /**
  82. * Averange paragraph length in sentences.
  83. * @type {number}
  84. * @private
  85. */
  86. goog.text.LoremIpsum.prototype.paragraphMean_;
  87. /**
  88. * Sigma (sqrt of variance) for the paragraph length in sentences.
  89. * @type {number}
  90. * @private
  91. */
  92. goog.text.LoremIpsum.prototype.paragraphSigma_;
  93. /**
  94. * Generates the chains and starts values required for sentence generation.
  95. * @param {string} sample The same text.
  96. * @private
  97. */
  98. goog.text.LoremIpsum.prototype.generateChains_ = function(sample) {
  99. var words = goog.text.LoremIpsum.splitWords_(sample);
  100. var wordInfo = goog.array.map(words, goog.text.LoremIpsum.getWordInfo_);
  101. /** @type {!Array<number>} */
  102. var previous = [0, 0];
  103. var previousKey = previous.join('-');
  104. var chains = new goog.structs.Map();
  105. var starts = [previousKey];
  106. var chainKeys = {};
  107. goog.array.forEach(wordInfo, function(pair) {
  108. var chain = chains.get(previousKey);
  109. if (chain) {
  110. chain.push(pair);
  111. } else {
  112. chain = [pair];
  113. chains.set(previousKey, chain);
  114. }
  115. if (goog.array.contains(
  116. goog.text.LoremIpsum.DELIMITERS_SENTENCES_, pair[1])) {
  117. starts.push(previousKey);
  118. }
  119. chainKeys[previousKey] = previous;
  120. previous = [previous[1], pair[0]];
  121. previousKey = previous.join('-');
  122. });
  123. if (chains.getCount() > 0) {
  124. this.chains_ = chains;
  125. this.starts_ = starts;
  126. this.chainKeys_ = chainKeys;
  127. } else {
  128. throw Error('Could not generate chains from sample text.');
  129. }
  130. };
  131. /**
  132. * Calculates the mean and standard deviation of sentence and paragraph lengths.
  133. * @param {string} sample The same text.
  134. * @private
  135. */
  136. goog.text.LoremIpsum.prototype.generateStatistics_ = function(sample) {
  137. this.generateSentenceStatistics_(sample);
  138. this.generateParagraphStatistics_(sample);
  139. };
  140. /**
  141. * Calculates the mean and standard deviation of the lengths of sentences
  142. * (in words) in a sample text.
  143. * @param {string} sample The same text.
  144. * @private
  145. */
  146. goog.text.LoremIpsum.prototype.generateSentenceStatistics_ = function(sample) {
  147. var sentences = goog.array.filter(
  148. goog.text.LoremIpsum.splitSentences_(sample),
  149. goog.text.LoremIpsum.isNotEmptyOrWhitepace_);
  150. var sentenceLengths = goog.array.map(
  151. goog.array.map(sentences, goog.text.LoremIpsum.splitWords_),
  152. goog.text.LoremIpsum.arrayLength_);
  153. this.sentenceMean_ = goog.math.average.apply(null, sentenceLengths);
  154. this.sentenceSigma_ = goog.math.standardDeviation.apply(
  155. null, sentenceLengths);
  156. };
  157. /**
  158. * Calculates the mean and standard deviation of the lengths of paragraphs
  159. * (in sentences) in a sample text.
  160. * @param {string} sample The same text.
  161. * @private
  162. */
  163. goog.text.LoremIpsum.prototype.generateParagraphStatistics_ = function(sample) {
  164. var paragraphs = goog.array.filter(
  165. goog.text.LoremIpsum.splitParagraphs_(sample),
  166. goog.text.LoremIpsum.isNotEmptyOrWhitepace_);
  167. var paragraphLengths = goog.array.map(
  168. goog.array.map(paragraphs, goog.text.LoremIpsum.splitSentences_),
  169. goog.text.LoremIpsum.arrayLength_);
  170. this.paragraphMean_ = goog.math.average.apply(null, paragraphLengths);
  171. this.paragraphSigma_ = goog.math.standardDeviation.apply(
  172. null, paragraphLengths);
  173. };
  174. /**
  175. * Sets the generator to use a given selection of words for generating
  176. * sentences with.
  177. * @param {string} dictionary The dictionary to use.
  178. * @private
  179. */
  180. goog.text.LoremIpsum.prototype.initializeDictionary_ = function(dictionary) {
  181. var dictionaryWords = goog.text.LoremIpsum.splitWords_(dictionary);
  182. var words = new goog.structs.Map();
  183. goog.array.forEach(dictionaryWords, function(word) {
  184. var set = words.get(word.length);
  185. if (!set) {
  186. set = new goog.structs.Set();
  187. words.set(word.length, set);
  188. }
  189. set.add(word);
  190. });
  191. this.words_ = words;
  192. };
  193. /**
  194. * Picks a random starting chain.
  195. * @return {Array<string>} The starting key.
  196. * @private
  197. */
  198. goog.text.LoremIpsum.prototype.chooseRandomStart_ = function() {
  199. var key = /** @type {string} */ (goog.text.LoremIpsum.randomChoice_(
  200. this.starts_));
  201. return this.chainKeys_[key];
  202. };
  203. /**
  204. * Generates a single sentence, of random length.
  205. * @param {boolean=} opt_startWithLorem Whether to start the setnence with the
  206. * standard "Lorem ipsum..." first sentence.
  207. * @return {string} The generated sentence.
  208. */
  209. goog.text.LoremIpsum.prototype.generateSentence = function(opt_startWithLorem) {
  210. if (this.chains_.getCount() == 0 || this.starts_.length == 0) {
  211. throw Error('No chains created');
  212. }
  213. if (this.words_.getCount() == 0) {
  214. throw Error('No dictionary');
  215. }
  216. // The length of the sentence is a normally distributed random variable.
  217. var sentenceLength = goog.text.LoremIpsum.randomNormal_(
  218. this.sentenceMean_, this.sentenceSigma_);
  219. sentenceLength = Math.max(Math.floor(sentenceLength), 1);
  220. var wordDelimiter = ''; // Defined here in case while loop doesn't run
  221. // Start the sentence with "Lorem ipsum...", if desired
  222. var sentence;
  223. if (opt_startWithLorem) {
  224. var lorem = 'lorem ipsum dolor sit amet, consecteteur adipiscing elit';
  225. sentence = goog.text.LoremIpsum.splitWords_(lorem);
  226. if (sentence.length > sentenceLength) {
  227. sentence.length = sentenceLength;
  228. }
  229. var lastWord = sentence[sentence.length - 1];
  230. var lastChar = lastWord.substring(lastWord.length - 1);
  231. if (goog.array.contains(goog.text.LoremIpsum.DELIMITERS_WORDS_, lastChar)) {
  232. wordDelimiter = lastChar;
  233. }
  234. } else {
  235. sentence = [];
  236. }
  237. var previous = [];
  238. var previousKey = '';
  239. // Generate a sentence from the "chains"
  240. while (sentence.length < sentenceLength) {
  241. // If the current starting point is invalid, choose another randomly
  242. if (!this.chains_.containsKey(previousKey)) {
  243. previous = this.chooseRandomStart_();
  244. previousKey = previous.join('-');
  245. }
  246. // Choose the next "chain" to go to. This determines the next word
  247. // length we'll use, and whether there is e.g. a comma at the end of
  248. // the word.
  249. var chain = /** @type {Array} */ (goog.text.LoremIpsum.randomChoice_(
  250. /** @type {Array} */ (this.chains_.get(previousKey))));
  251. var wordLength = chain[0];
  252. // If the word delimiter contained in the chain is also a sentence
  253. // delimiter, then we don't include it because we don't want the
  254. // sentence to end prematurely (we want the length to match the
  255. // sentence_length value).
  256. //debugger;
  257. if (goog.array.contains(goog.text.LoremIpsum.DELIMITERS_SENTENCES_,
  258. chain[1])) {
  259. wordDelimiter = '';
  260. } else {
  261. wordDelimiter = chain[1];
  262. }
  263. // Choose a word randomly that matches (or closely matches) the
  264. // length we're after.
  265. var closestLength = goog.text.LoremIpsum.chooseClosest(
  266. this.words_.getKeys(), wordLength);
  267. var word = goog.text.LoremIpsum.randomChoice_(
  268. this.words_.get(closestLength).getValues());
  269. sentence.push(word + wordDelimiter);
  270. previous = [previous[1], wordLength];
  271. previousKey = previous.join('-');
  272. }
  273. // Finish the sentence off with capitalisation, a period and
  274. // form it into a string
  275. sentence = sentence.join(' ');
  276. sentence = sentence.slice(0, 1).toUpperCase() + sentence.slice(1);
  277. if (sentence.substring(sentence.length - 1) == wordDelimiter) {
  278. sentence = sentence.slice(0, sentence.length - 1);
  279. }
  280. return sentence + '.';
  281. };
  282. /**
  283. * Generates a single lorem ipsum paragraph, of random length.
  284. * @param {boolean=} opt_startWithLorem Whether to start the sentence with the
  285. * standard "Lorem ipsum..." first sentence.
  286. * @return {string} The generated sentence.
  287. */
  288. goog.text.LoremIpsum.prototype.generateParagraph = function(
  289. opt_startWithLorem) {
  290. // The length of the paragraph is a normally distributed random variable.
  291. var paragraphLength = goog.text.LoremIpsum.randomNormal_(
  292. this.paragraphMean_, this.paragraphSigma_);
  293. paragraphLength = Math.max(Math.floor(paragraphLength), 1);
  294. // Construct a paragraph from a number of sentences.
  295. var paragraph = [];
  296. var startWithLorem = opt_startWithLorem;
  297. while (paragraph.length < paragraphLength) {
  298. var sentence = this.generateSentence(startWithLorem);
  299. paragraph.push(sentence);
  300. startWithLorem = false;
  301. }
  302. // Form the paragraph into a string.
  303. paragraph = paragraph.join(' ');
  304. return paragraph;
  305. };
  306. /**
  307. * Splits a piece of text into paragraphs.
  308. * @param {string} text The text to split.
  309. * @return {Array<string>} An array of paragraphs.
  310. * @private
  311. */
  312. goog.text.LoremIpsum.splitParagraphs_ = function(text) {
  313. return text.split('\n');
  314. };
  315. /**
  316. * Splits a piece of text into sentences.
  317. * @param {string} text The text to split.
  318. * @return {Array<string>} An array of sentences.
  319. * @private
  320. */
  321. goog.text.LoremIpsum.splitSentences_ = function(text) {
  322. return goog.array.filter(
  323. text.split(goog.text.LoremIpsum.SENTENCE_SPLIT_REGEX_),
  324. goog.text.LoremIpsum.isNotEmptyOrWhitepace_);
  325. };
  326. /**
  327. * Splits a piece of text into words..
  328. * @param {string} text The text to split.
  329. * @return {Array<string>} An array of words.
  330. * @private
  331. */
  332. goog.text.LoremIpsum.splitWords_ = function(text) {
  333. return goog.array.filter(
  334. text.split(goog.text.LoremIpsum.WORD_SPLIT_REGEX_),
  335. goog.text.LoremIpsum.isNotEmptyOrWhitepace_);
  336. };
  337. /**
  338. * Returns the text is not empty or just whitespace.
  339. * @param {string} text The text to check.
  340. * @return {boolean} Whether the text is nether empty nor whitespace.
  341. * @private
  342. */
  343. goog.text.LoremIpsum.isNotEmptyOrWhitepace_ = function(text) {
  344. return goog.string.trim(text).length > 0;
  345. };
  346. /**
  347. * Returns the length of an array. Written as a function so it can be used
  348. * as a function parameter.
  349. * @param {Array} array The array to check.
  350. * @return {number} The length of the array.
  351. * @private
  352. */
  353. goog.text.LoremIpsum.arrayLength_ = function(array) {
  354. return array.length;
  355. };
  356. /**
  357. * Find the number in the list of values that is closest to the target.
  358. * @param {Array<number>|Array<string>} values The values.
  359. * @param {number} target The target value.
  360. * @return {number} The closest value.
  361. */
  362. goog.text.LoremIpsum.chooseClosest = function(values, target) {
  363. var closest = Number(values[0]);
  364. goog.array.forEach(values, function(value) {
  365. if (Math.abs(target - Number(value)) < Math.abs(target - closest)) {
  366. closest = value;
  367. }
  368. });
  369. return closest;
  370. };
  371. /**
  372. * Gets info about a word used as part of the lorem ipsum algorithm.
  373. * @param {string} word The word to check.
  374. * @return {Array} A two element array. The first element is the size of the
  375. * word. The second element is the delimter used in the word.
  376. * @private
  377. */
  378. goog.text.LoremIpsum.getWordInfo_ = function(word) {
  379. var ret;
  380. goog.array.some(goog.text.LoremIpsum.DELIMITERS_WORDS_,
  381. function(delimiter) {
  382. if (goog.string.endsWith(word, delimiter)) {
  383. ret = [word.length - delimiter.length, delimiter];
  384. return true;
  385. }
  386. return false;
  387. }
  388. );
  389. return ret || [word.length, ''];
  390. };
  391. /**
  392. * Constant used for {@link #randomNormal_}.
  393. * @type {number}
  394. * @private
  395. */
  396. goog.text.LoremIpsum.NV_MAGICCONST_ = 4 * Math.exp(-0.5) / Math.sqrt(2.0);
  397. /**
  398. * Generates a random number for a normal distribution with the specified
  399. * mean and sigma.
  400. * @param {number} mu The mean of the distribution.
  401. * @param {number} sigma The sigma of the distribution.
  402. * @return {number}
  403. * @private
  404. */
  405. goog.text.LoremIpsum.randomNormal_ = function(mu, sigma) {
  406. while (true) {
  407. var u1 = Math.random();
  408. var u2 = 1.0 - Math.random();
  409. var z = goog.text.LoremIpsum.NV_MAGICCONST_ * (u1 - 0.5) / u2;
  410. var zz = z * z / 4.0;
  411. if (zz <= -Math.log(u2)) {
  412. break;
  413. }
  414. }
  415. return mu + z * sigma;
  416. };
  417. /**
  418. * Picks a random element of the array.
  419. * @param {Array} array The array to pick from.
  420. * @return {*} An element from the array.
  421. * @private
  422. */
  423. goog.text.LoremIpsum.randomChoice_ = function(array) {
  424. return array[goog.math.randomInt(array.length)];
  425. };
  426. /**
  427. * Dictionary of words for lorem ipsum.
  428. * @private {string}
  429. */
  430. goog.text.LoremIpsum.DICT_ =
  431. 'a ac accumsan ad adipiscing aenean aliquam aliquet amet ante ' +
  432. 'aptent arcu at auctor augue bibendum blandit class commodo ' +
  433. 'condimentum congue consectetuer consequat conubia convallis cras ' +
  434. 'cubilia cum curabitur curae cursus dapibus diam dictum dictumst ' +
  435. 'dignissim dis dolor donec dui duis egestas eget eleifend elementum ' +
  436. 'elit eni enim erat eros est et etiam eu euismod facilisi facilisis ' +
  437. 'fames faucibus felis fermentum feugiat fringilla fusce gravida ' +
  438. 'habitant habitasse hac hendrerit hymenaeos iaculis id imperdiet ' +
  439. 'in inceptos integer interdum ipsum justo lacinia lacus laoreet ' +
  440. 'lectus leo libero ligula litora lobortis lorem luctus maecenas ' +
  441. 'magna magnis malesuada massa mattis mauris metus mi molestie ' +
  442. 'mollis montes morbi mus nam nascetur natoque nec neque netus ' +
  443. 'nibh nisi nisl non nonummy nostra nulla nullam nunc odio orci ' +
  444. 'ornare parturient pede pellentesque penatibus per pharetra ' +
  445. 'phasellus placerat platea porta porttitor posuere potenti praesent ' +
  446. 'pretium primis proin pulvinar purus quam quis quisque rhoncus ' +
  447. 'ridiculus risus rutrum sagittis sapien scelerisque sed sem semper ' +
  448. 'senectus sit sociis sociosqu sodales sollicitudin suscipit ' +
  449. 'suspendisse taciti tellus tempor tempus tincidunt torquent tortor ' +
  450. 'tristique turpis ullamcorper ultrices ultricies urna ut varius ve ' +
  451. 'vehicula vel velit venenatis vestibulum vitae vivamus viverra ' +
  452. 'volutpat vulputate';
  453. /**
  454. * A sample to use for generating the distribution of word and sentence lengths
  455. * in lorem ipsum.
  456. * @type {string}
  457. * @private
  458. */
  459. goog.text.LoremIpsum.SAMPLE_ =
  460. 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean ' +
  461. 'commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus ' +
  462. 'et magnis dis parturient montes, nascetur ridiculus mus. Donec quam ' +
  463. 'felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla ' +
  464. 'consequat massa quis enim. Donec pede justo, fringilla vel, aliquet ' +
  465. 'nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, ' +
  466. 'venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. ' +
  467. 'Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean ' +
  468. 'vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat ' +
  469. 'vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra ' +
  470. 'quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius ' +
  471. 'laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel ' +
  472. 'augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.\n\n' +
  473. 'Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem ' +
  474. 'quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam ' +
  475. 'nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec ' +
  476. 'odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis ' +
  477. 'faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus ' +
  478. 'tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales ' +
  479. 'sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit ' +
  480. 'cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend ' +
  481. 'sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, ' +
  482. 'metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis ' +
  483. 'hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci ' +
  484. 'luctus et ultrices posuere cubilia Curae; In ac dui quis mi ' +
  485. 'consectetuer lacinia.\n\n' +
  486. 'Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet ' +
  487. 'nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ' +
  488. 'ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent ' +
  489. 'adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy ' +
  490. 'metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros ' +
  491. 'et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, ' +
  492. 'nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit ' +
  493. 'risus. Phasellus nec sem in justo pellentesque facilisis. Etiam ' +
  494. 'imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus ' +
  495. 'non, auctor et, hendrerit quis, nisi.\n\n' +
  496. 'Curabitur ligula sapien, tincidunt non, euismod vitae, posuere ' +
  497. 'imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed ' +
  498. 'cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus ' +
  499. 'accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci ' +
  500. 'luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis ' +
  501. 'porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis ' +
  502. 'orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, ' +
  503. 'bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede ' +
  504. 'sit amet augue. In turpis. Pellentesque posuere. Praesent turpis.\n\n' +
  505. 'Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu ' +
  506. 'sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales ' +
  507. 'nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse ' +
  508. 'pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, ' +
  509. 'nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in ' +
  510. 'faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id ' +
  511. 'purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum ' +
  512. 'mollis diam. Pellentesque ut neque. Pellentesque habitant morbi ' +
  513. 'tristique senectus et netus et malesuada fames ac turpis egestas.\n\n' +
  514. 'In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac ' +
  515. 'felis quis tortor malesuada pretium. Pellentesque auctor neque nec ' +
  516. 'urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean ' +
  517. 'viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et ' +
  518. 'netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis ' +
  519. 'pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna.\n\n' +
  520. 'In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare ' +
  521. 'lobortis. Curabitur a felis in nunc fringilla tristique. Morbi mattis ' +
  522. 'ullamcorper velit. Phasellus gravida semper nisi. Nullam vel sem. ' +
  523. 'Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, ' +
  524. 'quam. Sed hendrerit. Morbi ac felis. Nunc egestas, augue at ' +
  525. 'pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo ' +
  526. 'quis pede. Donec interdum, metus et hendrerit aliquet, dolor diam ' +
  527. 'sagittis ligula, eget egestas libero turpis vel mi. Nunc nulla. Fusce ' +
  528. 'risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis ' +
  529. 'vulputate lorem.\n\n' +
  530. 'Morbi nec metus. Phasellus blandit leo ut odio. Maecenas ullamcorper, ' +
  531. 'dui et placerat feugiat, eros pede varius nisi, condimentum viverra ' +
  532. 'felis nunc et lorem. Sed magna purus, fermentum eu, tincidunt eu, ' +
  533. 'varius ut, felis. In auctor lobortis lacus. Quisque libero metus, ' +
  534. 'condimentum nec, tempor a, commodo mollis, magna. Vestibulum ' +
  535. 'ullamcorper mauris at ligula. Fusce fermentum. Nullam cursus lacinia ' +
  536. 'erat. Praesent blandit laoreet nibh.\n\n' +
  537. 'Fusce convallis metus id felis luctus adipiscing. Pellentesque egestas, ' +
  538. 'neque sit amet convallis pulvinar, justo nulla eleifend augue, ac ' +
  539. 'auctor orci leo non est. Quisque id mi. Ut tincidunt tincidunt erat. ' +
  540. 'Etiam feugiat lorem non metus. Vestibulum dapibus nunc ac augue. ' +
  541. 'Curabitur vestibulum aliquam leo. Praesent egestas neque eu enim. In ' +
  542. 'hac habitasse platea dictumst. Fusce a quam. Etiam ut purus mattis ' +
  543. 'mauris sodales aliquam. Curabitur nisi. Quisque malesuada placerat ' +
  544. 'nisl. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, ' +
  545. 'lacus.\n\n' +
  546. 'Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, ' +
  547. 'dui. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi ' +
  548. 'congue nunc, vitae euismod ligula urna in dolor. Mauris sollicitudin ' +
  549. 'fermentum libero. Praesent nonummy mi in odio. Nunc interdum lacus sit ' +
  550. 'amet orci. Vestibulum rutrum, mi nec elementum vehicula, eros quam ' +
  551. 'gravida nisl, id fringilla neque ante vel mi. Morbi mollis tellus ac ' +
  552. 'sapien. Phasellus volutpat, metus eget egestas mollis, lacus lacus ' +
  553. 'blandit dui, id egestas quam mauris ut lacus. Fusce vel dui. Sed in ' +
  554. 'libero ut nibh placerat accumsan. Proin faucibus arcu quis ante. In ' +
  555. 'consectetuer turpis ut velit. Nulla sit amet est. Praesent metus ' +
  556. 'tellus, elementum eu, semper a, adipiscing nec, purus. Cras risus ' +
  557. 'ipsum, faucibus ut, ullamcorper id, varius ac, leo. Suspendisse ' +
  558. 'feugiat. Suspendisse enim turpis, dictum sed, iaculis a, condimentum ' +
  559. 'nec, nisi. Praesent nec nisl a purus blandit viverra. Praesent ac ' +
  560. 'massa at ligula laoreet iaculis. Nulla neque dolor, sagittis eget, ' +
  561. 'iaculis quis, molestie non, velit.\n\n' +
  562. 'Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. ' +
  563. 'Fusce pharetra convallis urna. Quisque ut nisi. Donec mi odio, faucibus ' +
  564. 'at, scelerisque quis, convallis in, nisi. Suspendisse non nisl sit amet ' +
  565. 'velit hendrerit rutrum. Ut leo. Ut a nisl id ante tempus hendrerit. ' +
  566. 'Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, ' +
  567. 'sed gravida augue augue mollis justo. Suspendisse eu ligula. Nulla ' +
  568. 'facilisi. Donec id justo. Praesent porttitor, nulla vitae posuere ' +
  569. 'iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. ' +
  570. 'Curabitur suscipit suscipit tellus.\n\n' +
  571. 'Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus. Ut id ' +
  572. 'nisl quis enim dignissim sagittis. Etiam sollicitudin, ipsum eu ' +
  573. 'pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante ' +
  574. 'odio sit amet eros. Proin magna. Duis vel nibh at velit scelerisque ' +
  575. 'suscipit. Curabitur turpis. Vestibulum suscipit nulla quis orci. Fusce ' +
  576. 'ac felis sit amet ligula pharetra condimentum. Maecenas egestas arcu ' +
  577. 'quis ligula mattis placerat. Duis lobortis massa imperdiet quam. ' +
  578. 'Suspendisse potenti.\n\n' +
  579. 'Pellentesque commodo eros a enim. Vestibulum turpis sem, aliquet eget, ' +
  580. 'lobortis pellentesque, rutrum eu, nisl. Sed libero. Aliquam erat ' +
  581. 'volutpat. Etiam vitae tortor. Morbi vestibulum volutpat enim. Aliquam ' +
  582. 'eu nunc. Nunc sed turpis. Sed mollis, eros et ultrices tempus, mauris ' +
  583. 'ipsum aliquam libero, non adipiscing dolor urna a orci. Nulla porta ' +
  584. 'dolor. Class aptent taciti sociosqu ad litora torquent per conubia ' +
  585. 'nostra, per inceptos hymenaeos.\n\n' +
  586. 'Pellentesque dapibus hendrerit tortor. Praesent egestas tristique nibh. ' +
  587. 'Sed a libero. Cras varius. Donec vitae orci sed dolor rutrum auctor. ' +
  588. 'Fusce egestas elit eget lorem. Suspendisse nisl elit, rhoncus eget, ' +
  589. 'elementum ac, condimentum eget, diam. Nam at tortor in tellus interdum ' +
  590. 'sagittis. Aliquam lobortis. Donec orci lectus, aliquam ut, faucibus ' +
  591. 'non, euismod id, nulla. Curabitur blandit mollis lacus. Nam adipiscing. ' +
  592. 'Vestibulum eu odio.\n\n' +
  593. 'Vivamus laoreet. Nullam tincidunt adipiscing enim. Phasellus tempus. ' +
  594. 'Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique ' +
  595. 'sapien, a accumsan nisi mauris ac eros. Fusce neque. Suspendisse ' +
  596. 'faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, ' +
  597. 'vitae iaculis lacus elit id tortor. Vivamus aliquet elit ac nisl. Fusce ' +
  598. 'fermentum odio nec arcu. Vivamus euismod mauris. In ut quam vitae ' +
  599. 'odio lacinia tincidunt. Praesent ut ligula non mi varius sagittis. ' +
  600. 'Cras sagittis. Praesent ac sem eget est egestas volutpat. Vivamus ' +
  601. 'consectetuer hendrerit lacus. Cras non dolor. Vivamus in erat ut urna ' +
  602. 'cursus vestibulum. Fusce commodo aliquam arcu. Nam commodo suscipit ' +
  603. 'quam. Quisque id odio. Praesent venenatis metus at tortor pulvinar ' +
  604. 'varius.\n\n';
  605. /**
  606. * Sample that the generated text is based on .
  607. * @private {string}
  608. */
  609. goog.text.LoremIpsum.prototype.sample_ = goog.text.LoremIpsum.SAMPLE_;
  610. /**
  611. * Dictionary of words.
  612. * @private {string}
  613. */
  614. goog.text.LoremIpsum.prototype.dictionary_ = goog.text.LoremIpsum.DICT_;