html_utils.js 154 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169
  1. window.onload = function() {
  2. // textCleanup
  3. test("textCleanup", function() {
  4. var source = "Some\nValue\n\n\nTest"
  5. var should = "Some\nValue\n\nTest"
  6. var result = App.Utils.textCleanup(source)
  7. equal(result, should, source)
  8. source = "Some\nValue\n\n \n\n\nTest"
  9. should = "Some\nValue\n\nTest"
  10. result = App.Utils.textCleanup(source)
  11. equal(result, should, source)
  12. source = "Some\n\rValue\n\r\n\r\n\rTest"
  13. should = "Some\nValue\n\nTest"
  14. result = App.Utils.textCleanup(source)
  15. equal(result, should, source)
  16. source = "Some\n\rValue\n\r\n\r\n\rTest\r"
  17. should = "Some\nValue\n\nTest"
  18. result = App.Utils.textCleanup(source)
  19. equal(result, should, source)
  20. source = "Some\r\nValue\r\n\r\n\r\nTest\r\n"
  21. should = "Some\nValue\n\nTest"
  22. result = App.Utils.textCleanup(source)
  23. equal(result, should, source)
  24. source = "Some\r\nValue\r\n\r\n\r\n\r\n\r\n\r\nTest\r\n"
  25. should = "Some\nValue\n\nTest"
  26. result = App.Utils.textCleanup(source)
  27. equal(result, should, source)
  28. source = "> Welcome!\n> \n> Thank you for installing Zammad.\n> \n> You will find ..."
  29. should = "> Welcome!\n>\n> Thank you for installing Zammad.\n>\n> You will find ..."
  30. result = App.Utils.textCleanup(source)
  31. equal(result, should, source)
  32. });
  33. // text2html
  34. test("text2html", function() {
  35. var source = "Some\nValue\n\n\nTest"
  36. var should = "<div>Some</div><div>Value</div><div><br></div><div>Test</div>"
  37. var result = App.Utils.text2html(source)
  38. equal(result, should, source)
  39. source = "Some\nValue\n"
  40. should = "<div>Some</div><div>Value</div>"
  41. result = App.Utils.text2html(source)
  42. equal(result, should, source)
  43. source = "Some\n<b>Value</b>\n"
  44. should = "<div>Some</div><div>&lt;b&gt;Value&lt;/b&gt;</div>"
  45. result = App.Utils.text2html(source)
  46. equal(result, should, source)
  47. source = "> Welcome!\n> \n> Thank you for installing Zammad.\n> \n> You will find ..."
  48. should = "<div>&gt; Welcome!</div><div>&gt;</div><div>&gt; Thank you for installing Zammad.</div><div>&gt;</div><div>&gt; You will find ...</div>"
  49. result = App.Utils.text2html(source)
  50. equal(result, should, source)
  51. });
  52. // htmlStrip
  53. test("htmlStrip", function() {
  54. var source = $('<div><br><b>lala</b></div>')
  55. var should = '<div><b>lala</b></div>'
  56. App.Utils.htmlStrip(source)
  57. equal(source.get(0).outerHTML, should)
  58. source = $('<div><br><br><br><b>lala</b></div>')
  59. should = '<div><b>lala</b></div>'
  60. App.Utils.htmlStrip(source)
  61. equal(source.get(0).outerHTML, should)
  62. source = $('<div><br><br><br><b>lala</b><br><br></div>')
  63. should = '<div><b>lala</b></div>'
  64. App.Utils.htmlStrip(source)
  65. equal(source.get(0).outerHTML, should)
  66. source = $('<div><br><br><div><br></div><b>lala</b><br><br></div>')
  67. should = '<div><div><br></div><b>lala</b></div>'
  68. App.Utils.htmlStrip(source)
  69. equal(source.get(0).outerHTML, should)
  70. });
  71. // lastLineEmpty
  72. test("htmlLastLineEmpty", function() {
  73. var source = $('<div><br><b>lala</b></div>')
  74. equal(App.Utils.htmlLastLineEmpty(source), false)
  75. source = $('<div><br><b>lala</b><br></div>')
  76. equal(App.Utils.htmlLastLineEmpty(source), true)
  77. });
  78. // html2text
  79. test("html2text", function() {
  80. var source = "<div>Some</div><div>Value</div><div><br></div><div>Test</div>"
  81. var should = "Some\nValue\n\nTest"
  82. var result = App.Utils.html2text(source)
  83. equal(result, should, source)
  84. source = "<div>Some</div><div>Value</div>"
  85. should = "Some\nValue"
  86. result = App.Utils.html2text(source)
  87. equal(result, should, source)
  88. source = "<div>Some<br/>Value</div>"
  89. should = "Some\nValue"
  90. result = App.Utils.html2text(source)
  91. equal(result, should, source)
  92. source = "<div>Some &amp; &lt;Value&gt;</div>"
  93. should = "Some & <Value>"
  94. result = App.Utils.html2text(source)
  95. equal(result, should, source)
  96. source = "<div>Some</div><div>&lt;b&gt;Value&lt;/b&gt;</div>"
  97. should = "Some\n<b>Value</b>"
  98. result = App.Utils.html2text(source)
  99. equal(result, should, source)
  100. source = "<div>&gt; Welcome!</div><div>&gt;</div><div>&gt; Thank you for installing Zammad.</div><div>&gt;</div><div>&gt; You will find ...</div>"
  101. should = "> Welcome!\n>\n> Thank you for installing Zammad.\n>\n> You will find ..."
  102. result = App.Utils.html2text(source)
  103. equal(result, should, source)
  104. source = "<div>test 123 <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>--<br/>Bob Smith</div>"
  105. should = "test 123 \n\n--\nBob Smith"
  106. result = App.Utils.html2text(source)
  107. equal(result, should, source)
  108. source = "test 123 <br><br><br><br><br><br><br><br><br><br><br>--<br>Bob Smith"
  109. should = "test 123 \n\n--\nBob Smith"
  110. result = App.Utils.html2text(source)
  111. equal(result, should, source)
  112. source = "<div>1<br><br><br><br><br><br><br><br><br><br></div><div>Von: Martin Edenhofer via Znuny Support [<a href=\"mailto:support@znuny.inc\" title=\"mailto:support@znuny.inc\" target=\"_blank\">mailto:support@znuny.inc</a>]</div>\n<div>Gesendet: Donnerstag, 2. April 2015 11:32</div>"
  113. should = "1\n\nVon: Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]\nGesendet: Donnerstag, 2. April 2015 11:32"
  114. result = App.Utils.html2text(source)
  115. equal(result, should, source)
  116. source = "<div>test 123<br/>lalala<p>--</p>some test</div>"
  117. should = "test 123\nlalala\n--\nsome test"
  118. result = App.Utils.html2text(source)
  119. equal(result, should, source)
  120. source = "<p><span>Was\nsoll verbessert werden:</span></p>"
  121. should = "Was soll verbessert werden:"
  122. result = App.Utils.html2text(source)
  123. equal(result, should, source)
  124. // in raw format, without cleanup
  125. source = "<div>Some</div><div>1234</div>"
  126. should = "Some\n1234\n"
  127. result = App.Utils.html2text(source, true)
  128. equal(result, should, source)
  129. source = "<div>Some</div><div> 1234</div>"
  130. should = "Some\n 1234\n"
  131. result = App.Utils.html2text(source, true)
  132. equal(result, should, source)
  133. source = "\n\n<div>Some</div>\n<div> 1234</div>"
  134. should = "Some\n 1234\n"
  135. result = App.Utils.html2text(source, true)
  136. equal(result, should, source)
  137. source = "<div>Some</div><div> 1234</div>"
  138. should = "Some\n 1234\n"
  139. result = App.Utils.html2text(source, true)
  140. equal(result, should, source)
  141. source = "<div>Some</div>\n\n<div> 1234</div>\n"
  142. should = "Some\n 1234\n"
  143. result = App.Utils.html2text(source, true)
  144. equal(result, should, source)
  145. source = "<div>test<br>new line<br></div>"
  146. should = "test\nnew line\n\n"
  147. result = App.Utils.html2text(source, true)
  148. equal(result, should, source)
  149. source = "<p><span>Was\nsoll verbessert werden:</span></p>"
  150. should = "Was soll verbessert werden:\n"
  151. result = App.Utils.html2text(source, true)
  152. equal(result, should, source)
  153. });
  154. // phoneify
  155. test("phoneify", function() {
  156. var source = "+1 123 123 123-123"
  157. var should = 'tel:+1123123123123'
  158. var result = App.Utils.phoneify(source)
  159. equal(result, should, source)
  160. source = "+1 123 123 A 123-123<>"
  161. should = 'tel:+1123123123123'
  162. result = App.Utils.phoneify(source)
  163. equal(result, should, source)
  164. source = "+1 (123) 123 123-123"
  165. should = 'tel:+1123123123123'
  166. result = App.Utils.phoneify(source)
  167. equal(result, should, source)
  168. source = "+1 (123) 123 1#23-123"
  169. should = 'tel:+11231231#23123'
  170. result = App.Utils.phoneify(source)
  171. equal(result, should, source)
  172. source = "+1 (123) 12*3 1#23-123"
  173. should = 'tel:+112312*31#23123'
  174. result = App.Utils.phoneify(source)
  175. equal(result, should, source)
  176. source = "+1 (123) 12+3"
  177. should = 'tel:+1123123'
  178. result = App.Utils.phoneify(source)
  179. equal(result, should, source)
  180. source = "+1 (123) 123 "
  181. should = 'tel:+1123123'
  182. result = App.Utils.phoneify(source)
  183. equal(result, should, source)
  184. source = " +1 (123) 123 "
  185. should = 'tel:+1123123'
  186. result = App.Utils.phoneify(source)
  187. equal(result, should, source)
  188. })
  189. // linkify
  190. test("linkify", function() {
  191. var source = "http://example.com"
  192. var should = '<a href="http://example.com" title="http://example.com" target="_blank">http://example.com</a>'
  193. var result = App.Utils.linkify(source)
  194. equal(result, should, source)
  195. source = "http://example.com?some_param=lalala"
  196. should = '<a href="http://example.com?some_param=lalala" title="http://example.com?some_param=lalala" target="_blank">http://example.com?some_param=lalala</a>'
  197. result = App.Utils.linkify(source)
  198. equal(result, should, source)
  199. source = "example.com"
  200. should = '<a href="http://example.com" title="http://example.com" target="_blank">example.com</a>'
  201. result = App.Utils.linkify(source)
  202. equal(result, should, source)
  203. source = "some text example.com"
  204. should = 'some text <a href="http://example.com" title="http://example.com" target="_blank">example.com</a>'
  205. result = App.Utils.linkify(source)
  206. equal(result, should, source)
  207. source = "example.com some text"
  208. should = '<a href="http://example.com" title="http://example.com" target="_blank">example.com</a> some text'
  209. result = App.Utils.linkify(source)
  210. equal(result, should, source)
  211. source = "test@example.com some text"
  212. should = 'test@example.com some text'
  213. result = App.Utils.linkify(source)
  214. equal(result, should, source)
  215. source = "abc test@example.com some text"
  216. should = 'abc test@example.com some text'
  217. result = App.Utils.linkify(source)
  218. equal(result, should, source)
  219. /*
  220. source = "<b>example.com</b>"
  221. should = '<b><a href="http://example.com" title="http://example.com" target="_blank">http://example.com</a></b>'
  222. result = App.Utils.linkify(source)
  223. equal(result, should, source)
  224. */
  225. });
  226. // htmlEscape
  227. test("htmlEscape", function() {
  228. var source = "<"
  229. var should = "&lt;"
  230. var result = App.Utils.htmlEscape(source)
  231. equal(result, should, source)
  232. source = ">"
  233. should = "&gt;"
  234. result = App.Utils.htmlEscape(source)
  235. equal(result, should, source)
  236. source = "&"
  237. should = "&amp;"
  238. result = App.Utils.htmlEscape(source)
  239. equal(result, should, source)
  240. source = "&amp;"
  241. should = "&amp;amp;"
  242. result = App.Utils.htmlEscape(source)
  243. equal(result, should, source)
  244. source = "&amp ;"
  245. should = "&amp;amp ;"
  246. result = App.Utils.htmlEscape(source)
  247. equal(result, should, source)
  248. source = "& amp;"
  249. should = "&amp; amp;"
  250. result = App.Utils.htmlEscape(source)
  251. equal(result, should, source)
  252. source = "'test'"
  253. should = "&#39;test&#39;"
  254. result = App.Utils.htmlEscape(source)
  255. equal(result, should, source)
  256. source = '"test"'
  257. should = "&quot;test&quot;"
  258. result = App.Utils.htmlEscape(source)
  259. equal(result, should, source)
  260. source = "<>"
  261. should = "&lt;&gt;"
  262. result = App.Utils.htmlEscape(source)
  263. equal(result, should, source)
  264. source = "<&lt;>"
  265. should = "&lt;&amp;lt;&gt;"
  266. result = App.Utils.htmlEscape(source)
  267. equal(result, should, source)
  268. });
  269. // htmlRemoveTags
  270. test("htmlRemoveTags", function() {
  271. var source = "<div>test</div>"
  272. //var should = "<div>test</div>"
  273. var should = "test"
  274. var result = App.Utils.htmlRemoveTags($(source))
  275. equal(result.html(), should, source)
  276. source = "<div>test<!-- some comment --></div>"
  277. //should = "<div>test</div>"
  278. should = "test"
  279. result = App.Utils.htmlRemoveTags($(source))
  280. equal(result.html(), should, source)
  281. source = "<a href=\"some_link\">some link to somewhere</a>"
  282. should = "some link to somewhere"
  283. result = App.Utils.htmlRemoveTags($(source))
  284. equal(result.html(), should, source)
  285. source = "<div><a href=\"some_link\">some link to somewhere</a></div>"
  286. //should = "<div>some link to somewhere</div>"
  287. should = "some link to somewhere"
  288. result = App.Utils.htmlRemoveTags($(source))
  289. equal(result.html(), should, source)
  290. source = "<div><a href=\"some_link\">some link to somewhere</a><input value=\"should not be shown\"></div>"
  291. //should = "<div>some link to somewhere</div>"
  292. should = "some link to somewhere"
  293. result = App.Utils.htmlRemoveTags($(source))
  294. equal(result.html(), should, source)
  295. source = "<div><a href=\"some_link\">some link to somewhere</a> <div><hr></div> <span>123</span> <img src=\"some_image\"/></div>"
  296. //should = "<div>some link to somewhere 123 </div>"
  297. should = "some link to somewhere 123 "
  298. result = App.Utils.htmlRemoveTags($(source))
  299. equal(result.html(), should, source)
  300. });
  301. // htmlRemoveRichtext
  302. test("htmlRemoveRichtext", function() {
  303. source = "<div><form class=\"xxx\">test 123</form><svg><use xlink:href=\"assets/images/icons.svg#icon-status\"></svg></div>"
  304. //should = "<div>test 123</div>"
  305. should = "test 123"
  306. result = App.Utils.htmlRemoveRichtext($(source))
  307. equal(result.html(), should, source)
  308. source = "<div><textarea class=\"xxx\">test 123</textarea></div>"
  309. //should = "<div>test 123</div>"
  310. should = "test 123"
  311. result = App.Utils.htmlRemoveRichtext($(source))
  312. equal(result.html(), should, source)
  313. source = "<div><p wrap=\"\">test 123</p></div>"
  314. should = "<p>test 123</p>"
  315. result = App.Utils.htmlRemoveRichtext($(source))
  316. equal(result.html(), should, source)
  317. source = "<div><font size=\"3\" color=\"red\">This is some text!</font></div>"
  318. should = "This is some text!"
  319. result = App.Utils.htmlRemoveRichtext($(source))
  320. equal(result.html(), should, source)
  321. should = "This is some text!"
  322. result = App.Utils.htmlRemoveRichtext(source)
  323. equal(result.html(), should, source)
  324. var source = "<div><!--test comment--><a href=\"test\">test</a></div>"
  325. //var should = "<div>test</div>"
  326. var should = "test"
  327. var result = App.Utils.htmlRemoveRichtext($(source))
  328. equal(result.html(), should, source)
  329. source = "<div><!--[if !supportLists]--><span lang=\"DE\">1.1.1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><!--[endif]--><span lang=\"DE\">Description</span></div>"
  330. //should = "<div><span>1.1.1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span>Description</span></div>"
  331. should = "<span>1.1.1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span>Description</span>"
  332. //should = '1.1.1 Description'
  333. result = App.Utils.htmlRemoveRichtext($(source))
  334. equal(result.html(), should, source)
  335. source = "<a href=\"some_link\">some link to somewhere</a>"
  336. should = "some link to somewhere"
  337. result = App.Utils.htmlRemoveRichtext($(source))
  338. equal(result.html(), should, source)
  339. source = "<div><a href=\"some_link\"></a> test </div>"
  340. //should = "<div> test </div>"
  341. should = " test "
  342. result = App.Utils.htmlRemoveRichtext($(source))
  343. equal(result.html(), should, source)
  344. source = "<div><b></b> test </div>"
  345. //should = "<div> test </div>"
  346. should = " test "
  347. result = App.Utils.htmlRemoveRichtext($(source))
  348. equal(result.html(), should, source)
  349. source = "<div><div><b></b> test </div></div>"
  350. //should = "<div><div> test </div></div>"
  351. should = "<div> test </div>"
  352. result = App.Utils.htmlRemoveRichtext($(source))
  353. equal(result.html(), should, source)
  354. source = "<div><div><b></b> test <input value=\"should not be shown\"></div></div>"
  355. //should = "<div><div> test </div></div>"
  356. should = "<div> test </div>"
  357. result = App.Utils.htmlRemoveRichtext($(source))
  358. equal(result.html(), should, source)
  359. source = "<div><div><b></b> test </div><span>123</span></div>"
  360. //should = "<div><div> test </div><span>123</span></div>"
  361. should = "<div> test </div><span>123</span>"
  362. //should = '<div> test </div>123'
  363. result = App.Utils.htmlRemoveRichtext($(source))
  364. equal(result.html(), should, source)
  365. source = "<div><div class=\"xxx\" title=\"some title\" lang=\"en\"><b></b> test </div></div>"
  366. //should = "<div><div> test </div></div>"
  367. should = "<div> test </div>"
  368. result = App.Utils.htmlRemoveRichtext($(source))
  369. equal(result.html(), should, source)
  370. source = "<div><textarea class=\"xxx\"> test </textarea></div>"
  371. //should = "<div> test </div>"
  372. should = " test "
  373. result = App.Utils.htmlRemoveRichtext($(source))
  374. equal(result.html(), should, source)
  375. source = "<div><br></div>"
  376. //should = "<div><br></div>"
  377. should = "<br>"
  378. result = App.Utils.htmlRemoveRichtext($(source))
  379. equal(result.html(), should, source)
  380. source = "<div><div class=\"xxx\"><br></div></div>"
  381. //should = "<div><div><br></div></div>"
  382. should = "<div><br></div>"
  383. result = App.Utils.htmlRemoveRichtext($(source))
  384. equal(result.html(), should, source)
  385. source = "<div><form class=\"xxx\">test 123</form></div>"
  386. //should = "<div>test 123</div>"
  387. should = "test 123"
  388. result = App.Utils.htmlRemoveRichtext($(source))
  389. equal(result.html(), should, source)
  390. source = "<div><div><label for=\"Ticket_888344_group_id\">Gruppe <span>*</span></label></div><div><div></div></div><div><div><span></span><span></span></div></div><div><div><label for=\"Ticket_888344_owner_id\">Besitzer <span></span></label></div><div><div></div></div></div><div><div><div><svg><use xlink:href=\"http://localhost:3000/assets/images/icons.svg#icon-arrow-down\"></use></svg></div><span></span><span></span></div></div><div><div> <label for=\"Ticket_888344_state_id\">Status <span>*</span></label></div></div></div>\n"
  391. //should = "<div>test 123</div>"
  392. should = '<div>Gruppe <span>*</span></div><div><div></div></div><div><div><span></span><span></span></div></div><div><div>Besitzer <span></span></div><div><div></div></div></div><div><div><div></div><span></span><span></span></div></div><div><div> Status <span>*</span></div></div>'
  393. result = App.Utils.htmlRemoveRichtext(source)
  394. equal(result.html(), should, source)
  395. source = "<div><font size=\"3\" color=\"red\">This is some text!</font><svg><use xlink:href=\"assets/images/icons.svg#icon-status\"></svg></div>"
  396. should = "This is some text!"
  397. result = App.Utils.htmlRemoveRichtext($(source))
  398. equal(result.html(), should, source)
  399. should = "This is some text!"
  400. result = App.Utils.htmlRemoveRichtext(source)
  401. equal(result.html(), should, source)
  402. var source = "<div><!--test comment--><a href=\"test\">test</a></div>"
  403. var should = "<div>test</div>"
  404. var result = App.Utils.htmlRemoveRichtext($(source))
  405. equal(result.get(0).outerHTML, should, source)
  406. source = "<div><small>some link to somewhere</small></a>"
  407. should = "<div>some link to somewhere</div>"
  408. result = App.Utils.htmlRemoveRichtext($(source))
  409. equal(result.get(0).outerHTML, should, source)
  410. source = "<div><div class=\"xxx\"><br></div></div>"
  411. should = "<div><div><br></div></div>"
  412. result = App.Utils.htmlRemoveRichtext($(source))
  413. equal(result.get(0).outerHTML, should, source)
  414. source = "<div><table bgcolor=\"green\" aaa=\"1\"><thead><tr><th>111</th><th colspan=\"2\" abc=\"a\">aaa</th></tr></thead><tbody><tr><td>key</td><td>value</td></tr></tbody></table></div>"
  415. should = "<div>111aaakeyvalue</div>"
  416. result = App.Utils.htmlRemoveRichtext(source, true)
  417. equal(result.get(0).outerHTML, should, source)
  418. });
  419. // htmlCleanup
  420. test("htmlCleanup", function() {
  421. var source = "<div><!--test comment--><a href=\"test\">test</a></div>"
  422. //var should = "<div>test</div>"
  423. var should = "<a href=\"test\">test</a>"
  424. var result = App.Utils.htmlCleanup($(source))
  425. equal(result.html(), should, source)
  426. source = "<div><!--test comment--><a href=\"test\">test</a></div>"
  427. should = "<a href=\"test\">test</a>"
  428. result = App.Utils.htmlCleanup(source)
  429. equal(result.html(), should, source)
  430. source = "some link to somewhere"
  431. should = "some link to somewhere"
  432. result = App.Utils.htmlCleanup(source)
  433. equal(result.html(), should, source)
  434. source = "<li>a</li><li>b</li>"
  435. should = "<li>a</li><li>b</li>"
  436. result = App.Utils.htmlCleanup(source)
  437. equal(result.html(), should, source)
  438. source = "<a href=\"some_link\">some link to somewhere</a>"
  439. should = "some link to somewhere"
  440. result = App.Utils.htmlCleanup($(source))
  441. equal(result.html(), should, source)
  442. source = "<p><a href=\"some_link\">some link to somewhere</a><p>"
  443. should = "<a href=\"some_link\">some link to somewhere</a>"
  444. result = App.Utils.htmlCleanup($(source))
  445. equal(result.html(), should, source)
  446. source = "<div><h1>some link to somewhere</h1></div>"
  447. should = "<h1>some link to somewhere</h1>"
  448. result = App.Utils.htmlCleanup($(source))
  449. equal(result.html(), should, source)
  450. source = "<div><p id=\"123\" data-id=\"abc\">some link to somewhere</p></div>"
  451. should = "<p>some link to somewhere</p>"
  452. result = App.Utils.htmlCleanup($(source))
  453. equal(result.html(), should, source)
  454. source = "<div><small>some link to somewhere</small></a>"
  455. //should = "<div>some link to somewhere</div>"
  456. should = "some link to somewhere"
  457. result = App.Utils.htmlCleanup($(source))
  458. equal(result.html(), should, source)
  459. source = "<div><time>some link to somewhere</time></a>"
  460. //should = "<div>some link to somewhere</div>"
  461. should = "some link to somewhere"
  462. result = App.Utils.htmlCleanup($(source))
  463. equal(result.html(), should, source)
  464. source = "<div><h1>some h1 for somewhere</h1><p><hr></p></div>"
  465. should = "<h1>some h1 for somewhere</h1><p></p><hr><p></p>"
  466. result = App.Utils.htmlCleanup($(source))
  467. equal(result.html(), should, source)
  468. source = "<div><br></div>"
  469. //should = "<div><br></div>"
  470. should = "<br>"
  471. result = App.Utils.htmlCleanup($(source))
  472. equal(result.html(), should, source)
  473. source = "<div><div class=\"xxx\"><br></div></div>"
  474. //should = "<div><div><br></div></div>"
  475. should = "<div><br></div>"
  476. result = App.Utils.htmlCleanup($(source))
  477. equal(result.html(), should, source)
  478. source = "<div><form class=\"xxx\">test 123</form></div>"
  479. //should = "<div>test 123<br></div>"
  480. should = "test 123"
  481. result = App.Utils.htmlCleanup($(source))
  482. equal(result.html(), should, source)
  483. source = "<div><form class=\"xxx\">test 123</form> some other value</div>"
  484. //should = "<div>test 123 some other value</div>"
  485. should = "test 123 some other value"
  486. result = App.Utils.htmlCleanup($(source))
  487. equal(result.html(), should, source)
  488. source = "<div><form class=\"xxx\">test 123</form> some other value<input value=\"should not be shown\"></div>"
  489. //should = "<div>test 123 some other value</div>"
  490. should = "test 123 some other value"
  491. result = App.Utils.htmlCleanup($(source))
  492. equal(result.html(), should, source)
  493. source = "<div><font size=\"3\" color=\"red\">This is some text!</font><svg><use xlink:href=\"assets/images/icons.svg#icon-status\"></svg></div>"
  494. //should = "<div>This is some text!</div>"
  495. should = "This is some text!"
  496. result = App.Utils.htmlCleanup($(source))
  497. equal(result.html(), should, source)
  498. source = "<div><p>some link to somewhere from word<w:sdt>abc</w:sdt></p><o:p></o:p></a>"
  499. //should = "<div><p>some link to somewhere from wordabc</p></div>"
  500. should = '<p>some link to somewhere from wordabc</p>'
  501. result = App.Utils.htmlCleanup($(source))
  502. equal(result.html(), should, source)
  503. source = "<div><div><label for=\"Ticket_888344_group_id\">Gruppe <span>*</span></label></div><div><div></div></div><div><div><span></span><span></span></div></div><div><div><label for=\"Ticket_888344_owner_id\">Besitzer <span></span></label></div><div><div></div></div></div><div><div><div><svg><use xlink:href=\"http://localhost:3000/assets/images/icons.svg#icon-arrow-down\"></use></svg></div><span></span><span></span></div></div><div><div> <label for=\"Ticket_888344_state_id\">Status <span>*</span></label></div></div></div>\n"
  504. //should = "<div>test 123</div>"
  505. should = '<div>Gruppe <span>*</span></div><div><div></div></div><div><div><span></span><span></span></div></div><div><div>Besitzer <span></span></div><div><div></div></div></div><div><div><div></div><span></span><span></span></div></div><div><div> Status <span>*</span></div></div>'
  506. result = App.Utils.htmlCleanup(source)
  507. equal(result.html(), should, source)
  508. source = "<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\nxmlns:w=\"urn:schemas-microsoft-com:office:word\"\nxmlns:m=\"http://schemas.microsoft.com/office/2004/12/omml\"\nxmlns=\"http://www.w3.org/TR/REC-html40\">\n\n<head>\n<meta name=Titel content=\"\">\n<meta name=Stichwörter content=\"\">\n<meta http-equiv=Content-Type content=\"text/html; charset=utf-8\">\n<meta name=ProgId content=Word.Document>\n<meta name=Generator content=\"Microsoft Word 15\">\n<meta name=Originator content=\"Microsoft Word 15\">\n<link rel=File-List\nhref=\"file://localhost/Users/johannes/Library/Group%20Containers/UBF8T346G9.Office/msoclip1/01/clip_filelist.xml\">\n<!--[if gte mso 9]><xml>\n <o:OfficeDocumentSettings>\n <o:AllowPNG/>\n <o:PixelsPerInch>96</o:PixelsPerInch>\n </o:OfficeDocumentSettings>\n</xml><![endif]-->\n<link rel=themeData\nhref=\"file://localhost/Users/johannes/Library/Group%20Containers/UBF8T346G9.Office/msoclip1/01/clip_themedata.thmx\">\n<!--[if gte mso 9]><xml>\n <w:WordDocument>\n <w:View>Normal</w:View>\n <w:Zoom>0</w:Zoom>\n <w:TrackMoves/>\n <w:TrackFormatting/>\n <w:HyphenationZone>21</w:HyphenationZone>\n <w:PunctuationKerning/>\n <w:ValidateAgainstSchemas/>\n <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>\n <w:IgnoreMixedContent>false</w:IgnoreMixedContent>\n <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>\n <w:DoNotPromoteQF/>\n <w:LidThemeOther>DE</w:LidThemeOther>\n <w:LidThemeAsian>X-NONE</w:LidThemeAsian>\n <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>\n <w:Compatibility>\n <w:BreakWrappedTables/>\n <w:SnapToGridInCell/>\n <w:WrapTextWithPunct/>\n <w:UseAsianBreakRules/>\n <w:DontGrowAutofit/>\n <w:SplitPgBreakAndParaMark/>\n <w:EnableOpenTypeKerning/>\n <w:DontFlipMirrorIndents/>\n <w:OverrideTableStyleHps/>\n </w:Compatibility>\n <m:mathPr>\n <m:mathFont m:val=\"Cambria Math\"/>\n <m:brkBin m:val=\"before\"/>\n <m:brkBinSub m:val=\"&#45;-\"/>\n <m:smallFrac m:val=\"off\"/>\n <m:dispDef/>\n <m:lMargin m:val=\"0\"/>\n <m:rMargin m:val=\"0\"/>\n <m:defJc m:val=\"centerGroup\"/>\n <m:wrapIndent m:val=\"1440\"/>\n <m:intLim m:val=\"subSup\"/>\n <m:naryLim m:val=\"undOvr\"/>\n </m:mathPr></w:WordDocument>\n</xml><![endif]--><!--[if gte mso 9]><xml>\n <w:LatentStyles DefLockedState=\"false\" DefUnhideWhenUsed=\"false\"\n DefSemiHidden=\"false\" DefQFormat=\"false\" DefPriority=\"99\"\n LatentStyleCount=\"380\">\n <w:LsdException Locked=\"false\" Priority=\"0\" QFormat=\"true\" Name=\"Normal\"/>\n <w:LsdException Locked=\"false\" Priority=\"0\" QFormat=\"true\" Name=\"heading 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"0\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" QFormat=\"true\" Name=\"heading 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"0\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" QFormat=\"true\" Name=\"heading 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"0\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" QFormat=\"true\" Name=\"heading 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"0\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" QFormat=\"true\" Name=\"heading 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"9\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" QFormat=\"true\" Name=\"heading 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"9\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" QFormat=\"true\" Name=\"heading 7\"/>\n <w:LsdException Locked=\"false\" Priority=\"9\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" QFormat=\"true\" Name=\"heading 8\"/>\n <w:LsdException Locked=\"false\" Priority=\"9\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" QFormat=\"true\" Name=\"heading 9\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"index 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"index 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"index 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"index 4\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"index 5\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"index 6\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"index 7\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"index 8\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"index 9\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"toc 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"toc 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"toc 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"toc 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"toc 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"toc 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"toc 7\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"toc 8\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"toc 9\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Normal Indent\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"footnote text\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"annotation text\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"header\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"footer\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"index heading\"/>\n <w:LsdException Locked=\"false\" Priority=\"35\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" QFormat=\"true\" Name=\"caption\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"table of figures\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"envelope address\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"envelope return\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"footnote reference\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"annotation reference\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"line number\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"page number\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"endnote reference\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"endnote text\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"table of authorities\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"macro\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"toa heading\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Bullet\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Number\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List 4\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List 5\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Bullet 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Bullet 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Bullet 4\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Bullet 5\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Number 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Number 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Number 4\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Number 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"10\" QFormat=\"true\" Name=\"Title\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Closing\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Signature\"/>\n <w:LsdException Locked=\"false\" Priority=\"1\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"Default Paragraph Font\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Body Text\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Body Text Indent\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Continue\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Continue 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Continue 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Continue 4\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"List Continue 5\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Message Header\"/>\n <w:LsdException Locked=\"false\" Priority=\"11\" QFormat=\"true\" Name=\"Subtitle\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Salutation\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Date\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Body Text First Indent\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Body Text First Indent 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Note Heading\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Body Text 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Body Text 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Body Text Indent 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Body Text Indent 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Block Text\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Hyperlink\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"FollowedHyperlink\"/>\n <w:LsdException Locked=\"false\" Priority=\"22\" QFormat=\"true\" Name=\"Strong\"/>\n <w:LsdException Locked=\"false\" Priority=\"20\" QFormat=\"true\" Name=\"Emphasis\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Document Map\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Plain Text\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"E-mail Signature\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Top of Form\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Bottom of Form\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Normal (Web)\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Acronym\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Address\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Cite\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Code\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Definition\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Keyboard\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Preformatted\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Sample\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Typewriter\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"HTML Variable\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Normal Table\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"annotation subject\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"No List\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Outline List 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Outline List 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Outline List 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Simple 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Simple 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Simple 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Classic 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Classic 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Classic 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Classic 4\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Colorful 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Colorful 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Colorful 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Columns 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Columns 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Columns 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Columns 4\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Columns 5\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Grid 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Grid 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Grid 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Grid 4\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Grid 5\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Grid 6\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Grid 7\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Grid 8\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table List 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table List 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table List 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table List 4\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table List 5\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table List 6\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table List 7\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table List 8\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table 3D effects 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table 3D effects 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table 3D effects 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Contemporary\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Elegant\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Professional\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Subtle 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Subtle 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Web 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Web 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Web 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Balloon Text\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" Name=\"Table Grid\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Table Theme\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Note Level 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Note Level 2\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Note Level 3\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Note Level 4\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Note Level 5\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Note Level 6\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Note Level 7\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Note Level 8\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" UnhideWhenUsed=\"true\"\n Name=\"Note Level 9\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" Name=\"Placeholder Text\"/>\n <w:LsdException Locked=\"false\" Priority=\"1\" QFormat=\"true\" Name=\"No Spacing\"/>\n <w:LsdException Locked=\"false\" Priority=\"60\" Name=\"Light Shading\"/>\n <w:LsdException Locked=\"false\" Priority=\"61\" Name=\"Light List\"/>\n <w:LsdException Locked=\"false\" Priority=\"62\" Name=\"Light Grid\"/>\n <w:LsdException Locked=\"false\" Priority=\"63\" Name=\"Medium Shading 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"64\" Name=\"Medium Shading 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"65\" Name=\"Medium List 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"66\" Name=\"Medium List 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"67\" Name=\"Medium Grid 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"68\" Name=\"Medium Grid 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"69\" Name=\"Medium Grid 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"70\" Name=\"Dark List\"/>\n <w:LsdException Locked=\"false\" Priority=\"71\" Name=\"Colorful Shading\"/>\n <w:LsdException Locked=\"false\" Priority=\"72\" Name=\"Colorful List\"/>\n <w:LsdException Locked=\"false\" Priority=\"73\" Name=\"Colorful Grid\"/>\n <w:LsdException Locked=\"false\" Priority=\"60\" Name=\"Light Shading Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"61\" Name=\"Light List Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"62\" Name=\"Light Grid Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"63\" Name=\"Medium Shading 1 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"64\" Name=\"Medium Shading 2 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"65\" Name=\"Medium List 1 Accent 1\"/>\n <w:LsdException Locked=\"false\" SemiHidden=\"true\" Name=\"Revision\"/>\n <w:LsdException Locked=\"false\" Priority=\"34\" QFormat=\"true\"\n Name=\"List Paragraph\"/>\n <w:LsdException Locked=\"false\" Priority=\"29\" QFormat=\"true\" Name=\"Quote\"/>\n <w:LsdException Locked=\"false\" Priority=\"30\" QFormat=\"true\"\n Name=\"Intense Quote\"/>\n <w:LsdException Locked=\"false\" Priority=\"66\" Name=\"Medium List 2 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"67\" Name=\"Medium Grid 1 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"68\" Name=\"Medium Grid 2 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"69\" Name=\"Medium Grid 3 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"70\" Name=\"Dark List Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"71\" Name=\"Colorful Shading Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"72\" Name=\"Colorful List Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"73\" Name=\"Colorful Grid Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"60\" Name=\"Light Shading Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"61\" Name=\"Light List Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"62\" Name=\"Light Grid Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"63\" Name=\"Medium Shading 1 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"64\" Name=\"Medium Shading 2 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"65\" Name=\"Medium List 1 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"66\" Name=\"Medium List 2 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"67\" Name=\"Medium Grid 1 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"68\" Name=\"Medium Grid 2 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"69\" Name=\"Medium Grid 3 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"70\" Name=\"Dark List Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"71\" Name=\"Colorful Shading Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"72\" Name=\"Colorful List Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"73\" Name=\"Colorful Grid Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"60\" Name=\"Light Shading Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"61\" Name=\"Light List Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"62\" Name=\"Light Grid Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"63\" Name=\"Medium Shading 1 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"64\" Name=\"Medium Shading 2 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"65\" Name=\"Medium List 1 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"66\" Name=\"Medium List 2 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"67\" Name=\"Medium Grid 1 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"68\" Name=\"Medium Grid 2 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"69\" Name=\"Medium Grid 3 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"70\" Name=\"Dark List Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"71\" Name=\"Colorful Shading Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"72\" Name=\"Colorful List Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"73\" Name=\"Colorful Grid Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"60\" Name=\"Light Shading Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"61\" Name=\"Light List Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"62\" Name=\"Light Grid Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"63\" Name=\"Medium Shading 1 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"64\" Name=\"Medium Shading 2 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"65\" Name=\"Medium List 1 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"66\" Name=\"Medium List 2 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"67\" Name=\"Medium Grid 1 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"68\" Name=\"Medium Grid 2 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"69\" Name=\"Medium Grid 3 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"70\" Name=\"Dark List Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"71\" Name=\"Colorful Shading Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"72\" Name=\"Colorful List Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"73\" Name=\"Colorful Grid Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"60\" Name=\"Light Shading Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"61\" Name=\"Light List Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"62\" Name=\"Light Grid Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"63\" Name=\"Medium Shading 1 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"64\" Name=\"Medium Shading 2 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"65\" Name=\"Medium List 1 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"66\" Name=\"Medium List 2 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"67\" Name=\"Medium Grid 1 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"68\" Name=\"Medium Grid 2 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"69\" Name=\"Medium Grid 3 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"70\" Name=\"Dark List Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"71\" Name=\"Colorful Shading Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"72\" Name=\"Colorful List Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"73\" Name=\"Colorful Grid Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"60\" Name=\"Light Shading Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"61\" Name=\"Light List Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"62\" Name=\"Light Grid Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"63\" Name=\"Medium Shading 1 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"64\" Name=\"Medium Shading 2 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"65\" Name=\"Medium List 1 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"66\" Name=\"Medium List 2 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"67\" Name=\"Medium Grid 1 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"68\" Name=\"Medium Grid 2 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"69\" Name=\"Medium Grid 3 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"70\" Name=\"Dark List Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"71\" Name=\"Colorful Shading Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"72\" Name=\"Colorful List Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"73\" Name=\"Colorful Grid Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"19\" QFormat=\"true\"\n Name=\"Subtle Emphasis\"/>\n <w:LsdException Locked=\"false\" Priority=\"21\" QFormat=\"true\"\n Name=\"Intense Emphasis\"/>\n <w:LsdException Locked=\"false\" Priority=\"31\" QFormat=\"true\"\n Name=\"Subtle Reference\"/>\n <w:LsdException Locked=\"false\" Priority=\"32\" QFormat=\"true\"\n Name=\"Intense Reference\"/>\n <w:LsdException Locked=\"false\" Priority=\"33\" QFormat=\"true\" Name=\"Book Title\"/>\n <w:LsdException Locked=\"false\" Priority=\"37\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" Name=\"Bibliography\"/>\n <w:LsdException Locked=\"false\" Priority=\"39\" SemiHidden=\"true\"\n UnhideWhenUsed=\"true\" QFormat=\"true\" Name=\"TOC Heading\"/>\n <w:LsdException Locked=\"false\" Priority=\"41\" Name=\"Plain Table 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"42\" Name=\"Plain Table 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"43\" Name=\"Plain Table 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"44\" Name=\"Plain Table 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"45\" Name=\"Plain Table 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"40\" Name=\"Grid Table Light\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\" Name=\"Grid Table 1 Light\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"Grid Table 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"Grid Table 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"Grid Table 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"Grid Table 5 Dark\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\" Name=\"Grid Table 6 Colorful\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\" Name=\"Grid Table 7 Colorful\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"Grid Table 1 Light Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"Grid Table 2 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"Grid Table 3 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"Grid Table 4 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"Grid Table 5 Dark Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"Grid Table 6 Colorful Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"Grid Table 7 Colorful Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"Grid Table 1 Light Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"Grid Table 2 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"Grid Table 3 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"Grid Table 4 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"Grid Table 5 Dark Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"Grid Table 6 Colorful Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"Grid Table 7 Colorful Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"Grid Table 1 Light Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"Grid Table 2 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"Grid Table 3 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"Grid Table 4 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"Grid Table 5 Dark Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"Grid Table 6 Colorful Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"Grid Table 7 Colorful Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"Grid Table 1 Light Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"Grid Table 2 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"Grid Table 3 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"Grid Table 4 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"Grid Table 5 Dark Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"Grid Table 6 Colorful Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"Grid Table 7 Colorful Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"Grid Table 1 Light Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"Grid Table 2 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"Grid Table 3 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"Grid Table 4 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"Grid Table 5 Dark Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"Grid Table 6 Colorful Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"Grid Table 7 Colorful Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"Grid Table 1 Light Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"Grid Table 2 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"Grid Table 3 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"Grid Table 4 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"Grid Table 5 Dark Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"Grid Table 6 Colorful Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"Grid Table 7 Colorful Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\" Name=\"List Table 1 Light\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"List Table 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"List Table 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"List Table 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"List Table 5 Dark\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\" Name=\"List Table 6 Colorful\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\" Name=\"List Table 7 Colorful\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"List Table 1 Light Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"List Table 2 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"List Table 3 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"List Table 4 Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"List Table 5 Dark Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"List Table 6 Colorful Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"List Table 7 Colorful Accent 1\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"List Table 1 Light Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"List Table 2 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"List Table 3 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"List Table 4 Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"List Table 5 Dark Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"List Table 6 Colorful Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"List Table 7 Colorful Accent 2\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"List Table 1 Light Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"List Table 2 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"List Table 3 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"List Table 4 Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"List Table 5 Dark Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"List Table 6 Colorful Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"List Table 7 Colorful Accent 3\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"List Table 1 Light Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"List Table 2 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"List Table 3 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"List Table 4 Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"List Table 5 Dark Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"List Table 6 Colorful Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"List Table 7 Colorful Accent 4\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"List Table 1 Light Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"List Table 2 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"List Table 3 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"List Table 4 Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"List Table 5 Dark Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"List Table 6 Colorful Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"List Table 7 Colorful Accent 5\"/>\n <w:LsdException Locked=\"false\" Priority=\"46\"\n Name=\"List Table 1 Light Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"47\" Name=\"List Table 2 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"48\" Name=\"List Table 3 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"49\" Name=\"List Table 4 Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"50\" Name=\"List Table 5 Dark Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"51\"\n Name=\"List Table 6 Colorful Accent 6\"/>\n <w:LsdException Locked=\"false\" Priority=\"52\"\n Name=\"List Table 7 Colorful Accent 6\"/>\n </w:LatentStyles>\n</xml><![endif]-->\n<style>\n<!--\n /* Font Definitions */\n@font-face\n {font-family:\"Courier New\";\n panose-1:2 7 3 9 2 2 5 2 4 4;\n mso-font-charset:0;\n mso-generic-font-family:auto;\n mso-font-pitch:variable;\n mso-font-signature:-536859905 -1073711037 9 0 511 0;}\n@font-face\n {font-family:Wingdings;\n panose-1:5 0 0 0 0 0 0 0 0 0;\n mso-font-charset:2;\n mso-generic-font-family:auto;\n mso-font-pitch:variable;\n mso-font-signature:0 268435456 0 0 -2147483648 0;}\n@font-face\n {font-family:\"Cambria Math\";\n panose-1:2 4 5 3 5 4 6 3 2 4;\n mso-font-charset:0;\n mso-generic-font-family:auto;\n mso-font-pitch:variable;\n mso-font-signature:-536870145 1107305727 0 0 415 0;}\n@font-face\n {font-family:Calibri;\n panose-1:2 15 5 2 2 2 4 3 2 4;\n mso-font-charset:0;\n mso-generic-font-family:auto;\n mso-font-pitch:variable;\n mso-font-signature:-536870145 1073786111 1 0 415 0;}\n /* Style Definitions */\np.MsoNormal, li.MsoNormal, div.MsoNormal\n {mso-style-unhide:no;\n mso-style-qformat:yes;\n mso-style-parent:\"\";\n margin:0cm;\n margin-bottom:.0001pt;\n mso-pagination:widow-orphan;\n font-size:12.0pt;\n font-family:Calibri;\n mso-ascii-font-family:Calibri;\n mso-ascii-theme-font:minor-latin;\n mso-fareast-font-family:Calibri;\n mso-fareast-theme-font:minor-latin;\n mso-hansi-font-family:Calibri;\n mso-hansi-theme-font:minor-latin;\n mso-bidi-font-family:\"Times New Roman\";\n mso-bidi-theme-font:minor-bidi;\n mso-fareast-language:EN-US;}\np.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph\n {mso-style-priority:34;\n mso-style-unhide:no;\n mso-style-qformat:yes;\n margin-top:0cm;\n margin-right:0cm;\n margin-bottom:0cm;\n margin-left:36.0pt;\n margin-bottom:.0001pt;\n mso-add-space:auto;\n mso-pagination:widow-orphan;\n font-size:12.0pt;\n font-family:Calibri;\n mso-ascii-font-family:Calibri;\n mso-ascii-theme-font:minor-latin;\n mso-fareast-font-family:Calibri;\n mso-fareast-theme-font:minor-latin;\n mso-hansi-font-family:Calibri;\n mso-hansi-theme-font:minor-latin;\n mso-bidi-font-family:\"Times New Roman\";\n mso-bidi-theme-font:minor-bidi;\n mso-fareast-language:EN-US;}\np.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParagraphCxSpFirst\n {mso-style-priority:34;\n mso-style-unhide:no;\n mso-style-qformat:yes;\n mso-style-type:export-only;\n margin-top:0cm;\n margin-right:0cm;\n margin-bottom:0cm;\n margin-left:36.0pt;\n margin-bottom:.0001pt;\n mso-add-space:auto;\n mso-pagination:widow-orphan;\n font-size:12.0pt;\n font-family:Calibri;\n mso-ascii-font-family:Calibri;\n mso-ascii-theme-font:minor-latin;\n mso-fareast-font-family:Calibri;\n mso-fareast-theme-font:minor-latin;\n mso-hansi-font-family:Calibri;\n mso-hansi-theme-font:minor-latin;\n mso-bidi-font-family:\"Times New Roman\";\n mso-bidi-theme-font:minor-bidi;\n mso-fareast-language:EN-US;}\np.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListParagraphCxSpMiddle\n {mso-style-priority:34;\n mso-style-unhide:no;\n mso-style-qformat:yes;\n mso-style-type:export-only;\n margin-top:0cm;\n margin-right:0cm;\n margin-bottom:0cm;\n margin-left:36.0pt;\n margin-bottom:.0001pt;\n mso-add-space:auto;\n mso-pagination:widow-orphan;\n font-size:12.0pt;\n font-family:Calibri;\n mso-ascii-font-family:Calibri;\n mso-ascii-theme-font:minor-latin;\n mso-fareast-font-family:Calibri;\n mso-fareast-theme-font:minor-latin;\n mso-hansi-font-family:Calibri;\n mso-hansi-theme-font:minor-latin;\n mso-bidi-font-family:\"Times New Roman\";\n mso-bidi-theme-font:minor-bidi;\n mso-fareast-language:EN-US;}\np.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagraphCxSpLast\n {mso-style-priority:34;\n mso-style-unhide:no;\n mso-style-qformat:yes;\n mso-style-type:export-only;\n margin-top:0cm;\n margin-right:0cm;\n margin-bottom:0cm;\n margin-left:36.0pt;\n margin-bottom:.0001pt;\n mso-add-space:auto;\n mso-pagination:widow-orphan;\n font-size:12.0pt;\n font-family:Calibri;\n mso-ascii-font-family:Calibri;\n mso-ascii-theme-font:minor-latin;\n mso-fareast-font-family:Calibri;\n mso-fareast-theme-font:minor-latin;\n mso-hansi-font-family:Calibri;\n mso-hansi-theme-font:minor-latin;\n mso-bidi-font-family:\"Times New Roman\";\n mso-bidi-theme-font:minor-bidi;\n mso-fareast-language:EN-US;}\n.MsoChpDefault\n {mso-style-type:export-only;\n mso-default-props:yes;\n font-family:Calibri;\n mso-ascii-font-family:Calibri;\n mso-ascii-theme-font:minor-latin;\n mso-fareast-font-family:Calibri;\n mso-fareast-theme-font:minor-latin;\n mso-hansi-font-family:Calibri;\n mso-hansi-theme-font:minor-latin;\n mso-bidi-font-family:\"Times New Roman\";\n mso-bidi-theme-font:minor-bidi;\n mso-fareast-language:EN-US;}\n@page WordSection1\n {size:595.0pt 842.0pt;\n margin:70.85pt 70.85pt 2.0cm 70.85pt;\n mso-header-margin:35.4pt;\n mso-footer-margin:35.4pt;\n mso-paper-source:0;}\ndiv.WordSection1\n {page:WordSection1;}\n /* List Definitions */\n@list l0\n {mso-list-id:240799396;\n mso-list-type:hybrid;\n mso-list-template-ids:1377200210 67567617 67567619 67567621 67567617 67567619 67567621 67567617 67567619 67567621;}\n@list l0:level1\n {mso-level-number-format:bullet;\n mso-level-text:;\n mso-level-tab-stop:none;\n mso-level-number-position:left;\n text-indent:-18.0pt;\n font-family:Symbol;}\n@list l0:level2\n {mso-level-number-format:bullet;\n mso-level-text:o;\n mso-level-tab-stop:none;\n mso-level-number-position:left;\n text-indent:-18.0pt;\n font-family:\"Courier New\";}\n@list l0:level3\n {mso-level-number-format:bullet;\n mso-level-text:;\n mso-level-tab-stop:none;\n mso-level-number-position:left;\n text-indent:-18.0pt;\n font-family:Wingdings;}\n@list l0:level4\n {mso-level-number-format:bullet;\n mso-level-text:;\n mso-level-tab-stop:none;\n mso-level-number-position:left;\n text-indent:-18.0pt;\n font-family:Symbol;}\n@list l0:level5\n {mso-level-number-format:bullet;\n mso-level-text:o;\n mso-level-tab-stop:none;\n mso-level-number-position:left;\n text-indent:-18.0pt;\n font-family:\"Courier New\";}\n@list l0:level6\n {mso-level-number-format:bullet;\n mso-level-text:;\n mso-level-tab-stop:none;\n mso-level-number-position:left;\n text-indent:-18.0pt;\n font-family:Wingdings;}\n@list l0:level7\n {mso-level-number-format:bullet;\n mso-level-text:;\n mso-level-tab-stop:none;\n mso-level-number-position:left;\n text-indent:-18.0pt;\n font-family:Symbol;}\n@list l0:level8\n {mso-level-number-format:bullet;\n mso-level-text:o;\n mso-level-tab-stop:none;\n mso-level-number-position:left;\n text-indent:-18.0pt;\n font-family:\"Courier New\";}\n@list l0:level9\n {mso-level-number-format:bullet;\n mso-level-text:;\n mso-level-tab-stop:none;\n mso-level-number-position:left;\n text-indent:-18.0pt;\n font-family:Wingdings;}\nol\n {margin-bottom:0cm;}\nul\n {margin-bottom:0cm;}\n-->\n</style>\n<!--[if gte mso 10]>\n<style>\n /* Style Definitions */\ntable.MsoNormalTable\n {mso-style-name:\"Normale Tabelle\";\n mso-tstyle-rowband-size:0;\n mso-tstyle-colband-size:0;\n mso-style-noshow:yes;\n mso-style-priority:99;\n mso-style-parent:\"\";\n mso-padding-alt:0cm 5.4pt 0cm 5.4pt;\n mso-para-margin:0cm;\n mso-para-margin-bottom:.0001pt;\n mso-pagination:widow-orphan;\n font-size:12.0pt;\n font-family:Calibri;\n mso-ascii-font-family:Calibri;\n mso-ascii-theme-font:minor-latin;\n mso-hansi-font-family:Calibri;\n mso-hansi-theme-font:minor-latin;\n mso-fareast-language:EN-US;}\n</style>\n<![endif]-->\n</head>\n\n<body bgcolor=white lang=DE style='tab-interval:35.4pt'>\n<!--StartFragment-->\n\n<p class=MsoListParagraphCxSpFirst style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span\nstyle='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:\nSymbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt \"Times New Roman\"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n</span></span></span><![endif]>Test 1<o:p></o:p></p>\n\n<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span\nstyle='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:\nSymbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt \"Times New Roman\"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n</span></span></span><![endif]>Test 2<o:p></o:p></p>\n\n<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span\nstyle='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:\nSymbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt \"Times New Roman\"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n</span></span></span><![endif]><i style='mso-bidi-font-style:normal'>Test 3<o:p></o:p></i></p>\n\n<p class=MsoListParagraphCxSpMiddle style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span\nstyle='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:\nSymbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt \"Times New Roman\"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n</span></span></span><![endif]>Test 4<o:p></o:p></p>\n\n<p class=MsoListParagraphCxSpLast style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span\nstyle='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:\nSymbol'><span style='mso-list:Ignore'>·<span style='font:7.0pt \"Times New Roman\"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n</span></span></span><![endif]><b style='mso-bidi-font-weight:normal'>Test5<o:p></o:p></b></p>\n\n<!--EndFragment-->\n</body>\n\n</html>"
  509. should = "<ul><li>Test 1</li><li>Test 2</li><li><i>Test 3</i></li><li>Test 4</li><li><b>Test5</b></li></ul>"
  510. result = App.Utils.htmlCleanup(source)
  511. equal(result.html().trim(), should, source)
  512. source = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n<html>\n<head>\n <meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/>\n <title></title>\n <meta name=\"generator\" content=\"LibreOffice 4.4.7.2 (MacOSX)\"/>\n <style type=\"text/css\">\n @page { margin: 0.79in }\n p { margin-bottom: 0.1in; line-height: 120% }\n a:link { so-language: zxx }\n </style>\n</head>\n<body lang=\"en-US\" dir=\"ltr\">\n<p align=\"center\" style=\"margin-bottom: 0in; line-height: 100%\">1.\nGehe a<b>uf </b><b>https://www.pfe</b>rdiathek.ge</p>\n<p align=\"center\" style=\"margin-bottom: 0in; line-height: 100%\"><br/>\n\n</p>\n<p align=\"center\" style=\"margin-bottom: 0in; line-height: 100%\">2.\nMel<font color=\"#800000\">de Dich mit folgende</font> Zugangsdaten an:</p>\n<p align=\"center\" style=\"margin-bottom: 0in; line-height: 100%\">Benutzer:\nme@xxx.net</p>\n<p align=\"center\" style=\"margin-bottom: 0in; line-height: 100%\">Passwort:\nxxx.</p>\n</body>\n</html>"
  513. should = "\n\n\n \n \n \n \n\n\n<p>1.\nGehe a<b>uf </b><b>https://www.pfe</b>rdiathek.ge</p>\n<p><br>\n\n</p>\n<p>2.\nMelde Dich mit folgende Zugangsdaten an:</p>\n<p>Benutzer:\nme@xxx.net</p>\n<p>Passwort:\nxxx.</p>\n\n"
  514. result = App.Utils.htmlCleanup(source)
  515. equal(result.html(), should, source)
  516. source = "<table bgcolor=\"green\" aaa=\"1\"><thead><tr><th colspan=\"2\" abc=\"a\">aaa</th></tr></thead><tbody><tr><td>value</td></tr></tbody></table>"
  517. should = "<table bgcolor=\"green\"><thead><tr><th colspan=\"2\">aaa</th></tr></thead><tbody><tr><td>value</td></tr></tbody></table>"
  518. result = App.Utils.htmlCleanup(source)
  519. equal(result.get(0).outerHTML, should, source)
  520. // strip out browser-inserted (broken) link (see https://github.com/zammad/zammad/issues/2019)
  521. source = "<div><a href=\"https://example.com/#{config.http_type}://#{config.fqdn}/#ticket/zoom/#{ticket.id}\">test</a></div>"
  522. should = "<a href=\"#{config.http_type}://#{config.fqdn}/#ticket/zoom/#{ticket.id}\">test</a>"
  523. result = App.Utils.htmlCleanup(source)
  524. equal(result.html(), should, source)
  525. source = "<table bgcolor=\"green\" aaa=\"1\" style=\"color: red\"><thead><tr style=\"margin-top: 10px\"><th colspan=\"2\" abc=\"a\" style=\"margin-top: 12px\">aaa</th></tr></thead><tbody><tr><td>value</td></tr></tbody></table>"
  526. should = "<table bgcolor=\"green\" style=\"color:red;\"><thead><tr style=\"margin-top:10px;\"><th colspan=\"2\" style=\"margin-top:12px;\">aaa</th></tr></thead><tbody><tr><td>value</td></tr></tbody></table>"
  527. result = App.Utils.htmlCleanup(source)
  528. result.get(0).outerHTML
  529. //equal(result.get(0).outerHTML, should, source) / string order is different on browsers
  530. equal(result.first().attr('bgcolor'), 'green')
  531. equal(result.first().attr('style'), 'color:red;')
  532. equal(result.first().attr('aaa'), undefined)
  533. equal(result.find('tr').first().attr('style'), 'margin-top:10px;')
  534. equal(result.find('th').first().attr('colspan'), '2')
  535. equal(result.find('th').first().attr('abc'), undefined)
  536. equal(result.find('th').first().attr('style'), 'margin-top:12px;')
  537. source = "<table bgcolor=\"green\" aaa=\"1\" style=\"color:red; display: none;\"><thead><tr><th colspan=\"2\" abc=\"a\">aaa</th></tr></thead><tbody><tr><td>value</td></tr></tbody></table>"
  538. should = "<table bgcolor=\"green\" style=\"color:red;\"><thead><tr><th colspan=\"2\">aaa</th></tr></thead><tbody><tr><td>value</td></tr></tbody></table>"
  539. result = App.Utils.htmlCleanup(source)
  540. //equal(result.get(0).outerHTML, should, source) / string order is different on browsers
  541. equal(result.first().attr('bgcolor'), 'green')
  542. equal(result.first().attr('style'), 'color:red;')
  543. equal(result.first().attr('aaa'), undefined)
  544. equal(result.find('tr').first().attr('style'), undefined)
  545. equal(result.find('th').first().attr('colspan'), '2')
  546. equal(result.find('th').first().attr('abc'), undefined)
  547. equal(result.find('th').first().attr('style'), undefined)
  548. });
  549. // wrap
  550. test("wrap", function() {
  551. var source = "some text"
  552. var should = 'some text'
  553. var result = App.Utils.wrap(source)
  554. equal(result, should, source)
  555. source = "some text\nsome other text\n"
  556. should = "some text\nsome other text\n"
  557. result = App.Utils.wrap(source)
  558. equal(result, should, source)
  559. source = "some text with some line to wrap"
  560. should = "some text with\nsome line to\nwrap"
  561. result = App.Utils.wrap(source, 14)
  562. equal(result, should, source)
  563. source = "some text\nsome other text\n"
  564. should = "some text\nsome other text\n"
  565. result = App.Utils.wrap(source)
  566. equal(result, should, source)
  567. source = "1234567890 1234567890 1234567890 1234567890"
  568. should = "1234567890 1234567890 1234567890 1234567890"
  569. result = App.Utils.wrap(source)
  570. equal(result, should, source)
  571. source = "123456789012 123456789012 123456789012"
  572. should = "123456789012\n123456789012\n123456789012"
  573. result = App.Utils.wrap(source, 14)
  574. equal(result, should, source)
  575. });
  576. // remove empty lines
  577. test("remove empty lines", function() {
  578. var source = "\ntest 123\n"
  579. var should = "test 123\n"
  580. var result = App.Utils.removeEmptyLines(source)
  581. equal(result, should, source)
  582. source = "\ntest\n\n123\n"
  583. should = "test\n123\n"
  584. result = App.Utils.removeEmptyLines(source)
  585. equal(result, should, source)
  586. });
  587. // quote
  588. test("quote", function() {
  589. var source = "some text"
  590. var should = '> some text'
  591. var result = App.Utils.quote(source)
  592. equal(result, should, source)
  593. source = "some text\nsome other text\n"
  594. should = "> some text\n> some other text"
  595. result = App.Utils.quote(source)
  596. equal(result, should, source)
  597. source = "\n\nsome text\nsome other text\n \n"
  598. should = "> some text\n> some other text"
  599. result = App.Utils.quote(source)
  600. equal(result, should, source)
  601. source = "Welcome!\n\nThank you for installing Zammad.\n\nYou will find ..."
  602. should = "> Welcome!\n>\n> Thank you for installing Zammad.\n>\n> You will find ..."
  603. result = App.Utils.quote(source)
  604. equal(result, should, source)
  605. source = "Welcome! Thank you for installing Zammad. You will find ..."
  606. should = "> Welcome! Thank you\n> for installing\n> Zammad. You will\n> find ..."
  607. result = App.Utils.quote(source, 20)
  608. equal(result, should, source)
  609. });
  610. // check signature
  611. test("check signature", function() {
  612. var message = "<div>test 123 </div>"
  613. var signature = '<div>--<br>Some Signature<br>some department</div>'
  614. var result = App.Utils.signatureCheck(message, signature)
  615. equal(result, true)
  616. message = "<div>test 123 <div>--<br>Some Signature<br>some department\n</div></div>"
  617. signature = '<div>--<br>Some Signature<br>some department</div>'
  618. result = App.Utils.signatureCheck(message, signature)
  619. equal(result, false)
  620. message = "<div>test 123 <div>--<br>Some Signature\n<br>some department\n</div></div>"
  621. signature = '<div>--<br>Some Signature<br>some department</div>'
  622. result = App.Utils.signatureCheck(message, signature)
  623. equal(result, false)
  624. message = "<div>test 123 <div>--<p>Some Signature</p>\n<p><div>some department</div>\n</p>\n</div></div>"
  625. signature = '<div>--<br>Some Signature<br>some department</div>'
  626. result = App.Utils.signatureCheck(message, signature)
  627. equal(result, false)
  628. message = ""
  629. signature = '<div>--<br>Some Signature<br>some department</div>'
  630. result = App.Utils.signatureCheck(message, signature)
  631. equal(result, true)
  632. message = ""
  633. signature = "--\nSome Signature\nsome department"
  634. result = App.Utils.signatureCheck(message, signature)
  635. equal(result, true)
  636. });
  637. // identify signature
  638. test("identify signature by plaintext", function() {
  639. var message = "<div>test 123 </div>"
  640. var should = '<div>test 123 </div>'
  641. var result = App.Utils.signatureIdentifyByPlaintext(message)
  642. equal(result, should)
  643. message = "<div>test 123 <br/>--<br/>Bob Smith</div>"
  644. should = '<div>test 123 <br/>--<br/>Bob Smith</div>'
  645. result = App.Utils.signatureIdentifyByPlaintext(message)
  646. equal(result, should)
  647. message = "<div>test 123 <br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/><br/>--<br/>Bob Smith</div>"
  648. should = '<div>test 123 <br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/><br/><span class="js-signatureMarker"></span>--<br/>Bob Smith</div>'
  649. result = App.Utils.signatureIdentifyByPlaintext(message)
  650. equal(result, should)
  651. message = "<div>test 123 <br/><br/>--no not match--<br/>--<br/>Bob Smith</div>"
  652. should = '<div>test 123 <br/><br/>--no not match--<br/><span class="js-signatureMarker"></span>--<br/>Bob Smith</div>'
  653. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  654. equal(result, should)
  655. message = "<div>test 123 <br/><br/>--no not match--<br/> -- <br/>Bob Smith</div>"
  656. should = '<div>test 123 <br/><br/>--no not match--<br/><span class="js-signatureMarker"></span> -- <br/>Bob Smith</div>'
  657. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  658. equal(result, should)
  659. message = "<div>test 123 <br/><br/>--<br/>Bob Smith<br/><br/><br/><br/><br/>--<br/>Bob Smith</div>"
  660. should = '<div>test 123 <br/><br/><span class="js-signatureMarker"></span>--<br/>Bob Smith<br/><br/><br/><br/><br/>--<br/>Bob Smith</div>'
  661. //should = '<div>test 123 <br><br><br><br><br><br><br><br><br><br><br><span class="js-signatureMarker"></span>--<br>Bob Smith<br/><br/><br/><br/><br/>--<br/>Bob Smith</div>'
  662. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  663. equal(result, should)
  664. message = "<div>test 123</div><div>test 123</div><div>--</div><div>Bob Smith</div>"
  665. should = "<div>test 123</div><div>test 123</div><div><span class=\"js-signatureMarker\"></span>--</div><div>Bob Smith</div>"
  666. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  667. equal(result, should)
  668. message = "<p><span>test 123</span></p><p><span>test 123</span></p><p><span>--</span></p><p><span>Bob Smith</span></p><div></div>"
  669. should = "<p><span>test 123</span></p><p><span>test 123</span></p><p><span><span class=\"js-signatureMarker\"></span>--</span></p><p><span>Bob Smith</span></p><div></div>"
  670. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  671. equal(result, should)
  672. message = "Test reply to zammad<br><br>Am 24.10.2016 18:55 schrieb &quot;Android Support&quot; &lt;android-support@example.com&gt;:<br><br>&gt; <u></u><br>&gt; Sehr geehrte Damen"
  673. should = "Test reply to zammad<br><br><span class=\"js-signatureMarker\"></span>Am 24.10.2016 18:55 schrieb &quot;Android Support&quot; &lt;android-support@example.com&gt;:<br><br>&gt; <u></u><br>&gt; Sehr geehrte Damen"
  674. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  675. equal(result, should)
  676. message = "<br>&lt; On 20 Oct 2016, at 12:23, Martin Edenhofer via Zammad Helpdesk wrote:<br>"
  677. should = "<br><span class=\"js-signatureMarker\"></span>&lt; On 20 Oct 2016, at 12:23, Martin Edenhofer via Zammad Helpdesk wrote:<br>"
  678. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  679. equal(result, should)
  680. // apple
  681. // en
  682. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>On 01/04/15 10:55, Bob Smith wrote:<br/>lalala<p>--</p>some test</div>"
  683. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class="js-signatureMarker"></span>On 01/04/15 10:55, Bob Smith wrote:<br/>lalala<p>--</p>some test</div>'
  684. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  685. equal(result, should)
  686. // de
  687. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>Am 03.04.2015 um 20:58 schrieb Bob Smith &lt;bob@example.com&gt;:<br/>lalala</div>"
  688. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class="js-signatureMarker"></span>Am 03.04.2015 um 20:58 schrieb Bob Smith &lt;bob@example.com&gt;:<br/>lalala</div>'
  689. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  690. equal(result, should)
  691. // ms
  692. // en
  693. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>From: Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]<br/>Sent: Donnerstag, 2. April 2015 10:00<br/>lalala</div>"
  694. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>From: Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]<br/>Sent: Donnerstag, 2. April 2015 10:00<br/>lalala</div>'
  695. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  696. equal(result, should)
  697. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>From: Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]<br/>Sent: Donnerstag, 2. April 2015 10:00<br/>Subject: lalala</div>"
  698. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class="js-signatureMarker"></span>From: Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]<br/>Sent: Donnerstag, 2. April 2015 10:00<br/>Subject: lalala</div>'
  699. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  700. equal(result, should)
  701. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>From: Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]<br/>Sent: Donnerstag, 2. April 2015 10:00<br/>1<br/>2<br/>3<br/>4<br/>4<br/>Subject: lalala</div>"
  702. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>From: Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]<br/>Sent: Donnerstag, 2. April 2015 10:00<br/>1<br/>2<br/>3<br/>4<br/>4<br/>Subject: lalala</div>'
  703. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  704. equal(result, should)
  705. // de
  706. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>Von: Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]<br/>Gesendet: Donnerstag, 2. April 2015 10:00<br/>Betreff: lalala</div>"
  707. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class="js-signatureMarker"></span>Von: Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]<br/>Gesendet: Donnerstag, 2. April 2015 10:00<br/>Betreff: lalala</div>'
  708. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  709. equal(result, should)
  710. message = "<div>1<br><br></div><div>Von: Martin Edenhofer via Znuny Support [<a href=\"mailto:support@znuny.inc\" title=\"mailto:support@znuny.inc\" target=\"_blank\">mailto:support@znuny.inc</a>]</div>\n<div>Gesendet: Donnerstag, 2. April 2015 11:32</div>"
  711. should = "<div>1<br><br></div><div>Von: Martin Edenhofer via Znuny Support [<a href=\"mailto:support@znuny.inc\" title=\"mailto:support@znuny.inc\" target=\"_blank\">mailto:support@znuny.inc</a>]</div>\n<div>Gesendet: Donnerstag, 2. April 2015 11:32</div>"
  712. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  713. equal(result, should)
  714. message = "<div>1<br><br></div><div>Von: Martin Edenhofer via Znuny Support [<a href=\"mailto:support@znuny.inc\" title=\"mailto:support@znuny.inc\" target=\"_blank\">mailto:support@znuny.inc</a>]</div>\n<div>Gesendet: Donnerstag, 2. April 2015 11:32</div><div>Betreff: lalala</div>"
  715. should = "<div>1<br><br></div><div><span class=\"js-signatureMarker\"></span>Von: Martin Edenhofer via Znuny Support [<a href=\"mailto:support@znuny.inc\" title=\"mailto:support@znuny.inc\" target=\"_blank\">mailto:support@znuny.inc</a>]</div>\n<div>Gesendet: Donnerstag, 2. April 2015 11:32</div><div>Betreff: lalala</div>"
  716. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  717. equal(result, should)
  718. message = "<div>1<br><br></div><div>Von: Martin Edenhofer via Znuny Support &lt;<a href=\"mailto:support@znuny.inc\" title=\"mailto:support@znuny.inc\" target=\"_blank\">mailto:support@znuny.inc</a>&gt;</div>\n<div>An: somebody</div><div>Datum: Donnerstag, 2. April 2015 11:32</div><div>Betreff: lalala</div>"
  719. should = "<div>1<br><br></div><div><span class=\"js-signatureMarker\"></span>Von: Martin Edenhofer via Znuny Support &lt;<a href=\"mailto:support@znuny.inc\" title=\"mailto:support@znuny.inc\" target=\"_blank\">mailto:support@znuny.inc</a>&gt;</div>\n<div>An: somebody</div><div>Datum: Donnerstag, 2. April 2015 11:32</div><div>Betreff: lalala</div>"
  720. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  721. equal(result, should)
  722. message = "<div>Von: &quot;Johannes Nickel via Znuny Projects&quot; &lt;<a href=\"mailto:projects@znuny.inc\" title=\"mailto:projects@znuny.inc\">projects@znuny.inc</a>&gt;</div><div>An: \"Lisa Smith\" &lt;<a href=\"mailto:lisa.smith@example.com\" title=\"mailto:lisa.smith@example.com\">lisa.smith@example.com</a>&gt;</div><div>Gesendet: Donnerstag, 2. April 2015 10:11:12</div><div>Betreff: Angebot Redundanz / Paket mit Silver Subscription [Ticket#424242]</div><div><br></div><div>Hallo Frau Smith,</div>"
  723. should = "<div><span class=\"js-signatureMarker\"></span>Von: &quot;Johannes Nickel via Znuny Projects&quot; &lt;<a href=\"mailto:projects@znuny.inc\" title=\"mailto:projects@znuny.inc\">projects@znuny.inc</a>&gt;</div><div>An: \"Lisa Smith\" &lt;<a href=\"mailto:lisa.smith@example.com\" title=\"mailto:lisa.smith@example.com\">lisa.smith@example.com</a>&gt;</div><div>Gesendet: Donnerstag, 2. April 2015 10:11:12</div><div>Betreff: Angebot Redundanz / Paket mit Silver Subscription [Ticket#424242]</div><div><br></div><div>Hallo Frau Smith,</div>"
  724. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  725. equal(result, should)
  726. message = "<div>Hi Johannes,</div><div><br></div><div>das Angebot für den halben Tag bitte an uns.</div><div>Der Termin hat sich jetzt auf 10-12 Uhr verschoben, hab ich dir weitergeleitet.</div><div><br></div><div>Viele Grüße</div><div>Max</div><div><br></div><div>&gt; On 07 Oct 2015, at 11:55, Johannes Smith &lt;<a href=mailto:smith@example.com title=mailto:smith@example.com target=_blank>smith@example.com</a> &lt;<a href=mailto:smith@example.com title=mailto:smith@example.com target=_blank>mailto:smith@example.com</a>&gt;&gt; wrote:</div><div>&gt;</div><div>&gt; Hi,</div><div>&gt;</div><div>&gt; OK. Wer kriegt das Angebot? Ist das wirklich nur ein halber Tag?</div></div>"
  727. should = "<div>Hi Johannes,</div><div><br></div><div>das Angebot für den halben Tag bitte an uns.</div><div>Der Termin hat sich jetzt auf 10-12 Uhr verschoben, hab ich dir weitergeleitet.</div><div><br></div><div>Viele Grüße</div><div>Max</div><div><br></div><div><span class=\"js-signatureMarker\"></span>&gt; On 07 Oct 2015, at 11:55, Johannes Smith &lt;<a href=mailto:smith@example.com title=mailto:smith@example.com target=_blank>smith@example.com</a> &lt;<a href=mailto:smith@example.com title=mailto:smith@example.com target=_blank>mailto:smith@example.com</a>&gt;&gt; wrote:</div><div>&gt;</div><div>&gt; Hi,</div><div>&gt;</div><div>&gt; OK. Wer kriegt das Angebot? Ist das wirklich nur ein halber Tag?</div></div>"
  728. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  729. equal(result, should)
  730. message = "Dear Mr. Smith,<div><br></div><div>it seems to be, dass Sie den AutoIncrement Nummerngenerator für Ihre ITSMChangeManagement Installation verwenden. Seit ABC 3.2 wird führend vor der sich in der Datei&nbsp;<span style=\"line-height: 1.45; background-color: initial;\">&lt;ABC_CONFIG_Home&gt;/war/log/ITSMChangeCounter.log &nbsp;befindenden Zahl die SystemID (SysConfig) geschrieben. Dies ist ein Standardverhalten, dass auch bei der Ticketnummer verwendet wird.<br><br>Please ask me if you have questions.</span></div><div><span style=\"line-height: 1.45; background-color: initial;\"><br></span></div><div><span style=\"line-height: 1.45; background-color: initial;\">Viele Grüße,</span></div><div><div data-signature=\"true\" data-signature-id=\"1\">&nbsp; Thorsten Smith\n<br>\n<br>--\n<br>Enterprise Services for ABC\n<br>\n<br>Znuny GmbH // Marienstraße 11 // 10117 Berlin // Germany\n<br>\n<br>P: +49 (0) 30 111 111 111-0\n<br>F: +49 (0) 30 111 111 111-8\n<br>W: http://znuny.com \n<br>\n<br>Location: Berlin - HRB 12345678 B Amtsgericht Berlin-Charlottenburg\n<br>Managing Director: Martin Edenhofer\n<br></div></div>"
  731. should = "Dear Mr. Smith,<div><br></div><div>it seems to be, dass Sie den AutoIncrement Nummerngenerator für Ihre ITSMChangeManagement Installation verwenden. Seit ABC 3.2 wird führend vor der sich in der Datei&nbsp;<span style=\"line-height: 1.45; background-color: initial;\">&lt;ABC_CONFIG_Home&gt;/war/log/ITSMChangeCounter.log &nbsp;befindenden Zahl die SystemID (SysConfig) geschrieben. Dies ist ein Standardverhalten, dass auch bei der Ticketnummer verwendet wird.<br><br>Please ask me if you have questions.</span></div><div><span style=\"line-height: 1.45; background-color: initial;\"><br></span></div><div><span style=\"line-height: 1.45; background-color: initial;\">Viele Grüße,</span></div><div><span class=\"js-signatureMarker\"></span><div data-signature=\"true\" data-signature-id=\"1\">&nbsp; Thorsten Smith\n<br>\n<br>--\n<br>Enterprise Services for ABC\n<br>\n<br>Znuny GmbH // Marienstraße 11 // 10117 Berlin // Germany\n<br>\n<br>P: +49 (0) 30 111 111 111-0\n<br>F: +49 (0) 30 111 111 111-8\n<br>W: http://znuny.com \n<br>\n<br>Location: Berlin - HRB 12345678 B Amtsgericht Berlin-Charlottenburg\n<br>Managing Director: Martin Edenhofer\n<br></div></div>"
  732. result = App.Utils.signatureIdentifyByPlaintext(message, true, true)
  733. equal(result, should)
  734. message = "Dear Mr. Smith, nice to read you,<div><div data-signature=\"true\" data-signature-id=\"1\">&nbsp; Thorsten Smith\n<br>\n<br>--\n</div></div>"
  735. should = "Dear Mr. Smith, nice to read you,<div><span class=\"js-signatureMarker\"></span><div data-signature=\"true\" data-signature-id=\"1\">&nbsp; Thorsten Smith\n<br>\n<br>--\n</div></div>"
  736. result = App.Utils.signatureIdentifyByPlaintext(message, true, true)
  737. equal(result, should)
  738. message = "Dear Mr. Smith, nice to read you,<div><div data-signature=\"true\" data-signature-id=\"9999\">&nbsp; Thorsten Smith\n<br>\n<br>--\n</div></div>"
  739. should = "Dear Mr. Smith, nice to read you,<div><div data-signature=\"true\" data-signature-id=\"9999\">&nbsp; Thorsten Smith\n<br>\n<br>--\n</div></div>"
  740. result = App.Utils.signatureIdentifyByPlaintext(message, false, true)
  741. equal(result, should)
  742. // fr
  743. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>De : Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]<br/>Envoyé : mercredi 29 avril 2015 17:31<br/>Objet : lalala</div>"
  744. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class="js-signatureMarker"></span>De : Martin Edenhofer via Znuny Support [mailto:support@znuny.inc]<br/>Envoyé : mercredi 29 avril 2015 17:31<br/>Objet : lalala</div>'
  745. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  746. equal(result, should)
  747. // thunderbird
  748. // de
  749. message = "<div><br></div><div>Viele Grüße,</div><div>Christian</div><div><br></div><div>Am 04.03.2015 um 12:47 schrieb Martin Edenhofer via Znuny Sales:</div><div>&gt; Hallo Christian,</div>"
  750. should = "<div><br></div><div>Viele Grüße,</div><div>Christian</div><div><br></div><div><span class=\"js-signatureMarker\"></span>Am 04.03.2015 um 12:47 schrieb Martin Edenhofer via Znuny Sales:</div><div>&gt; Hallo Christian,</div>"
  751. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  752. equal(result, should)
  753. // en - Thunderbird default - http://kb.mozillazine.org/Reply_header_settings
  754. message = "<div><br></div><div>Viele Grüße,</div><div>Christian</div><div><br></div><div>On 01-01-2007 11:00 AM, Alf Aardvark wrote:</div><div>&gt; Hallo Christian,</div>"
  755. should = "<div><br></div><div>Viele Grüße,</div><div>Christian</div><div><br></div><div><span class=\"js-signatureMarker\"></span>On 01-01-2007 11:00 AM, Alf Aardvark wrote:</div><div>&gt; Hallo Christian,</div>"
  756. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  757. equal(result, should)
  758. // en - http://kb.mozillazine.org/Reply_header_settings
  759. message = "<div><br></div><div>Viele Grüße,</div><div>Christian</div><div><br></div><div>Alf Aardvark wrote, on 01-01-2007 11:00 AM:</div><div>&gt; Hallo Christian,</div>"
  760. should = "<div><br></div><div>Viele Grüße,</div><div>Christian</div><div><br></div><div><span class=\"js-signatureMarker\"></span>Alf Aardvark wrote, on 01-01-2007 11:00 AM:</div><div>&gt; Hallo Christian,</div>"
  761. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  762. equal(result, should)
  763. // otrs
  764. // en
  765. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>01/04/15 10:55 - Bob Smith wrote:<br/>lalala</div>"
  766. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class="js-signatureMarker"></span>01/04/15 10:55 - Bob Smith wrote:<br/>lalala</div>'
  767. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  768. equal(result, should)
  769. // de
  770. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>01/04/15 10:55 - Bob Smith schrieb:<br/>lalala</div>"
  771. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class="js-signatureMarker"></span>01/04/15 10:55 - Bob Smith schrieb:<br/>lalala</div>'
  772. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  773. equal(result, should)
  774. message = "<div>test 123 <br/><br/></div><div>24.02.2015 14:20 - Roy Kaldung via Znuny Sales schrieb: &nbsp;</div>"
  775. should = "<div>test 123 <br/><br/></div><div><span class=\"js-signatureMarker\"></span>24.02.2015 14:20 - Roy Kaldung via Znuny Sales schrieb: &nbsp;</div>"
  776. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  777. equal(result, should)
  778. // zammad
  779. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><div data-signature=\"true\" data-signature-id=\"5\">lalala</div></div>"
  780. should = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class=\"js-signatureMarker\"></span><div data-signature=\"true\" data-signature-id=\"5\">lalala</div></div>"
  781. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  782. equal(result, should)
  783. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><blockquote type=\"cite\">lalala</blockquote></div>"
  784. should = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class=\"js-signatureMarker\"></span><blockquote type=\"cite\">lalala</blockquote></div>"
  785. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  786. equal(result, should)
  787. // gmail
  788. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><blockquote class=\"ecxgmail_quote\">lalala</blockquote></div>"
  789. should = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class=\"js-signatureMarker\"></span><blockquote class=\"ecxgmail_quote\">lalala</blockquote></div>"
  790. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  791. equal(result, should)
  792. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><blockquote class=\"gmail_quote\">lalala</blockquote></div>"
  793. should = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class=\"js-signatureMarker\"></span><blockquote class=\"gmail_quote\">lalala</blockquote></div>"
  794. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  795. equal(result, should)
  796. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>Am 24. Dezember 2015 um 07:45 schrieb kathrine &lt;kathrine@example.com&gt;:<br/>lalala</div>"
  797. should = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class=\"js-signatureMarker\"></span>Am 24. Dezember 2015 um 07:45 schrieb kathrine &lt;kathrine@example.com&gt;:<br/>lalala</div>"
  798. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  799. equal(result, should)
  800. // word 14
  801. // en
  802. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>Bob Smith wrote:<br/>lalala</div>"
  803. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class="js-signatureMarker"></span>Bob Smith wrote:<br/>lalala</div>'
  804. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  805. equal(result, should)
  806. // de
  807. message = "<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/>Bob Smith schrieb:<br/>lalala</div>"
  808. should = '<div>test 123 <br/><br/>--no not match--<br/><br/>Bob Smith<br/><span class="js-signatureMarker"></span>Bob Smith schrieb:<br/>lalala</div>'
  809. result = App.Utils.signatureIdentifyByPlaintext(message, true)
  810. equal(result, should)
  811. });
  812. test("identify signature by HTML", function() {
  813. var message = "<div>test 123 </div>"
  814. var should = message
  815. var result = App.Utils.signatureIdentifyByHtml(message)
  816. equal(result, should)
  817. // simple case 1
  818. message = '<div>actual content</div><blockquote>quoted content</blockquote>'
  819. should = '<div>actual content</div><span class="js-signatureMarker"></span><blockquote>quoted content</blockquote>'
  820. result = App.Utils.signatureIdentifyByHtml(message)
  821. equal(result, should)
  822. // simple case 2
  823. message = '<div>actual content</div><blockquote>quoted content</blockquote><br><div><br></div><div><br> </div>'
  824. should = '<div>actual content</div><span class="js-signatureMarker"></span><blockquote>quoted content</blockquote><br><div><br></div><div><br> </div>'
  825. result = App.Utils.signatureIdentifyByHtml(message)
  826. equal(result, should)
  827. // simple case 3
  828. message = '<div>actual content</div><blockquote>quoted content</blockquote><br><div>actual content 2</div>'
  829. should = message
  830. result = App.Utils.signatureIdentifyByHtml(message)
  831. equal(result, should)
  832. // simple case 4
  833. message = ' content 0 <div>content 1</div> content 2 <blockquote>quoted content</blockquote><br><div><br></div><div><br> </div>'
  834. should = ' content 0 <div>content 1</div> content 2 <span class="js-signatureMarker"></span><blockquote>quoted content</blockquote><br><div><br></div><div><br> </div>'
  835. result = App.Utils.signatureIdentifyByHtml(message)
  836. equal(result, should)
  837. // Gmail via Safari on MacOS 10.12
  838. message = '<div dir="ltr">Reply with <b>gmail</b> via Safari on MacOS 10.12</div><br>\
  839. <div>\
  840. <div dir="ltr">Am Mi., 5. Sep. 2018 um 09:22 Uhr schrieb Billy Zhou &lt;bz@zammad.com&gt;:<br>\
  841. </div>\
  842. <blockquote>test email content<br>\
  843. <br>\
  844. </blockquote>\
  845. </div>'
  846. should = '<div dir="ltr">Reply with <b>gmail</b> via Safari on MacOS 10.12</div><br>\
  847. <span class=\"js-signatureMarker\"></span><div>\
  848. <div dir="ltr">Am Mi., 5. Sep. 2018 um 09:22 Uhr schrieb Billy Zhou &lt;bz@zammad.com&gt;:<br>\
  849. </div>\
  850. <blockquote>test email content<br>\
  851. <br>\
  852. </blockquote>\
  853. </div>'
  854. result = App.Utils.signatureIdentifyByHtml(message)
  855. equal(result, should)
  856. // Yahoo Mail via Safari on MacOS 10.12
  857. message = '<div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:16px"><div id="yui_3_16_0_ym19_1_1536132243868_2594"><span id="yui_3_16_0_ym19_1_1536132243868_2593">Reply with <b id="yui_3_16_0_ym19_1_1536132243868_2597">Yahoo Mail</b> via Safari on MacOS 10.12</span></div> <div class="qtdSeparateBR"><br><br></div><div class="yahoo_quoted" style="display: block;"> <div style="font-family: Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 16px;"> <div style="font-family: HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 16px;"> <div dir="ltr"><font size="2" face="Arial"> Billy Zhou &lt;bz@zammad.com&gt; schrieb am 9:08 Mittwoch, 5.September 2018:<br></font></div> <br><br> <div class="y_msg_container"><div dir="ltr">test email content<br></div><div dir="ltr"><br></div><br><br></div> </div> </div> </div></div>'
  858. should = '<div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:16px"><div id="yui_3_16_0_ym19_1_1536132243868_2594"><span id="yui_3_16_0_ym19_1_1536132243868_2593">Reply with <b id="yui_3_16_0_ym19_1_1536132243868_2597">Yahoo Mail</b> via Safari on MacOS 10.12</span></div> <div class="qtdSeparateBR"><br><br></div><span class="js-signatureMarker"></span><div class="yahoo_quoted" style="display: block;"> <div style="font-family: Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 16px;"> <div style="font-family: HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 16px;"> <div dir="ltr"><font size="2" face="Arial"> Billy Zhou &lt;bz@zammad.com&gt; schrieb am 9:08 Mittwoch, 5.September 2018:<br></font></div> <br><br> <div class="y_msg_container"><div dir="ltr">test email content<br></div><div dir="ltr"><br></div><br><br></div> </div> </div> </div></div>'
  859. result = App.Utils.signatureIdentifyByHtml(message)
  860. equal(result, should)
  861. // Thunderbird 52 on MacOS 10.12
  862. message = 'Reply with <b>Thunderbird 52</b> on MacOS 10.12<br>\
  863. <br>\
  864. <div class="moz-cite-prefix">Am 04.09.18 um 15:32 schrieb Billy\
  865. Zhou:<br>\
  866. </div>\
  867. <blockquote type="cite"\
  868. cite="mid:da18ed01-b187-a383-bfe7-72663cf82a83@zammad.com">test\
  869. email content\
  870. <br>\
  871. <br>\
  872. </blockquote>\
  873. <br>'
  874. should = 'Reply with <b>Thunderbird 52</b> on MacOS 10.12<br>\
  875. <br>\
  876. <div class="moz-cite-prefix">Am 04.09.18 um 15:32 schrieb Billy\
  877. Zhou:<br>\
  878. </div>\
  879. <span class=\"js-signatureMarker\"></span><blockquote type="cite" cite="mid:da18ed01-b187-a383-bfe7-72663cf82a83@zammad.com">test\
  880. email content\
  881. <br>\
  882. <br>\
  883. </blockquote>\
  884. <br>'
  885. result = App.Utils.signatureIdentifyByHtml(message)
  886. equal(result, should)
  887. // Apple Mail on MacOS 10
  888. message = '<div class="">Reply by <b class="">Apple Mail</b> on MacOS 10.</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On 4. Sep 2018, at 15:32, Billy Zhou &lt;<a href="mailto:bz@zammad.com" class="">bz@zammad.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">test email content<br class=""><br class=""></div></div></blockquote></div><br class="">'
  889. should = '<div class="">Reply by <b class="">Apple Mail</b> on MacOS 10.</div><div class=""><br class=""></div><br class=""><span class=\"js-signatureMarker\"></span><div><blockquote type="cite" class=""><div class="">On 4. Sep 2018, at 15:32, Billy Zhou &lt;<a href="mailto:bz@zammad.com" class="">bz@zammad.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">test email content<br class=""><br class=""></div></div></blockquote></div><br class="">'
  890. result = App.Utils.signatureIdentifyByHtml(message)
  891. equal(result, should)
  892. // Office 365 (10325.20118) on Windows 10 Build 1803
  893. // With German marker: -----Ursprüngliche Nachricht-----
  894. // Using fallback to signatureIdentifyByPlaintext
  895. message = '<div>\
  896. <p>Reply with Office 365 (10325.20118) on Windows 10 Build 1803</p>\
  897. <p> </p>\
  898. <p><b>fett</b></p>\
  899. <p> </p>\
  900. <span class="js-signatureMarker"></span><p>--</p>\
  901. <p>Zammad GmbH // Marienstraße 11 // 10117 Berlin // Germany</p>\
  902. <p> </p>\
  903. <p>P: +49 (0) 30 55 57 160-0</p>\
  904. <p>F: +49 (0) 30 55 57 160-99</p>\
  905. <p>W: <a href="https://zammad.com" rel="nofollow noreferrer noopener" target="_blank">https://zammad.com</a></p>\
  906. <p> </p>\
  907. <p>Location: Berlin - HRB 163946 B Amtsgericht Berlin-Charlottenburg</p>\
  908. <p>Managing Director: Martin Edenhofer</p>\
  909. <p> </p>\
  910. <p>-----Ursprüngliche Nachricht-----<br>Von: Billy Zhou &lt;bz@zammad.com&gt; <br>Gesendet: Dienstag, 4. September 2018 15:33<br>An: me@zammad.com<br>Betreff: test email title</p>\
  911. <p> </p>\
  912. <p>test email content</p>\
  913. <p> </p>\
  914. </div>'
  915. should = '<div>\
  916. <p>Reply with Office 365 (10325.20118) on Windows 10 Build 1803</p>\
  917. <p> </p>\
  918. <p><b>fett</b></p>\
  919. <p> </p>\
  920. <span class="js-signatureMarker"></span><p><span class=\"js-signatureMarker\"></span>--</p>\
  921. <p>Zammad GmbH // Marienstraße 11 // 10117 Berlin // Germany</p>\
  922. <p> </p>\
  923. <p>P: +49 (0) 30 55 57 160-0</p>\
  924. <p>F: +49 (0) 30 55 57 160-99</p>\
  925. <p>W: <a href="https://zammad.com" rel="nofollow noreferrer noopener" target="_blank">https://zammad.com</a></p>\
  926. <p> </p>\
  927. <p>Location: Berlin - HRB 163946 B Amtsgericht Berlin-Charlottenburg</p>\
  928. <p>Managing Director: Martin Edenhofer</p>\
  929. <p> </p>\
  930. <p>-----Ursprüngliche Nachricht-----<br>Von: Billy Zhou &lt;bz@zammad.com&gt; <br>Gesendet: Dienstag, 4. September 2018 15:33<br>An: me@zammad.com<br>Betreff: test email title</p>\
  931. <p> </p>\
  932. <p>test email content</p>\
  933. <p> </p>\
  934. </div>'
  935. result = App.Utils.signatureIdentifyByHtml(message)
  936. equal(result, should)
  937. // Office 365 (10325.20118) on Windows 10 Build 1803
  938. // With English marker: -----Original Message-----
  939. // Using fallback to signatureIdentifyByPlaintext
  940. message = '<div>\
  941. <p>Reply with Office 365 (10325.20118) on Windows 10 Build 1803</p>\
  942. <p> </p>\
  943. <p><b>fett</b></p>\
  944. <p> </p>\
  945. <span class="js-signatureMarker"></span><p>--</p>\
  946. <p>Zammad GmbH // Marienstraße 11 // 10117 Berlin // Germany</p>\
  947. <p> </p>\
  948. <p>P: +49 (0) 30 55 57 160-0</p>\
  949. <p>F: +49 (0) 30 55 57 160-99</p>\
  950. <p>W: <a href="https://zammad.com" rel="nofollow noreferrer noopener" target="_blank">https://zammad.com</a></p>\
  951. <p> </p>\
  952. <p>Location: Berlin - HRB 163946 B Amtsgericht Berlin-Charlottenburg</p>\
  953. <p>Managing Director: Martin Edenhofer</p>\
  954. <p> </p>\
  955. <p>-----Original Message-----<br>Von: Billy Zhou &lt;bz@zammad.com&gt; <br>Gesendet: Dienstag, 4. September 2018 15:33<br>An: me@zammad.com<br>Betreff: test email title</p>\
  956. <p> </p>\
  957. <p>test email content</p>\
  958. <p> </p>\
  959. </div>'
  960. should = '<div>\
  961. <p>Reply with Office 365 (10325.20118) on Windows 10 Build 1803</p>\
  962. <p> </p>\
  963. <p><b>fett</b></p>\
  964. <p> </p>\
  965. <span class="js-signatureMarker"></span><p><span class=\"js-signatureMarker\"></span>--</p>\
  966. <p>Zammad GmbH // Marienstraße 11 // 10117 Berlin // Germany</p>\
  967. <p> </p>\
  968. <p>P: +49 (0) 30 55 57 160-0</p>\
  969. <p>F: +49 (0) 30 55 57 160-99</p>\
  970. <p>W: <a href="https://zammad.com" rel="nofollow noreferrer noopener" target="_blank">https://zammad.com</a></p>\
  971. <p> </p>\
  972. <p>Location: Berlin - HRB 163946 B Amtsgericht Berlin-Charlottenburg</p>\
  973. <p>Managing Director: Martin Edenhofer</p>\
  974. <p> </p>\
  975. <p>-----Original Message-----<br>Von: Billy Zhou &lt;bz@zammad.com&gt; <br>Gesendet: Dienstag, 4. September 2018 15:33<br>An: me@zammad.com<br>Betreff: test email title</p>\
  976. <p> </p>\
  977. <p>test email content</p>\
  978. <p> </p>\
  979. </div>'
  980. result = App.Utils.signatureIdentifyByHtml(message)
  981. equal(result, should)
  982. // Office 365 (10325.20118) on Windows 10 Build 1803
  983. // With German marker: -----Ursprüngliche Nachricht-----
  984. // Without any existing <span class="js-signatureMarker"></span>
  985. // Using fallback to signatureIdentifyByPlaintext
  986. message = '<div>\
  987. <p>Reply with Office 365 (10325.20118) on Windows 10 Build 1803</p>\
  988. <p> </p>\
  989. <p><b>fett</b></p>\
  990. <p> </p>\
  991. <p>--</p>\
  992. <p>Zammad GmbH // Marienstraße 11 // 10117 Berlin // Germany</p>\
  993. <p> </p>\
  994. <p>P: +49 (0) 30 55 57 160-0</p>\
  995. <p>F: +49 (0) 30 55 57 160-99</p>\
  996. <p>W: <a href="https://zammad.com" rel="nofollow noreferrer noopener" target="_blank">https://zammad.com</a></p>\
  997. <p> </p>\
  998. <p>Location: Berlin - HRB 163946 B Amtsgericht Berlin-Charlottenburg</p>\
  999. <p>Managing Director: Martin Edenhofer</p>\
  1000. <p> </p>\
  1001. <p>-----Ursprüngliche Nachricht-----<br>Von: Billy Zhou &lt;bz@zammad.com&gt; <br>Gesendet: Dienstag, 4. September 2018 15:33<br>An: me@zammad.com<br>Betreff: test email title</p>\
  1002. <p> </p>\
  1003. <p>test email content</p>\
  1004. <p> </p>\
  1005. </div>'
  1006. should = '<div>\
  1007. <p>Reply with Office 365 (10325.20118) on Windows 10 Build 1803</p>\
  1008. <p> </p>\
  1009. <p><b>fett</b></p>\
  1010. <p> </p>\
  1011. <p><span class=\"js-signatureMarker\"></span>--</p>\
  1012. <p>Zammad GmbH // Marienstraße 11 // 10117 Berlin // Germany</p>\
  1013. <p> </p>\
  1014. <p>P: +49 (0) 30 55 57 160-0</p>\
  1015. <p>F: +49 (0) 30 55 57 160-99</p>\
  1016. <p>W: <a href="https://zammad.com" rel="nofollow noreferrer noopener" target="_blank">https://zammad.com</a></p>\
  1017. <p> </p>\
  1018. <p>Location: Berlin - HRB 163946 B Amtsgericht Berlin-Charlottenburg</p>\
  1019. <p>Managing Director: Martin Edenhofer</p>\
  1020. <p> </p>\
  1021. <p>-----Ursprüngliche Nachricht-----<br>Von: Billy Zhou &lt;bz@zammad.com&gt; <br>Gesendet: Dienstag, 4. September 2018 15:33<br>An: me@zammad.com<br>Betreff: test email title</p>\
  1022. <p> </p>\
  1023. <p>test email content</p>\
  1024. <p> </p>\
  1025. </div>'
  1026. result = App.Utils.signatureIdentifyByHtml(message)
  1027. equal(result, should)
  1028. });
  1029. // check attachment references
  1030. test("check check attachment reference", function() {
  1031. var message = 'some not existing'
  1032. var result = false
  1033. var verify = App.Utils.checkAttachmentReference(message)
  1034. equal(verify, result)
  1035. message = 'some attachment for you'
  1036. result = 'Attachment'
  1037. verify = App.Utils.checkAttachmentReference(message)
  1038. equal(verify, result)
  1039. message = 'your attachment.'
  1040. result = 'Attachment'
  1041. verify = App.Utils.checkAttachmentReference(message)
  1042. equal(verify, result)
  1043. message = 'some otherattachment for you'
  1044. result = false
  1045. verify = App.Utils.checkAttachmentReference(message)
  1046. equal(verify, result)
  1047. message = 'some attachmentother for you'
  1048. result = false
  1049. verify = App.Utils.checkAttachmentReference(message)
  1050. equal(verify, result)
  1051. message = 'someattachment'
  1052. result = false
  1053. verify = App.Utils.checkAttachmentReference(message)
  1054. equal(verify, result)
  1055. message = 'As enclosed you will find.'
  1056. result = 'Enclosed'
  1057. verify = App.Utils.checkAttachmentReference(message)
  1058. equal(verify, result)
  1059. });
  1060. // replace tags
  1061. test("check replace tags", function() {
  1062. var formatNumber = function(num, digits) {
  1063. while (num.toString().length < digits) {
  1064. num = '0' + num
  1065. }
  1066. return num
  1067. }
  1068. var formatTimestamp = function(timestamp) {
  1069. localTime = new Date(Date.parse(timestamp))
  1070. d = formatNumber(localTime.getDate(), 2)
  1071. m = formatNumber(localTime.getMonth() + 1, 2)
  1072. yfull = localTime.getFullYear()
  1073. M = formatNumber(localTime.getMinutes(), 2)
  1074. H = formatNumber(localTime.getHours(), 2)
  1075. return m + '/' + d + '/' + yfull + ' ' + H + ':' + M
  1076. }
  1077. var message = "<div>#{user.firstname} #{user.lastname}</div>"
  1078. var result = '<div>Bob Smith</div>'
  1079. var data = {
  1080. user: {
  1081. firstname: 'Bob',
  1082. lastname: 'Smith',
  1083. },
  1084. }
  1085. var verify = App.Utils.replaceTags(message, data)
  1086. equal(verify, result)
  1087. message = "<div>#{user.firstname} #{user.lastname}</div>"
  1088. result = '<div>Bob Smith</div>'
  1089. data = {
  1090. user: {
  1091. firstname: function() { return 'Bob' },
  1092. lastname: function() { return 'Smith' },
  1093. },
  1094. }
  1095. verify = App.Utils.replaceTags(message, data)
  1096. equal(verify, result)
  1097. message = "<div>#{user.firstname} #{user.lastname}</div>"
  1098. result = '<div>Bob -</div>'
  1099. data = {
  1100. user: {
  1101. firstname: 'Bob',
  1102. },
  1103. }
  1104. verify = App.Utils.replaceTags(message, data)
  1105. equal(verify, result)
  1106. message = "<div>#{user.firstname} #{user.lastname}</div>"
  1107. result = '<div>Bob 0</div>'
  1108. data = {
  1109. user: {
  1110. firstname: 'Bob',
  1111. lastname: 0,
  1112. },
  1113. }
  1114. verify = App.Utils.replaceTags(message, data)
  1115. equal(verify, result)
  1116. message = "<div>#{user.firstname} #{user.lastname}</div>"
  1117. result = '<div>Bob -</div>'
  1118. data = {
  1119. user: {
  1120. firstname: 'Bob',
  1121. lastname: '',
  1122. },
  1123. }
  1124. verify = App.Utils.replaceTags(message, data)
  1125. equal(verify, result)
  1126. message = "<div>#{user.firstname} #{user.not.existing.test}</div>"
  1127. result = '<div>Bob -</div>'
  1128. data = {
  1129. user: {
  1130. firstname: 'Bob',
  1131. },
  1132. }
  1133. verify = App.Utils.replaceTags(message, data)
  1134. equal(verify, result)
  1135. message = "<div>#{user.firstname} #{not.existing.test}</div>"
  1136. result = '<div>Bob -</div>'
  1137. data = {
  1138. user: {
  1139. firstname: 'Bob',
  1140. },
  1141. }
  1142. verify = App.Utils.replaceTags(message, data)
  1143. equal(verify, result)
  1144. message = "<div>#{user.firstname} #{not.existing.test}</div>"
  1145. result = '<div>Bob -</div>'
  1146. data = {
  1147. user: {
  1148. firstname: 'Bob',
  1149. not: null,
  1150. },
  1151. }
  1152. verify = App.Utils.replaceTags(message, data)
  1153. equal(verify, result)
  1154. message = "<div>#{user.firstname} #{not.existing.test}</div>"
  1155. result = '<div>Bob -</div>'
  1156. data = {
  1157. user: {
  1158. firstname: 'Bob',
  1159. not: {},
  1160. },
  1161. }
  1162. verify = App.Utils.replaceTags(message, data)
  1163. equal(verify, result)
  1164. message = "<div>#{user.firstname} #{<a href=\"/test\">user.lastname</a>}</div>"
  1165. result = '<div>Bob Smith</div>'
  1166. data = {
  1167. user: {
  1168. firstname: 'Bob',
  1169. lastname: 'Smith',
  1170. },
  1171. }
  1172. verify = App.Utils.replaceTags(message, data)
  1173. equal(verify, result)
  1174. user = new App.User({
  1175. firstname: 'Bob',
  1176. lastname: 'Smith',
  1177. created_at: '2018-10-31T10:00:00Z',
  1178. })
  1179. message = "<div>#{user.firstname} #{user.created_at}</div>"
  1180. result = '<div>Bob ' + formatTimestamp('2018-10-31T10:00:00Z') + '</div>'
  1181. data = {
  1182. user: user
  1183. }
  1184. verify = App.Utils.replaceTags(message, data)
  1185. equal(verify, result)
  1186. message = "<div>#{user.firstname} #{user.created_at.date}</div>"
  1187. result = '<div>Bob -</div>'
  1188. data = {
  1189. user: user
  1190. }
  1191. verify = App.Utils.replaceTags(message, data)
  1192. equal(verify, result)
  1193. message = "<div>#{user.firstname} #{user.created.date}</div>"
  1194. result = '<div>Bob -</div>'
  1195. data = {
  1196. user: user
  1197. }
  1198. verify = App.Utils.replaceTags(message, data)
  1199. equal(verify, result)
  1200. });
  1201. // check attibute validation
  1202. test("check attibute validation", function() {
  1203. var string = '123'
  1204. var result = '123'
  1205. var verify = App.Utils.htmlAttributeCleanup(string)
  1206. equal(verify, result, string)
  1207. string = '123!'
  1208. result = '123'
  1209. verify = App.Utils.htmlAttributeCleanup(string)
  1210. equal(verify, result, string)
  1211. string = '12 3!'
  1212. result = '123'
  1213. verify = App.Utils.htmlAttributeCleanup(string)
  1214. equal(verify, result, string)
  1215. string = '12-3!'
  1216. result = '12-3'
  1217. verify = App.Utils.htmlAttributeCleanup(string)
  1218. equal(verify, result, string)
  1219. string = '12_3!'
  1220. result = '12_3'
  1221. verify = App.Utils.htmlAttributeCleanup(string)
  1222. equal(verify, result, string)
  1223. string = '^12_3!'
  1224. result = '12_3'
  1225. verify = App.Utils.htmlAttributeCleanup(string)
  1226. equal(verify, result, string)
  1227. string = '^1\n 2_3!'
  1228. result = '12_3'
  1229. verify = App.Utils.htmlAttributeCleanup(string)
  1230. equal(verify, result, string)
  1231. string = 'abc?'
  1232. result = 'abc'
  1233. verify = App.Utils.htmlAttributeCleanup(string)
  1234. equal(verify, result, string)
  1235. string = 'abc."'
  1236. result = 'abc'
  1237. verify = App.Utils.htmlAttributeCleanup(string)
  1238. equal(verify, result, string)
  1239. string = '#abc!^'
  1240. result = 'abc'
  1241. verify = App.Utils.htmlAttributeCleanup(string)
  1242. equal(verify, result, string)
  1243. string = 'abc()=$'
  1244. result = 'abc'
  1245. verify = App.Utils.htmlAttributeCleanup(string)
  1246. equal(verify, result, string)
  1247. string = "abc()=$\n123\rß"
  1248. result = 'abc123'
  1249. verify = App.Utils.htmlAttributeCleanup(string)
  1250. equal(verify, result, string)
  1251. });
  1252. // check form diff
  1253. test("check form diff", function() {
  1254. var dataNow = {
  1255. owner_id: 1,
  1256. pending_date: '2015-01-28T09:39:00Z',
  1257. }
  1258. var dataLast = {
  1259. owner_id: '',
  1260. pending_date: '2015-01-28T09:39:00Z',
  1261. }
  1262. var diff = {}
  1263. var result = App.Utils.formDiff(dataNow, dataLast)
  1264. deepEqual(result, diff, 'check form diff')
  1265. dataNow = {
  1266. owner_id: '1',
  1267. pending_date: '2015-01-28T09:39:00Z',
  1268. }
  1269. dataLast = {
  1270. owner_id: '',
  1271. pending_date: '2015-01-28T09:39:00Z',
  1272. }
  1273. diff = {}
  1274. result = App.Utils.formDiff(dataNow, dataLast)
  1275. deepEqual(result, diff, 'check form diff')
  1276. dataNow = {
  1277. pending_date: '2015-01-28T09:39:00Z',
  1278. }
  1279. dataLast = {
  1280. owner_id: 1,
  1281. pending_date: '2015-01-28T09:39:00Z',
  1282. }
  1283. diff = {}
  1284. result = App.Utils.formDiff(dataNow, dataLast)
  1285. deepEqual(result, diff, 'check form diff')
  1286. dataNow = {
  1287. owner_id: '',
  1288. pending_date: '2015-01-28T09:39:00Z',
  1289. }
  1290. dataLast = {
  1291. pending_date: '2015-01-28T09:39:00Z',
  1292. }
  1293. diff = {
  1294. }
  1295. result = App.Utils.formDiff(dataNow, dataLast)
  1296. deepEqual(result, diff, 'check form diff')
  1297. dataNow = {
  1298. owner_id: '',
  1299. state_ids: [1,5,6,7],
  1300. }
  1301. dataLast = {}
  1302. diff = {
  1303. state_ids: ['1','5','6','7'],
  1304. }
  1305. result = App.Utils.formDiff(dataNow, dataLast)
  1306. deepEqual(result, diff, 'check form diff')
  1307. dataNow = {
  1308. owner_id: 1,
  1309. state_ids: [1,5,7,6],
  1310. }
  1311. dataLast = {
  1312. owner_id: '',
  1313. state_ids: [1,5,6,7],
  1314. }
  1315. diff = {}
  1316. result = App.Utils.formDiff(dataNow, dataLast)
  1317. deepEqual(result, diff, 'check form diff')
  1318. dataNow = {
  1319. owner_id: 1,
  1320. state_ids: [1,5,6,7],
  1321. }
  1322. dataLast = {
  1323. state_ids: ['1','5','7'],
  1324. }
  1325. diff = {
  1326. state_ids: ['6'],
  1327. }
  1328. result = App.Utils.formDiff(dataNow, dataLast)
  1329. deepEqual(result, diff, 'check form diff')
  1330. dataNow = {
  1331. owner_id: '',
  1332. state_ids: [1,5,6,7],
  1333. }
  1334. dataLast = {
  1335. owner_id: 1,
  1336. state_ids: [1,5,6,7],
  1337. }
  1338. diff = {}
  1339. result = App.Utils.formDiff(dataNow, dataLast)
  1340. deepEqual(result, diff, 'check form diff')
  1341. dataNow = {
  1342. owner_id: '',
  1343. state_ids: [1,5,6,7],
  1344. }
  1345. dataLast = {
  1346. owner_id: 5,
  1347. state_ids: [1,5,6,7],
  1348. }
  1349. diff = {
  1350. owner_id: ''
  1351. }
  1352. result = App.Utils.formDiff(dataNow, dataLast)
  1353. deepEqual(result, diff, 'check form diff')
  1354. dataNow = {
  1355. state_id: 4,
  1356. pending_time: '2015-01-28T11:34:00Z'
  1357. }
  1358. dataLast = {
  1359. state_id: 5,
  1360. pending_time: undefined
  1361. }
  1362. diff = {
  1363. state_id: '4',
  1364. pending_time: '2015-01-28T11:34:00Z'
  1365. }
  1366. result = App.Utils.formDiff(dataNow, dataLast)
  1367. deepEqual(result, diff, 'check form diff')
  1368. dataNow = {
  1369. pending_time: undefined
  1370. }
  1371. dataLast = {
  1372. pending_time: null
  1373. }
  1374. diff = {}
  1375. result = App.Utils.formDiff(dataNow, dataLast)
  1376. deepEqual(result, diff, 'check form diff')
  1377. dataNow = {
  1378. ticket: {
  1379. pending_time: undefined,
  1380. },
  1381. }
  1382. dataLast = {
  1383. ticket: {
  1384. pending_time: null,
  1385. },
  1386. }
  1387. diff = {}
  1388. result = App.Utils.formDiff(dataNow, dataLast)
  1389. deepEqual(result, diff, 'check form diff')
  1390. dataNow = {
  1391. test: '123',
  1392. ticket: {
  1393. pending_time: undefined,
  1394. },
  1395. }
  1396. dataLast = {
  1397. test: '123',
  1398. ticket: {
  1399. pending_time: null,
  1400. },
  1401. }
  1402. diff = {}
  1403. result = App.Utils.formDiff(dataNow, dataLast)
  1404. deepEqual(result, diff, 'check form diff')
  1405. dataNow = {
  1406. test: '123',
  1407. }
  1408. dataLast = {}
  1409. diff = {
  1410. test: '123',
  1411. }
  1412. result = App.Utils.formDiff(dataNow, dataLast)
  1413. deepEqual(result, diff, 'check form diff')
  1414. dataNow = {
  1415. test: '123',
  1416. }
  1417. dataLast = {
  1418. test: [1,2,3,4]
  1419. }
  1420. diff = {
  1421. test: '123',
  1422. }
  1423. result = App.Utils.formDiff(dataNow, dataLast)
  1424. deepEqual(result, diff, 'check form diff')
  1425. dataNow = {
  1426. test: '123',
  1427. }
  1428. dataLast = {
  1429. test: {
  1430. 1: 1,
  1431. 2: 2,
  1432. }
  1433. }
  1434. diff = {
  1435. test: '123',
  1436. }
  1437. result = App.Utils.formDiff(dataNow, dataLast)
  1438. deepEqual(result, diff, 'check form diff')
  1439. dataNow = {
  1440. test: [1,2,3,'4']
  1441. }
  1442. dataLast = {
  1443. test: '123',
  1444. }
  1445. diff = {
  1446. test: ['1','2','3','4']
  1447. }
  1448. result = App.Utils.formDiff(dataNow, dataLast)
  1449. deepEqual(result, diff, 'check form diff')
  1450. dataNow = {
  1451. test: {
  1452. 1: 1,
  1453. 2: 2,
  1454. }
  1455. }
  1456. dataLast = {
  1457. test: '123',
  1458. }
  1459. diff = {
  1460. test: {
  1461. 1: '1',
  1462. 2: '2',
  1463. }
  1464. }
  1465. result = App.Utils.formDiff(dataNow, dataLast)
  1466. deepEqual(result, diff, 'check form diff')
  1467. // regression test for issue #2042 - incorrect notification when closing a tab after setting up an object
  1468. // A newly created attribute will have the empty string as its value, this should be ignored for formDiff comparison
  1469. dataNow = {
  1470. test: '',
  1471. }
  1472. dataLast = {}
  1473. diff = {}
  1474. result = App.Utils.formDiff(dataNow, dataLast)
  1475. deepEqual(result, diff, 'check form diff for a newly created attribute that is blank')
  1476. dataNow = {
  1477. test: '',
  1478. }
  1479. dataLast = {
  1480. test: '123',
  1481. }
  1482. diff = {
  1483. test: '',
  1484. }
  1485. result = App.Utils.formDiff(dataNow, dataLast)
  1486. deepEqual(result, diff, 'check form diff for setting a previously valid value to blank')
  1487. dataNow = {
  1488. test: '123',
  1489. ticket: {
  1490. pending_time: undefined,
  1491. },
  1492. }
  1493. dataLast = {
  1494. ticket: {
  1495. pending_time: null,
  1496. },
  1497. }
  1498. diff = {
  1499. test: '123',
  1500. }
  1501. result = App.Utils.formDiff(dataNow, dataLast)
  1502. deepEqual(result, diff, 'check form diff')
  1503. dataNow = undefined
  1504. dataLast = undefined
  1505. diff = {}
  1506. result = App.Utils.formDiff(dataNow, dataLast)
  1507. deepEqual(result, diff, 'check form diff')
  1508. dataNow = {}
  1509. dataLast = {"number":"10012","title":"some subject 123äöü","group_id":1,"owner_id":1,"customer_id":2,"state_id":3,"priority_id":2,"article":{"from":"Test Master Agent","to":"","cc":"","body":"dasdad","content_type":"text/html","ticket_id":12,"type_id":9,"sender_id":1,"internal":false,"form_id":"523405147"},"updated_at":"2015-01-29T09:22:23.000Z","pending_time":"2015-01-28T22:22:00.000Z","id":12}
  1510. diff = {}
  1511. result = App.Utils.formDiff(dataNow, dataLast)
  1512. deepEqual(result, diff, 'check form diff')
  1513. // do not compare content of data instances/objects
  1514. no = function test_object() {
  1515. this.a = function() { return 123; }
  1516. this.b = function() { return '1234'; }
  1517. this.c = function() { return [123]; }
  1518. this.d = [1,2,3];
  1519. this.e = 'abc';
  1520. }
  1521. no1 = new no()
  1522. no2 = new no()
  1523. no3 = new no()
  1524. dataNow = {
  1525. number:'10013',
  1526. Article: [no1],
  1527. }
  1528. dataLast = {
  1529. number: "10012",
  1530. title: "some subject 123äöü",
  1531. Article: [ no2, no3 ],
  1532. }
  1533. diff = {
  1534. number:'10013',
  1535. }
  1536. result = App.Utils.formDiff(dataNow, dataLast)
  1537. deepEqual(result, diff, 'check form diff')
  1538. dataNow = {
  1539. number:'10013',
  1540. Article: [no1,2],
  1541. }
  1542. dataLast = {
  1543. number: "10012",
  1544. title: "some subject 123äöü",
  1545. Article: [ no2, no3 ],
  1546. }
  1547. diff = {
  1548. number:'10013',
  1549. Article: ['2'],
  1550. }
  1551. result = App.Utils.formDiff(dataNow, dataLast)
  1552. deepEqual(result, diff, 'check form diff')
  1553. });
  1554. // check decimal format
  1555. test("check decimal format", function() {
  1556. var string = '123'
  1557. var result = '123.00'
  1558. var verify = App.Utils.decimal(string)
  1559. equal(verify, result, string)
  1560. string = '0.6'
  1561. result = '0.60'
  1562. verify = App.Utils.decimal(string)
  1563. equal(verify, result, string)
  1564. string = '6'
  1565. result = '6.00'
  1566. verify = App.Utils.decimal(string)
  1567. equal(verify, result, string)
  1568. string = 6.5
  1569. result = '6.50'
  1570. verify = App.Utils.decimal(string)
  1571. equal(verify, result, string)
  1572. string = '111111.6'
  1573. result = '111111.60'
  1574. verify = App.Utils.decimal(string)
  1575. equal(verify, result, string)
  1576. string = '111111.622'
  1577. result = '111111.62'
  1578. verify = App.Utils.decimal(string)
  1579. equal(verify, result, string)
  1580. string = 'abc.6'
  1581. result = 'abc.6'
  1582. verify = App.Utils.decimal(string)
  1583. equal(verify, result, string)
  1584. string = ''
  1585. result = ''
  1586. verify = App.Utils.decimal(string)
  1587. equal(verify, result, string)
  1588. string = undefined
  1589. result = ''
  1590. verify = App.Utils.decimal(string)
  1591. equal(verify, result, string)
  1592. string = null
  1593. result = ''
  1594. verify = App.Utils.decimal(string)
  1595. equal(verify, result, string)
  1596. });
  1597. // check formatTime format
  1598. test("check formatTime format", function() {
  1599. var string = '123'
  1600. var result = '123'
  1601. var verify = App.Utils.formatTime(string, 0)
  1602. equal(verify, result, string)
  1603. string = '6'
  1604. result = '06'
  1605. verify = App.Utils.formatTime(string, 2)
  1606. equal(verify, result, string)
  1607. string = ''
  1608. result = '00'
  1609. verify = App.Utils.formatTime(string, 2)
  1610. equal(verify, result, string)
  1611. string = undefined
  1612. result = ''
  1613. verify = App.Utils.formatTime(string, 2)
  1614. equal(verify, result, string)
  1615. string = null
  1616. result = ''
  1617. verify = App.Utils.formatTime(string, 2)
  1618. equal(verify, result, string)
  1619. });
  1620. // check diffPosition
  1621. test("check diffPosition format", function() {
  1622. var a = [1,2,3,4]
  1623. var b = [1,2,3,4,5]
  1624. var result = [
  1625. {
  1626. position: 4,
  1627. id: 5,
  1628. },
  1629. ]
  1630. var verify = App.Utils.diffPositionAdd(a, b)
  1631. deepEqual(verify, result)
  1632. a = [2,3,4]
  1633. b = [1,2,3,4]
  1634. result = [
  1635. {
  1636. position: 0,
  1637. id: 1,
  1638. },
  1639. ]
  1640. verify = App.Utils.diffPositionAdd(a, b)
  1641. deepEqual(verify, result)
  1642. a = [2,3,4]
  1643. b = [1,2,3,4,5]
  1644. result = [
  1645. {
  1646. position: 0,
  1647. id: 1,
  1648. },
  1649. {
  1650. position: 4,
  1651. id: 5,
  1652. },
  1653. ]
  1654. verify = App.Utils.diffPositionAdd(a, b)
  1655. deepEqual(verify, result)
  1656. a = [2,3,4]
  1657. b = [1,99,12,2,3,4,5]
  1658. result = [
  1659. {
  1660. position: 0,
  1661. id: 1,
  1662. },
  1663. {
  1664. position: 1,
  1665. id: 99,
  1666. },
  1667. {
  1668. position: 2,
  1669. id: 12,
  1670. },
  1671. {
  1672. position: 6,
  1673. id: 5,
  1674. },
  1675. ]
  1676. verify = App.Utils.diffPositionAdd(a, b)
  1677. deepEqual(verify, result)
  1678. a = [4,3,1]
  1679. b = [1,2,3,4,5]
  1680. result = false
  1681. verify = App.Utils.diffPositionAdd(a, b)
  1682. deepEqual(verify, result)
  1683. a = ['Ticket-347', 'TicketCreateScreen-2217']
  1684. b = ['Ticket-347', 'TicketCreateScreen-2217', 'TicketCreateScreen-71517']
  1685. result = [
  1686. {
  1687. position: 2,
  1688. id: 'TicketCreateScreen-71517',
  1689. },
  1690. ]
  1691. verify = App.Utils.diffPositionAdd(a, b)
  1692. deepEqual(verify, result)
  1693. });
  1694. // check textLengthWithUrl format
  1695. test("check textLengthWithUrl format", function() {
  1696. var string = '123'
  1697. var result = 3
  1698. var verify = App.Utils.textLengthWithUrl(string)
  1699. equal(verify, result)
  1700. string = '123 http is not here'
  1701. result = 20
  1702. verify = App.Utils.textLengthWithUrl(string)
  1703. equal(verify, result)
  1704. string = '123 http://host is not here'
  1705. result = 39
  1706. verify = App.Utils.textLengthWithUrl(string)
  1707. equal(verify, result)
  1708. string = '123 http://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX is not here'
  1709. result = 39
  1710. verify = App.Utils.textLengthWithUrl(string)
  1711. equal(verify, result)
  1712. string = 'http://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1713. result = 23
  1714. verify = App.Utils.textLengthWithUrl(string)
  1715. equal(verify, result)
  1716. string = 'http://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX, some other text'
  1717. result = 23 + 17
  1718. verify = App.Utils.textLengthWithUrl(string)
  1719. equal(verify, result)
  1720. string = 'some other text,http://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1721. result = 23 + 16
  1722. verify = App.Utils.textLengthWithUrl(string)
  1723. equal(verify, result)
  1724. string = 'some other text, http://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX?abc=123;aaa=ab+c usw'
  1725. result = 23 + 21
  1726. verify = App.Utils.textLengthWithUrl(string)
  1727. equal(verify, result)
  1728. });
  1729. // check getRecipientArticle format
  1730. test('check getRecipientArticle format', function() {
  1731. var customer = {
  1732. login: 'login',
  1733. firstname: 'firstname',
  1734. lastname: 'lastname',
  1735. email: 'customer@example.com',
  1736. }
  1737. var ticket = {
  1738. customer: customer,
  1739. }
  1740. var article = {
  1741. type: {
  1742. name: 'phone',
  1743. },
  1744. sender: {
  1745. name: 'Customer',
  1746. },
  1747. from: customer.email,
  1748. to: 'some group',
  1749. message_id: 'message_id1',
  1750. created_by: {
  1751. login: 'login',
  1752. firstname: 'firstname',
  1753. lastname: 'lastname',
  1754. email: 'article_created_by@example.com',
  1755. },
  1756. }
  1757. var result = {
  1758. to: 'customer@example.com',
  1759. cc: '',
  1760. body: '',
  1761. in_reply_to: 'message_id1',
  1762. }
  1763. var verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  1764. deepEqual(verify, result)
  1765. customer = {
  1766. login: 'login',
  1767. firstname: 'firstname',
  1768. lastname: 'lastname',
  1769. email: 'customer@example.com',
  1770. }
  1771. ticket = {
  1772. customer: customer,
  1773. }
  1774. article = {
  1775. type: {
  1776. name: 'phone',
  1777. },
  1778. sender: {
  1779. name: 'Customer',
  1780. },
  1781. from: customer.email,
  1782. message_id: 'message_id2',
  1783. created_by: {
  1784. login: 'login',
  1785. firstname: 'firstname',
  1786. lastname: 'lastname',
  1787. email: 'article_created_by@example.com',
  1788. },
  1789. }
  1790. result = {
  1791. to: customer.email,
  1792. cc: '',
  1793. body: '',
  1794. in_reply_to: 'message_id2',
  1795. }
  1796. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  1797. deepEqual(verify, result)
  1798. customer = {
  1799. login: 'login',
  1800. firstname: 'firstname',
  1801. lastname: 'lastname',
  1802. email: 'customer@example.com',
  1803. }
  1804. ticket = {
  1805. customer: customer,
  1806. }
  1807. article = {
  1808. message_id: 'message_id3',
  1809. type: {
  1810. name: 'phone',
  1811. },
  1812. sender: {
  1813. name: 'Agent',
  1814. },
  1815. from: 'article_created_by@example.com',
  1816. created_by: {
  1817. login: 'login',
  1818. firstname: 'firstname',
  1819. lastname: 'lastname',
  1820. email: 'article_created_by@example.com',
  1821. },
  1822. }
  1823. result = {
  1824. to: 'customer@example.com',
  1825. cc: '',
  1826. body: '',
  1827. in_reply_to: 'message_id3',
  1828. }
  1829. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  1830. deepEqual(verify, result)
  1831. customer = {
  1832. login: 'login',
  1833. firstname: 'firstname',
  1834. lastname: 'lastname',
  1835. email: 'customer@example.com',
  1836. }
  1837. ticket = {
  1838. customer: customer,
  1839. }
  1840. article = {
  1841. message_id: 'message_id4',
  1842. created_by: customer,
  1843. type: {
  1844. name: 'web',
  1845. },
  1846. sender: {
  1847. name: 'Customer',
  1848. },
  1849. from: customer.email,
  1850. to: 'some group',
  1851. created_by: {
  1852. login: 'login',
  1853. firstname: 'firstname',
  1854. lastname: 'lastname',
  1855. email: 'article_created_by@example.com',
  1856. },
  1857. }
  1858. result = {
  1859. to: 'customer@example.com',
  1860. cc: '',
  1861. body: '',
  1862. in_reply_to: 'message_id4',
  1863. }
  1864. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  1865. deepEqual(verify, result)
  1866. customer = {
  1867. login: 'login',
  1868. firstname: 'firstname',
  1869. lastname: 'lastname',
  1870. email: 'customer@example.com',
  1871. }
  1872. ticket = {
  1873. customer: customer,
  1874. }
  1875. article = {
  1876. message_id: 'message_id5',
  1877. type: {
  1878. name: 'web',
  1879. },
  1880. sender: {
  1881. name: 'Customer',
  1882. },
  1883. from: customer.email,
  1884. created_by: {
  1885. login: 'login',
  1886. firstname: 'firstname',
  1887. lastname: 'lastname',
  1888. email: 'article_created_by@example.com',
  1889. }
  1890. }
  1891. result = {
  1892. to: 'customer@example.com',
  1893. cc: '',
  1894. body: '',
  1895. in_reply_to: 'message_id5',
  1896. }
  1897. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  1898. deepEqual(verify, result)
  1899. customer = {
  1900. login: 'login',
  1901. firstname: 'firstname',
  1902. lastname: 'lastname',
  1903. email: 'customer@example.com',
  1904. }
  1905. ticket = {
  1906. customer: customer,
  1907. }
  1908. article = {
  1909. message_id: 'message_id6',
  1910. type: {
  1911. name: 'email',
  1912. },
  1913. sender: {
  1914. name: 'Customer',
  1915. },
  1916. from: customer.email,
  1917. to: 'some group',
  1918. created_by: {
  1919. login: 'login',
  1920. firstname: 'firstname',
  1921. lastname: 'lastname',
  1922. email: 'article_created_by@example.com',
  1923. }
  1924. }
  1925. result = {
  1926. to: 'customer@example.com',
  1927. cc: '',
  1928. body: '',
  1929. in_reply_to: 'message_id6',
  1930. }
  1931. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  1932. deepEqual(verify, result)
  1933. customer = {
  1934. login: 'login',
  1935. firstname: 'firstname',
  1936. lastname: 'lastname',
  1937. email: 'customer@example.com',
  1938. }
  1939. ticket = {
  1940. customer: customer,
  1941. }
  1942. article = {
  1943. message_id: 'message_id7',
  1944. type: {
  1945. name: 'email',
  1946. },
  1947. sender: {
  1948. name: 'Customer',
  1949. },
  1950. from: 'some other invalid part, ' + customer.email,
  1951. to: 'some group',
  1952. created_by: {
  1953. login: 'login',
  1954. firstname: 'firstname',
  1955. lastname: 'lastname',
  1956. email: 'article_created_by@example.com',
  1957. }
  1958. }
  1959. result = {
  1960. to: 'customer@example.com',
  1961. cc: '',
  1962. body: '',
  1963. in_reply_to: 'message_id7',
  1964. }
  1965. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  1966. console.log(verify)
  1967. deepEqual(verify, result)
  1968. customer = {
  1969. login: 'login',
  1970. firstname: 'firstname',
  1971. lastname: 'lastname',
  1972. email: 'customer@example.com',
  1973. }
  1974. ticket = {
  1975. customer: customer,
  1976. }
  1977. article = {
  1978. message_id: 'message_id7.1',
  1979. type: {
  1980. name: 'email',
  1981. },
  1982. sender: {
  1983. name: 'Customer',
  1984. },
  1985. from: 'some other invalid part, Some Realname ' + customer.email,
  1986. to: 'some group',
  1987. created_by: {
  1988. login: 'login',
  1989. firstname: 'firstname',
  1990. lastname: 'lastname',
  1991. email: 'article_created_by@example.com',
  1992. }
  1993. }
  1994. result = {
  1995. to: 'customer@example.com',
  1996. cc: '',
  1997. body: '',
  1998. in_reply_to: 'message_id7.1',
  1999. }
  2000. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  2001. console.log(verify)
  2002. deepEqual(verify, result)
  2003. customer = {
  2004. login: 'login',
  2005. firstname: 'firstname',
  2006. lastname: 'lastname',
  2007. email: 'customer@example.com',
  2008. }
  2009. ticket = {
  2010. customer: customer,
  2011. }
  2012. article = {
  2013. message_id: 'message_id7.2',
  2014. type: {
  2015. name: 'email',
  2016. },
  2017. sender: {
  2018. name: 'Customer',
  2019. },
  2020. from: 'some other invalid part, Some Realname ' + customer.email + ' , abc',
  2021. to: 'some group',
  2022. created_by: {
  2023. login: 'login',
  2024. firstname: 'firstname',
  2025. lastname: 'lastname',
  2026. email: 'article_created_by@example.com',
  2027. }
  2028. }
  2029. result = {
  2030. to: 'customer@example.com',
  2031. cc: '',
  2032. body: '',
  2033. in_reply_to: 'message_id7.2',
  2034. }
  2035. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  2036. console.log(verify)
  2037. deepEqual(verify, result)
  2038. customer = {
  2039. login: 'login',
  2040. firstname: 'firstname',
  2041. lastname: 'lastname',
  2042. email: 'customer@example.com',
  2043. }
  2044. agent = {
  2045. login: 'login',
  2046. firstname: 'firstname',
  2047. lastname: 'lastname',
  2048. email: 'agent@example.com',
  2049. }
  2050. ticket = {
  2051. customer: customer,
  2052. }
  2053. article = {
  2054. message_id: 'message_id8',
  2055. created_by: agent,
  2056. type: {
  2057. name: 'email',
  2058. },
  2059. sender: {
  2060. name: 'Agent',
  2061. },
  2062. from: 'customer2@example.com',
  2063. to: 'customer@example.com',
  2064. }
  2065. result = {
  2066. to: 'customer2@example.com',
  2067. cc: '',
  2068. body: '',
  2069. in_reply_to: 'message_id8',
  2070. }
  2071. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  2072. deepEqual(verify, result)
  2073. customer = {
  2074. login: 'login',
  2075. firstname: 'firstname',
  2076. lastname: 'lastname',
  2077. email: 'customer@example.com',
  2078. }
  2079. agent = {
  2080. login: 'login',
  2081. firstname: 'firstname',
  2082. lastname: 'lastname',
  2083. email: 'agent@example.com',
  2084. }
  2085. ticket = {
  2086. customer: customer,
  2087. }
  2088. article = {
  2089. message_id: 'message_id9',
  2090. created_by: agent,
  2091. type: {
  2092. name: 'email',
  2093. },
  2094. sender: {
  2095. name: 'Agent',
  2096. },
  2097. from: 'agent@example.com',
  2098. to: 'customer@example.com',
  2099. }
  2100. result = {
  2101. to: 'customer@example.com',
  2102. cc: '',
  2103. body: '',
  2104. in_reply_to: 'message_id9',
  2105. }
  2106. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  2107. deepEqual(verify, result)
  2108. customer = {
  2109. login: 'login',
  2110. firstname: 'firstname',
  2111. lastname: 'lastname',
  2112. email: 'customer@example.com',
  2113. }
  2114. agent = {
  2115. login: 'login',
  2116. firstname: 'firstname',
  2117. lastname: 'lastname',
  2118. email: 'agent@example.com',
  2119. }
  2120. ticket = {
  2121. customer: customer,
  2122. }
  2123. article = {
  2124. message_id: 'message_id10',
  2125. created_by: agent,
  2126. type: {
  2127. name: 'email',
  2128. },
  2129. sender: {
  2130. name: 'Agent',
  2131. },
  2132. from: 'Agent@Example.com',
  2133. to: 'customer@example.com',
  2134. cc: 'zammad@example.com',
  2135. }
  2136. result = {
  2137. to: 'customer@example.com',
  2138. cc: '',
  2139. body: '',
  2140. in_reply_to: 'message_id10',
  2141. }
  2142. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  2143. deepEqual(verify, result)
  2144. customer = {
  2145. login: 'login',
  2146. firstname: 'firstname',
  2147. lastname: 'lastname',
  2148. email: 'customer@example.com',
  2149. }
  2150. agent = {
  2151. login: 'login',
  2152. firstname: 'firstname',
  2153. lastname: 'lastname',
  2154. email: 'agent@example.com',
  2155. }
  2156. ticket = {
  2157. customer: customer,
  2158. }
  2159. article = {
  2160. message_id: 'message_id11',
  2161. created_by: agent,
  2162. type: {
  2163. name: 'email',
  2164. },
  2165. sender: {
  2166. name: 'Agent',
  2167. },
  2168. from: 'Agent@Example.com',
  2169. to: 'customer@example.com, agent@example.com',
  2170. cc: 'zammad@example.com',
  2171. }
  2172. result = {
  2173. to: 'customer@example.com, agent@example.com',
  2174. cc: 'zammad@example.com',
  2175. body: '',
  2176. in_reply_to: 'message_id11',
  2177. }
  2178. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type, [], true)
  2179. deepEqual(verify, result)
  2180. customer = {
  2181. login: 'login',
  2182. firstname: 'firstname',
  2183. lastname: 'lastname',
  2184. email: 'customer@example.com',
  2185. }
  2186. agent = {
  2187. login: 'login',
  2188. firstname: 'firstname',
  2189. lastname: 'lastname',
  2190. email: 'agent@example.com',
  2191. }
  2192. ticket = {
  2193. customer: customer,
  2194. }
  2195. article = {
  2196. message_id: 'message_id12',
  2197. created_by: agent,
  2198. type: {
  2199. name: 'email',
  2200. },
  2201. sender: {
  2202. name: 'Agent',
  2203. },
  2204. from: 'Agent@Example.com',
  2205. to: 'customeR@EXAMPLE.com, agent@example.com',
  2206. cc: 'zammad@example.com, customer@example.com',
  2207. }
  2208. result = {
  2209. to: 'customer@example.com, agent@example.com',
  2210. cc: 'zammad@example.com',
  2211. body: '',
  2212. in_reply_to: 'message_id12',
  2213. }
  2214. verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, [], true)
  2215. deepEqual(verify, result)
  2216. customer = {
  2217. login: 'login',
  2218. firstname: 'firstname',
  2219. lastname: 'lastname',
  2220. email: 'customer@example.com',
  2221. }
  2222. agent = {
  2223. login: 'login',
  2224. firstname: 'firstname',
  2225. lastname: 'lastname',
  2226. email: 'agent@example.com',
  2227. }
  2228. ticket = {
  2229. customer: customer,
  2230. }
  2231. article = {
  2232. message_id: 'message_id13',
  2233. created_by: agent,
  2234. type: {
  2235. name: 'email',
  2236. },
  2237. sender: {
  2238. name: 'Agent',
  2239. },
  2240. from: 'Agent@Example.com',
  2241. to: 'customeR@EXAMPLE.com, agent@example.com, zammad2@EXAMPLE.com',
  2242. cc: 'zammad@example.com, customer2@example.com',
  2243. }
  2244. result = {
  2245. to: 'customer@example.com, agent@example.com',
  2246. cc: 'customer2@example.com',
  2247. body: '',
  2248. in_reply_to: 'message_id13',
  2249. }
  2250. email_addresses = [
  2251. {
  2252. email: 'zammad@example.com',
  2253. },
  2254. {
  2255. email: 'zammad2@example.com',
  2256. }
  2257. ]
  2258. verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, true)
  2259. deepEqual(verify, result)
  2260. customer = {
  2261. login: 'login',
  2262. firstname: 'firstname',
  2263. lastname: 'lastname',
  2264. email: 'customer@example.com',
  2265. }
  2266. agent = {
  2267. login: 'login',
  2268. firstname: 'firstname',
  2269. lastname: 'lastname',
  2270. email: 'AGENT@example.com',
  2271. }
  2272. ticket = {
  2273. customer: customer,
  2274. }
  2275. article = {
  2276. message_id: 'message_id14',
  2277. created_by: agent,
  2278. type: {
  2279. name: 'email',
  2280. },
  2281. sender: {
  2282. name: 'Agent',
  2283. },
  2284. from: 'Agent@Example.com',
  2285. to: 'customeR@EXAMPLE.com, agent@example.com, zammad2@EXAMPLE.com',
  2286. cc: 'zammad@example.com, customer2@example.com',
  2287. }
  2288. result = {
  2289. to: 'customer@example.com, agent@example.com',
  2290. cc: 'customer2@example.com',
  2291. body: '',
  2292. in_reply_to: 'message_id14',
  2293. }
  2294. email_addresses = [
  2295. {
  2296. email: 'zammad@example.com',
  2297. },
  2298. {
  2299. email: 'zammad2@example.com',
  2300. }
  2301. ]
  2302. verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, true)
  2303. deepEqual(verify, result)
  2304. customer = {
  2305. login: 'login',
  2306. firstname: 'firstname',
  2307. lastname: 'lastname',
  2308. email: 'zammad@example.com',
  2309. }
  2310. ticket = {
  2311. customer: customer,
  2312. }
  2313. article = {
  2314. message_id: 'message_id15',
  2315. created_by: customer,
  2316. type: {
  2317. name: 'email',
  2318. },
  2319. sender: {
  2320. name: 'Agent',
  2321. },
  2322. from: 'zammad@EXAMPLE.com',
  2323. to: 'customeR@EXAMPLE.com, agent@example.com, zammad2@EXAMPLE.com',
  2324. cc: 'zammad@example.com, customer2@example.com',
  2325. }
  2326. result = {
  2327. to: 'customer@example.com, agent@example.com',
  2328. cc: 'customer2@example.com',
  2329. body: '',
  2330. in_reply_to: 'message_id15',
  2331. }
  2332. email_addresses = [
  2333. {
  2334. email: 'zammad@example.com',
  2335. },
  2336. {
  2337. email: 'zammad2@example.com',
  2338. }
  2339. ]
  2340. verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, true)
  2341. deepEqual(verify, result)
  2342. customer = {
  2343. login: 'login',
  2344. firstname: 'firstname',
  2345. lastname: 'lastname',
  2346. email: 'customer@example.com',
  2347. }
  2348. ticket = {
  2349. customer: customer,
  2350. }
  2351. article = {
  2352. message_id: 'message_id16',
  2353. created_by: customer,
  2354. type: {
  2355. name: 'email',
  2356. },
  2357. sender: {
  2358. name: 'Agent',
  2359. },
  2360. from: 'customer@example.com',
  2361. to: 'customer1@example.com, customer2@example.com, zammad@example.com',
  2362. cc: '',
  2363. }
  2364. result = {
  2365. to: 'customer1@example.com, customer2@example.com, customer@example.com',
  2366. cc: '',
  2367. body: '',
  2368. in_reply_to: 'message_id16',
  2369. }
  2370. email_addresses = [
  2371. {
  2372. email: 'zammad@example.com',
  2373. },
  2374. {
  2375. email: 'zammad2@example.com',
  2376. }
  2377. ]
  2378. verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, true)
  2379. deepEqual(verify, result)
  2380. customer = {
  2381. login: 'login',
  2382. firstname: 'firstname',
  2383. lastname: 'lastname',
  2384. email: 'customer@example.com',
  2385. }
  2386. ticket = {
  2387. customer: customer,
  2388. }
  2389. article = {
  2390. message_id: 'message_id17',
  2391. created_by: customer,
  2392. type: {
  2393. name: 'email',
  2394. },
  2395. sender: {
  2396. name: 'Agent',
  2397. },
  2398. from: 'customer@example.com',
  2399. to: 'customer1@example.com, customer2@example.com, zammad@example.com, customer2+2@example.com',
  2400. cc: '',
  2401. }
  2402. result = {
  2403. to: 'customer1@example.com, customer2@example.com, customer2+2@example.com, customer@example.com',
  2404. cc: '',
  2405. body: '',
  2406. in_reply_to: 'message_id17',
  2407. }
  2408. email_addresses = [
  2409. {
  2410. email: 'zammad@example.com',
  2411. },
  2412. {
  2413. email: 'zammad2@example.com',
  2414. }
  2415. ]
  2416. verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, true)
  2417. deepEqual(verify, result)
  2418. customer = {
  2419. login: 'login',
  2420. firstname: 'firstname',
  2421. lastname: 'lastname',
  2422. email: 'customer@example.com',
  2423. }
  2424. agent = {
  2425. login: 'login',
  2426. firstname: 'firstname',
  2427. lastname: 'lastname',
  2428. email: 'zammad@example.com',
  2429. }
  2430. ticket = {
  2431. customer: customer,
  2432. }
  2433. article = {
  2434. message_id: 'message_id18',
  2435. created_by: agent,
  2436. type: {
  2437. name: 'email',
  2438. },
  2439. sender: {
  2440. name: 'Agent',
  2441. },
  2442. from: 'zammad@example.com',
  2443. to: 'customer@example.com',
  2444. cc: '',
  2445. }
  2446. result = {
  2447. to: 'customer@example.com',
  2448. cc: '',
  2449. body: '',
  2450. in_reply_to: 'message_id18',
  2451. }
  2452. email_addresses = [
  2453. {
  2454. email: 'zammad@example.com',
  2455. },
  2456. {
  2457. email: 'zammad2@example.com',
  2458. }
  2459. ]
  2460. verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, true)
  2461. deepEqual(verify, result)
  2462. customer = {
  2463. login: 'login',
  2464. firstname: 'firstname',
  2465. lastname: 'lastname',
  2466. email: 'customer@example.com',
  2467. }
  2468. agent = {
  2469. login: 'login',
  2470. firstname: 'firstname',
  2471. lastname: 'lastname',
  2472. email: 'zammad@example.com',
  2473. }
  2474. ticket = {
  2475. customer: customer,
  2476. }
  2477. article = {
  2478. message_id: 'message_id19',
  2479. created_by: agent,
  2480. type: {
  2481. name: 'email',
  2482. },
  2483. sender: {
  2484. name: 'Agent',
  2485. },
  2486. from: 'Sender <zammad@example.com>',
  2487. to: 'Customer <customer@example.com>',
  2488. cc: '',
  2489. }
  2490. result = {
  2491. to: 'customer@example.com',
  2492. cc: '',
  2493. body: '',
  2494. in_reply_to: 'message_id19',
  2495. }
  2496. email_addresses = [
  2497. {
  2498. email: 'zammad@example.com',
  2499. },
  2500. {
  2501. email: 'zammad2@example.com',
  2502. }
  2503. ]
  2504. verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, false)
  2505. deepEqual(verify, result)
  2506. agent = {
  2507. login: 'login',
  2508. firstname: 'firstname',
  2509. lastname: 'lastname',
  2510. email: 'agent@example.com',
  2511. }
  2512. ticket = {
  2513. customer: agent,
  2514. }
  2515. article = {
  2516. message_id: 'message_id20',
  2517. created_by: agent,
  2518. type: {
  2519. name: 'email',
  2520. },
  2521. sender: {
  2522. name: 'Agent',
  2523. },
  2524. from: 'Agent <Agent@Example.com>',
  2525. to: 'Sender <zammad@example.com>',
  2526. cc: '',
  2527. }
  2528. result = {
  2529. to: 'agent@example.com',
  2530. cc: '',
  2531. body: '',
  2532. in_reply_to: 'message_id20',
  2533. }
  2534. email_addresses = [
  2535. {
  2536. email: 'zammad@example.com',
  2537. },
  2538. {
  2539. email: 'zammad2@example.com',
  2540. }
  2541. ]
  2542. verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, false)
  2543. deepEqual(verify, result)
  2544. agent = {
  2545. login: 'login',
  2546. firstname: 'firstname',
  2547. lastname: 'lastname',
  2548. email: 'agent@example.com',
  2549. }
  2550. ticket = {
  2551. customer: agent,
  2552. }
  2553. article = {
  2554. message_id: 'message_id20',
  2555. created_by: agent,
  2556. type: {
  2557. name: 'email',
  2558. },
  2559. sender: {
  2560. name: 'Agent',
  2561. },
  2562. from: 'Agent <Agent@Example.com>',
  2563. to: 'somebodyelse@example.com, Zammad <zammad@example.com>',
  2564. cc: '',
  2565. }
  2566. result = {
  2567. to: 'agent@example.com',
  2568. cc: '',
  2569. body: '',
  2570. in_reply_to: 'message_id20',
  2571. }
  2572. email_addresses = [
  2573. {
  2574. email: 'zammad@example.com',
  2575. },
  2576. {
  2577. email: 'zammad2@example.com',
  2578. }
  2579. ]
  2580. verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, false)
  2581. deepEqual(verify, result)
  2582. customer = {
  2583. login: 'login',
  2584. firstname: 'firstname',
  2585. lastname: 'lastname',
  2586. email: "'customer@example.com'",
  2587. }
  2588. agent = {
  2589. login: 'login',
  2590. firstname: 'firstname',
  2591. lastname: 'lastname',
  2592. email: 'agent@example.com',
  2593. }
  2594. ticket = {
  2595. customer: customer,
  2596. }
  2597. article = {
  2598. message_id: 'message_id21',
  2599. created_by: agent,
  2600. type: {
  2601. name: 'email',
  2602. },
  2603. sender: {
  2604. name: 'Agent',
  2605. },
  2606. from: customer.email,
  2607. to: 'agent@example.com',
  2608. }
  2609. result = {
  2610. to: 'customer@example.com',
  2611. cc: '',
  2612. body: '',
  2613. in_reply_to: 'message_id21',
  2614. }
  2615. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  2616. deepEqual(verify, result)
  2617. // Regression test for issue #2184
  2618. // Case 1
  2619. // 1. Create a "Received Call" Ticket for article_customer
  2620. // 2. Change the Customer of the ticket to ticket_customer (but article.from still points to article_customer)
  2621. // 3. Reply to the first Article
  2622. // Recipient SHOULD BE Article.from
  2623. var article_customer = {
  2624. login: 'login',
  2625. firstname: 'article',
  2626. lastname: 'lastname',
  2627. email: 'article_customer@example.com',
  2628. }
  2629. var ticket_customer = {
  2630. login: 'login2',
  2631. firstname: 'ticket',
  2632. lastname: 'lastname',
  2633. email: 'ticket_customer@example.com',
  2634. }
  2635. ticket = {
  2636. customer: ticket_customer,
  2637. }
  2638. article = {
  2639. type: {
  2640. name: 'phone',
  2641. },
  2642. sender: {
  2643. name: 'Customer',
  2644. },
  2645. from: 'article lastname <article_customer@example.com>',
  2646. to: 'some group',
  2647. message_id: 'message_id22',
  2648. created_by: {
  2649. login: 'login',
  2650. firstname: 'firstname',
  2651. lastname: 'lastname',
  2652. email: 'article_created_by@example.com',
  2653. },
  2654. }
  2655. result = {
  2656. to: 'article_customer@example.com',
  2657. cc: '',
  2658. body: '',
  2659. in_reply_to: 'message_id22',
  2660. }
  2661. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  2662. deepEqual(verify, result)
  2663. // Regression test for issue #2184
  2664. // Case 2
  2665. // 1. Create a "Outbound Call" Ticket for article_customer
  2666. // 2. Change the Customer of the Ticket to ticket_customer (but article.to still points to article_customer)
  2667. // 3. Reply to the first Article
  2668. // Recipient SHOULD BE Article.to
  2669. article_customer = {
  2670. login: 'login',
  2671. firstname: 'article',
  2672. lastname: 'lastname',
  2673. email: 'article_customer@example.com',
  2674. }
  2675. ticket_customer = {
  2676. login: 'login2',
  2677. firstname: 'ticket',
  2678. lastname: 'lastname',
  2679. email: 'ticket_customer@example.com',
  2680. }
  2681. ticket = {
  2682. customer: ticket_customer,
  2683. }
  2684. article = {
  2685. type: {
  2686. name: 'phone',
  2687. },
  2688. sender: {
  2689. name: 'Agent',
  2690. },
  2691. from: 'agent1@example.com',
  2692. to: article_customer.email,
  2693. message_id: 'message_id23',
  2694. created_by: {
  2695. login: 'login',
  2696. firstname: 'firstname',
  2697. lastname: 'lastname',
  2698. email: 'article_created_by@example.com',
  2699. },
  2700. }
  2701. result = {
  2702. to: 'article_customer@example.com',
  2703. cc: '',
  2704. body: '',
  2705. in_reply_to: 'message_id23',
  2706. }
  2707. verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
  2708. deepEqual(verify, result)
  2709. });
  2710. test("contentTypeCleanup", function() {
  2711. var source = "image/png"
  2712. var should = "image/png"
  2713. var result = App.Utils.contentTypeCleanup(source)
  2714. equal(result, should, source)
  2715. source = "image/png; some.file"
  2716. should = "image/png"
  2717. result = App.Utils.contentTypeCleanup(source)
  2718. equal(result, should, source)
  2719. source = "image/png;some.file"
  2720. should = "image/png"
  2721. result = App.Utils.contentTypeCleanup(source)
  2722. equal(result, should, source)
  2723. source = "image/jpeg;some.file"
  2724. should = "image/jpeg"
  2725. result = App.Utils.contentTypeCleanup(source)
  2726. equal(result, should, source)
  2727. source = "image/jpg;some.file"
  2728. should = "image/jpg"
  2729. result = App.Utils.contentTypeCleanup(source)
  2730. equal(result, should, source)
  2731. source = "image/gif;some.file"
  2732. should = "image/gif"
  2733. result = App.Utils.contentTypeCleanup(source)
  2734. equal(result, should, source)
  2735. source = "image/gif\n;some.file"
  2736. should = "image/gif"
  2737. result = App.Utils.contentTypeCleanup(source)
  2738. equal(result, should, source)
  2739. });
  2740. // htmlImage2DataUrl
  2741. test("htmlImage2DataUrl", function() {
  2742. var source = '<div>test 13</div>'
  2743. var should = '<div>test 13</div>'
  2744. var result = App.Utils.htmlImage2DataUrl(source)
  2745. equal(result, should, source)
  2746. source = 'some test'
  2747. should = 'some test'
  2748. result = App.Utils.htmlImage2DataUrl(source)
  2749. equal(result, should, source)
  2750. source = '<img src="some url">some test'
  2751. should = '<img src="data:,">some test'
  2752. result = App.Utils.htmlImage2DataUrl(source)
  2753. equal(result, should, source)
  2754. source = '<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAADAAEDAREAAhEBAxEB/8QAFAABAAAAAAAAAAAAAAAAAAAACv/EABQQAQAAAAAAAAAAAAAAAAAAAAD/xAAUAQEAAAAAAAAAAAAAAAAAAAAF/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AbgQDv//Z">some test'
  2755. should = '<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAADAAEDAREAAhEBAxEB/8QAFAABAAAAAAAAAAAAAAAAAAAACv/EABQQAQAAAAAAAAAAAAAAAAAAAAD/xAAUAQEAAAAAAAAAAAAAAAAAAAAF/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AbgQDv//Z">some test'
  2756. result = App.Utils.htmlImage2DataUrl(source)
  2757. equal(result, should, source)
  2758. source = '<img src="data:image/jpeg;base64,some_data_123">some <img src="some url">test'
  2759. should = '<img src="data:image/jpeg;base64,some_data_123">some <img src="data:,">test'
  2760. result = App.Utils.htmlImage2DataUrl(source)
  2761. equal(result, should, source)
  2762. source = '<img src="cid:1234">some test'
  2763. should = '<img src="cid:1234">some test'
  2764. result = App.Utils.htmlImage2DataUrl(source)
  2765. equal(result, should, source)
  2766. });
  2767. source = '<img src="/assets/images/avatar-bg.png">some test'
  2768. $('#image2text').html(source)
  2769. var htmlImage2DataUrlTest = function() {
  2770. var result = App.Utils.htmlImage2DataUrl(source)
  2771. test("htmlImage2DataUrl async", function() {
  2772. var result = App.Utils.htmlImage2DataUrl(source)
  2773. ok(result.match(/some test/), source)
  2774. ok(!result.match(/avatar-bg.png/), source)
  2775. ok(result.match(/^\<img src=\"data:image\/png;base64,/), source)
  2776. });
  2777. }
  2778. $('#image2text img').one('load', htmlImage2DataUrlTest)
  2779. }