this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

New: char count for Compose field

Uses pre-compiled regex for perf

+226
+65
package-lock.json
··· 29 29 "autoprefixer": "~10.4.13", 30 30 "postcss": "~8.4.20", 31 31 "postcss-dark-theme-class": "~0.7.3", 32 + "twitter-text": "~3.1.0", 32 33 "vite": "~4.0.3", 33 34 "vite-plugin-pwa": "~0.14.0", 34 35 "workbox-cacheable-response": "~6.5.4", ··· 2930 2931 "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", 2931 2932 "dev": true 2932 2933 }, 2934 + "node_modules/core-js": { 2935 + "version": "2.6.12", 2936 + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", 2937 + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", 2938 + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", 2939 + "dev": true, 2940 + "hasInstallScript": true 2941 + }, 2933 2942 "node_modules/core-js-compat": { 2934 2943 "version": "3.26.1", 2935 2944 "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", ··· 5074 5083 "version": "2.4.1", 5075 5084 "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", 5076 5085 "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" 5086 + }, 5087 + "node_modules/twemoji-parser": { 5088 + "version": "11.0.2", 5089 + "resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-11.0.2.tgz", 5090 + "integrity": "sha512-5kO2XCcpAql6zjdLwRwJjYvAZyDy3+Uj7v1ipBzLthQmDL7Ce19bEqHr3ImSNeoSW2OA8u02XmARbXHaNO8GhA==", 5091 + "dev": true 5092 + }, 5093 + "node_modules/twitter-text": { 5094 + "version": "3.1.0", 5095 + "resolved": "https://registry.npmjs.org/twitter-text/-/twitter-text-3.1.0.tgz", 5096 + "integrity": "sha512-nulfUi3FN6z0LUjYipJid+eiwXvOLb8Ass7Jy/6zsXmZK3URte043m8fL3FyDzrK+WLpyqhHuR/TcARTN/iuGQ==", 5097 + "dev": true, 5098 + "dependencies": { 5099 + "@babel/runtime": "^7.3.1", 5100 + "core-js": "^2.5.0", 5101 + "punycode": "1.4.1", 5102 + "twemoji-parser": "^11.0.2" 5103 + } 5104 + }, 5105 + "node_modules/twitter-text/node_modules/punycode": { 5106 + "version": "1.4.1", 5107 + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 5108 + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", 5109 + "dev": true 5077 5110 }, 5078 5111 "node_modules/type-fest": { 5079 5112 "version": "0.16.0", ··· 7752 7785 "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", 7753 7786 "dev": true 7754 7787 }, 7788 + "core-js": { 7789 + "version": "2.6.12", 7790 + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", 7791 + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", 7792 + "dev": true 7793 + }, 7755 7794 "core-js-compat": { 7756 7795 "version": "3.26.1", 7757 7796 "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", ··· 9315 9354 "version": "2.4.1", 9316 9355 "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", 9317 9356 "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" 9357 + }, 9358 + "twemoji-parser": { 9359 + "version": "11.0.2", 9360 + "resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-11.0.2.tgz", 9361 + "integrity": "sha512-5kO2XCcpAql6zjdLwRwJjYvAZyDy3+Uj7v1ipBzLthQmDL7Ce19bEqHr3ImSNeoSW2OA8u02XmARbXHaNO8GhA==", 9362 + "dev": true 9363 + }, 9364 + "twitter-text": { 9365 + "version": "3.1.0", 9366 + "resolved": "https://registry.npmjs.org/twitter-text/-/twitter-text-3.1.0.tgz", 9367 + "integrity": "sha512-nulfUi3FN6z0LUjYipJid+eiwXvOLb8Ass7Jy/6zsXmZK3URte043m8fL3FyDzrK+WLpyqhHuR/TcARTN/iuGQ==", 9368 + "dev": true, 9369 + "requires": { 9370 + "@babel/runtime": "^7.3.1", 9371 + "core-js": "^2.5.0", 9372 + "punycode": "1.4.1", 9373 + "twemoji-parser": "^11.0.2" 9374 + }, 9375 + "dependencies": { 9376 + "punycode": { 9377 + "version": "1.4.1", 9378 + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 9379 + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", 9380 + "dev": true 9381 + } 9382 + } 9318 9383 }, 9319 9384 "type-fest": { 9320 9385 "version": "0.16.0",
+1
package.json
··· 31 31 "autoprefixer": "~10.4.13", 32 32 "postcss": "~8.4.20", 33 33 "postcss-dark-theme-class": "~0.7.3", 34 + "twitter-text": "~3.1.0", 34 35 "vite": "~4.0.3", 35 36 "vite-plugin-pwa": "~0.14.0", 36 37 "workbox-cacheable-response": "~6.5.4",
+48
scripts/extract-url.js
··· 1 + import fs from 'fs'; 2 + import regexSupplant from 'twitter-text/dist/lib/regexSupplant.js'; 3 + import validDomain from 'twitter-text/dist/regexp/validDomain.js'; 4 + import validPortNumber from 'twitter-text/dist/regexp/validPortNumber.js'; 5 + import validUrlPath from 'twitter-text/dist/regexp/validUrlPath.js'; 6 + import validUrlPrecedingChars from 'twitter-text/dist/regexp/validUrlPrecedingChars.js'; 7 + import validUrlQueryChars from 'twitter-text/dist/regexp/validUrlQueryChars.js'; 8 + import validUrlQueryEndingChars from 'twitter-text/dist/regexp/validUrlQueryEndingChars.js'; 9 + 10 + // The difference with twitter-text's extractURL is that the protocol isn't 11 + // optional. 12 + 13 + const urlRegex = regexSupplant( 14 + '(' + // $1 total match 15 + '(#{validUrlPrecedingChars})' + // $2 Preceeding chracter 16 + '(' + // $3 URL 17 + '(https?:\\/\\/)' + // $4 Protocol (optional) <-- THIS IS THE DIFFERENCE, MISSING '?' AFTER PROTOCOL 18 + '(#{validDomain})' + // $5 Domain(s) 19 + '(?::(#{validPortNumber}))?' + // $6 Port number (optional) 20 + '(\\/#{validUrlPath}*)?' + // $7 URL Path 21 + '(\\?#{validUrlQueryChars}*#{validUrlQueryEndingChars})?' + // $8 Query String 22 + ')' + 23 + ')', 24 + { 25 + validUrlPrecedingChars, 26 + validDomain, 27 + validPortNumber, 28 + validUrlPath, 29 + validUrlQueryChars, 30 + validUrlQueryEndingChars, 31 + }, 32 + 'gi', 33 + ); 34 + 35 + const filePath = 'src/data/url-regex.json'; 36 + fs.writeFile( 37 + filePath, 38 + JSON.stringify({ 39 + source: urlRegex.source, 40 + flags: urlRegex.flags, 41 + }), 42 + (err) => { 43 + if (err) { 44 + console.error(err); 45 + } 46 + console.log(`Wrote ${filePath}`); 47 + }, 48 + );
+59
src/app.css
··· 658 658 background-color: var(--link-color); 659 659 } 660 660 661 + /* DONUT METER */ 662 + 663 + meter.donut { 664 + appearance: none; 665 + } 666 + 667 + meter.donut:is( 668 + ::-webkit-progress-inner-element, 669 + ::-webkit-progress-bar, 670 + ::-webkit-progress-value, 671 + ::-webkit-meter-bar, 672 + ::-webkit-meter-optimum-value, 673 + ::-webkit-meter-suboptimum-value, 674 + ::-webkit-meter-even-less-good-value 675 + ) { 676 + display: none; 677 + } 678 + 679 + meter.donut:is(::-moz-progress-bar, ::-moz-meter-bar) { 680 + background: transparent; 681 + } 682 + 683 + meter.donut { 684 + position: relative; 685 + width: 24px; 686 + height: 24px; 687 + border-radius: 50%; 688 + --fill: calc(var(--percentage) * 1%); 689 + --color: var(--link-color); 690 + --middle-circle: radial-gradient( 691 + circle at 50% 50%, 692 + var(--bg-faded-color) 10px, 693 + transparent 10px 694 + ); 695 + background-image: var(--middle-circle), 696 + conic-gradient(var(--color) var(--fill), var(--bg-faded-blur-color) 0); 697 + } 698 + meter.donut.warning { 699 + --color: var(--orange-color); 700 + } 701 + meter.donut.danger { 702 + --color: var(--red-color); 703 + } 704 + meter.donut.explode { 705 + background-image: none; 706 + } 707 + meter.donut:is(.warning, .danger, .explode):after { 708 + content: attr(data-left); 709 + position: absolute; 710 + top: 50%; 711 + left: 50%; 712 + transform: translate(-50%, -50%); 713 + font-size: 12px; 714 + color: var(--text-insignificant-color); 715 + } 716 + meter.donut:is(.danger, .explode):after { 717 + color: var(--red-color); 718 + } 719 + 661 720 @media (min-width: 40em) { 662 721 html, 663 722 body {
+52
src/components/compose.jsx
··· 4 4 import { useEffect, useMemo, useRef, useState } from 'preact/hooks'; 5 5 import stringLength from 'string-length'; 6 6 7 + import urlRegex from '../data/url-regex'; 7 8 import emojifyText from '../utils/emojify-text'; 8 9 import openCompose from '../utils/open-compose'; 9 10 import store from '../utils/store'; ··· 380 381 }); 381 382 }, []); 382 383 384 + const [charCount, setCharCount] = useState( 385 + textareaRef.current?.value?.length + 386 + spoilerTextRef.current?.value?.length || 0, 387 + ); 388 + const leftChars = maxCharacters - charCount; 389 + const getCharCount = () => { 390 + const { value } = textareaRef.current; 391 + const { value: spoilerText } = spoilerTextRef.current; 392 + return stringLength(countableText(value)) + stringLength(spoilerText); 393 + }; 394 + const updateCharCount = () => { 395 + setCharCount(getCharCount()); 396 + }; 397 + 383 398 return ( 384 399 <div id="compose-container" class={standalone ? 'standalone' : ''}> 385 400 <div class="compose-top"> ··· 543 558 sensitive = sensitive === 'on'; // checkboxes return "on" if checked 544 559 545 560 // Validation 561 + /* Let the backend validate this 546 562 if (stringLength(status) > maxCharacters) { 547 563 alert(`Status is too long! Max characters: ${maxCharacters}`); 548 564 return; ··· 556 572 ); 557 573 return; 558 574 } 575 + */ 559 576 if (poll) { 560 577 if (poll.options.length < 2) { 561 578 alert('Poll must have at least 2 options'); ··· 663 680 style={{ 664 681 opacity: sensitive ? 1 : 0, 665 682 pointerEvents: sensitive ? 'auto' : 'none', 683 + }} 684 + onInput={() => { 685 + updateCharCount(); 666 686 }} 667 687 /> 668 688 <label ··· 738 758 e.target.style.height = value 739 759 ? scrollHeight + offset + 'px' 740 760 : null; 761 + updateCharCount(); 741 762 }} 742 763 style={{ 743 764 maxHeight: `${maxCharacters / 50}em`, ··· 848 869 </button>{' '} 849 870 <div class="spacer" /> 850 871 {uiState === 'loading' && <Loader abrupt />}{' '} 872 + {uiState !== 'loading' && charCount > maxCharacters / 2 && ( 873 + <> 874 + <meter 875 + class={`donut ${ 876 + leftChars <= -10 877 + ? 'explode' 878 + : leftChars <= 0 879 + ? 'danger' 880 + : leftChars <= 20 881 + ? 'warning' 882 + : '' 883 + }`} 884 + value={charCount} 885 + max={maxCharacters} 886 + data-left={leftChars} 887 + style={{ 888 + '--percentage': (charCount / maxCharacters) * 100, 889 + }} 890 + />{' '} 891 + </> 892 + )} 851 893 <button type="submit" class="large" disabled={uiState === 'loading'}> 852 894 {replyToStatus ? 'Reply' : editStatus ? 'Update' : 'Post'} 853 895 </button> ··· 1063 1105 return str.replace(/[&<>"']/g, function (char) { 1064 1106 return '&#' + char.charCodeAt(0) + ';'; 1065 1107 }); 1108 + } 1109 + 1110 + // https://github.com/mastodon/mastodon/blob/c4a429ed47e85a6bbf0d470a41cc2f64cf120c19/app/javascript/mastodon/features/compose/util/counter.js 1111 + const urlRegexObj = new RegExp(urlRegex.source, urlRegex.flags); 1112 + const usernameRegex = /(^|[^\/\w])@(([a-z0-9_]+)@[a-z0-9\.\-]+[a-z0-9]+)/gi; 1113 + const urlPlaceholder = '$2xxxxxxxxxxxxxxxxxxxxxxx'; 1114 + function countableText(inputText) { 1115 + return inputText 1116 + .replace(urlRegexObj, urlPlaceholder) 1117 + .replace(usernameRegex, '$1@$3'); 1066 1118 } 1067 1119 1068 1120 export default Compose;
+1
src/data/url-regex.json
··· 1 + {"source":"(((?:[^A-Za-z0-9@@$##\\uFFFE\\uFEFF\\uFFFF]|[\\u202A-\\u202E\\u061C\\u200E\\u200F\\u2066\\u2067\\u2068\\u2069]|^))((https?:\\/\\/)((?:(?:(?:[^/\\!'#%&'\\(\\)*\\+,\\\\\\-\\.\\/:;<=>\\?@\\[\\]\\^_{|}~\\$//\\x09-\\x0D\\x20\\x85\\xA0\\u1680\\u180E\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000//\\uFFFE\\uFEFF\\uFFFF//\\u202A-\\u202E\\u061C\\u200E\\u200F\\u2066\\u2067\\u2068\\u2069/](?:[_-]|[^/\\!'#%&'\\(\\)*\\+,\\\\\\-\\.\\/:;<=>\\?@\\[\\]\\^_{|}~\\$//\\x09-\\x0D\\x20\\x85\\xA0\\u1680\\u180E\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000//\\uFFFE\\uFEFF\\uFFFF//\\u202A-\\u202E\\u061C\\u200E\\u200F\\u2066\\u2067\\u2068\\u2069/])*)?[^/\\!'#%&'\\(\\)*\\+,\\\\\\-\\.\\/:;<=>\\?@\\[\\]\\^_{|}~\\$//\\x09-\\x0D\\x20\\x85\\xA0\\u1680\\u180E\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000//\\uFFFE\\uFEFF\\uFFFF//\\u202A-\\u202E\\u061C\\u200E\\u200F\\u2066\\u2067\\u2068\\u2069/]\\.)*(?:(?:[^/\\!'#%&'\\(\\)*\\+,\\\\\\-\\.\\/:;<=>\\?@\\[\\]\\^_{|}~\\$//\\x09-\\x0D\\x20\\x85\\xA0\\u1680\\u180E\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000//\\uFFFE\\uFEFF\\uFFFF//\\u202A-\\u202E\\u061C\\u200E\\u200F\\u2066\\u2067\\u2068\\u2069/](?:-|[^/\\!'#%&'\\(\\)*\\+,\\\\\\-\\.\\/:;<=>\\?@\\[\\]\\^_{|}~\\$//\\x09-\\x0D\\x20\\x85\\xA0\\u1680\\u180E\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000//\\uFFFE\\uFEFF\\uFFFF//\\u202A-\\u202E\\u061C\\u200E\\u200F\\u2066\\u2067\\u2068\\u2069/])*)?[^/\\!'#%&'\\(\\)*\\+,\\\\\\-\\.\\/:;<=>\\?@\\[\\]\\^_{|}~\\$//\\x09-\\x0D\\x20\\x85\\xA0\\u1680\\u180E\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000//\\uFFFE\\uFEFF\\uFFFF//\\u202A-\\u202E\\u061C\\u200E\\u200F\\u2066\\u2067\\u2068\\u2069/]\\.)(?:(?:(?:삼성|닷컴|닷넷|香格里拉|餐厅|食品|飞利浦|電訊盈科|集团|通販|购物|谷歌|诺基亚|联通|网络|网站|网店|网址|组织机构|移动|珠宝|点看|游戏|淡马锡|机构|書籍|时尚|新闻|政府|政务|招聘|手表|手机|我爱你|慈善|微博|广东|工行|家電|娱乐|天主教|大拿|大众汽车|在线|嘉里大酒店|嘉里|商标|商店|商城|公益|公司|八卦|健康|信息|佛山|企业|中文网|中信|世界|ポイント|ファッション|セール|ストア|コム|グーグル|クラウド|みんな|คอม|संगठन|नेट|कॉम|همراه|موقع|موبايلي|كوم|كاثوليك|عرب|شبكة|بيتك|بازار|العليان|ارامكو|اتصالات|ابوظبي|קום|сайт|рус|орг|онлайн|москва|ком|католик|дети|zuerich|zone|zippo|zip|zero|zara|zappos|yun|youtube|you|yokohama|yoga|yodobashi|yandex|yamaxun|yahoo|yachts|xyz|xxx|xperia|xin|xihuan|xfinity|xerox|xbox|wtf|wtc|wow|world|works|work|woodside|wolterskluwer|wme|winners|wine|windows|win|williamhill|wiki|wien|whoswho|weir|weibo|wedding|wed|website|weber|webcam|weatherchannel|weather|watches|watch|warman|wanggou|wang|walter|walmart|wales|vuelos|voyage|voto|voting|vote|volvo|volkswagen|vodka|vlaanderen|vivo|viva|vistaprint|vista|vision|visa|virgin|vip|vin|villas|viking|vig|video|viajes|vet|versicherung|vermögensberatung|vermögensberater|verisign|ventures|vegas|vanguard|vana|vacations|ups|uol|uno|university|unicom|uconnect|ubs|ubank|tvs|tushu|tunes|tui|tube|trv|trust|travelersinsurance|travelers|travelchannel|travel|training|trading|trade|toys|toyota|town|tours|total|toshiba|toray|top|tools|tokyo|today|tmall|tkmaxx|tjx|tjmaxx|tirol|tires|tips|tiffany|tienda|tickets|tiaa|theatre|theater|thd|teva|tennis|temasek|telefonica|telecity|tel|technology|tech|team|tdk|tci|taxi|tax|tattoo|tatar|tatamotors|target|taobao|talk|taipei|tab|systems|symantec|sydney|swiss|swiftcover|swatch|suzuki|surgery|surf|support|supply|supplies|sucks|style|study|studio|stream|store|storage|stockholm|stcgroup|stc|statoil|statefarm|statebank|starhub|star|staples|stada|srt|srl|spreadbetting|spot|sport|spiegel|space|soy|sony|song|solutions|solar|sohu|software|softbank|social|soccer|sncf|smile|smart|sling|skype|sky|skin|ski|site|singles|sina|silk|shriram|showtime|show|shouji|shopping|shop|shoes|shiksha|shia|shell|shaw|sharp|shangrila|sfr|sexy|sex|sew|seven|ses|services|sener|select|seek|security|secure|seat|search|scot|scor|scjohnson|science|schwarz|schule|school|scholarships|schmidt|schaeffler|scb|sca|sbs|sbi|saxo|save|sas|sarl|sapo|sap|sanofi|sandvikcoromant|sandvik|samsung|samsclub|salon|sale|sakura|safety|safe|saarland|ryukyu|rwe|run|ruhr|rugby|rsvp|room|rogers|rodeo|rocks|rocher|rmit|rip|rio|ril|rightathome|ricoh|richardli|rich|rexroth|reviews|review|restaurant|rest|republican|report|repair|rentals|rent|ren|reliance|reit|reisen|reise|rehab|redumbrella|redstone|red|recipes|realty|realtor|realestate|read|raid|radio|racing|qvc|quest|quebec|qpon|pwc|pub|prudential|pru|protection|property|properties|promo|progressive|prof|productions|prod|pro|prime|press|praxi|pramerica|post|porn|politie|poker|pohl|pnc|plus|plumbing|playstation|play|place|pizza|pioneer|pink|ping|pin|pid|pictures|pictet|pics|piaget|physio|photos|photography|photo|phone|philips|phd|pharmacy|pfizer|pet|pccw|pay|passagens|party|parts|partners|pars|paris|panerai|panasonic|pamperedchef|page|ovh|ott|otsuka|osaka|origins|orientexpress|organic|org|orange|oracle|open|ooo|onyourside|online|onl|ong|one|omega|ollo|oldnavy|olayangroup|olayan|okinawa|office|off|observer|obi|nyc|ntt|nrw|nra|nowtv|nowruz|now|norton|northwesternmutual|nokia|nissay|nissan|ninja|nikon|nike|nico|nhk|ngo|nfl|nexus|nextdirect|next|news|newholland|new|neustar|network|netflix|netbank|net|nec|nba|navy|natura|nationwide|name|nagoya|nadex|nab|mutuelle|mutual|museum|mtr|mtpc|mtn|msd|movistar|movie|mov|motorcycles|moto|moscow|mortgage|mormon|mopar|montblanc|monster|money|monash|mom|moi|moe|moda|mobily|mobile|mobi|mma|mls|mlb|mitsubishi|mit|mint|mini|mil|microsoft|miami|metlife|merckmsd|meo|menu|men|memorial|meme|melbourne|meet|media|med|mckinsey|mcdonalds|mcd|mba|mattel|maserati|marshalls|marriott|markets|marketing|market|map|mango|management|man|makeup|maison|maif|madrid|macys|luxury|luxe|lupin|lundbeck|ltda|ltd|lplfinancial|lpl|love|lotto|lotte|london|lol|loft|locus|locker|loans|loan|llp|llc|lixil|living|live|lipsy|link|linde|lincoln|limo|limited|lilly|like|lighting|lifestyle|lifeinsurance|life|lidl|liaison|lgbt|lexus|lego|legal|lefrak|leclerc|lease|lds|lawyer|law|latrobe|latino|lat|lasalle|lanxess|landrover|land|lancome|lancia|lancaster|lamer|lamborghini|ladbrokes|lacaixa|kyoto|kuokgroup|kred|krd|kpn|kpmg|kosher|komatsu|koeln|kiwi|kitchen|kindle|kinder|kim|kia|kfh|kerryproperties|kerrylogistics|kerryhotels|kddi|kaufen|juniper|juegos|jprs|jpmorgan|joy|jot|joburg|jobs|jnj|jmp|jll|jlc|jio|jewelry|jetzt|jeep|jcp|jcb|java|jaguar|iwc|iveco|itv|itau|istanbul|ist|ismaili|iselect|irish|ipiranga|investments|intuit|international|intel|int|insure|insurance|institute|ink|ing|info|infiniti|industries|inc|immobilien|immo|imdb|imamat|ikano|iinet|ifm|ieee|icu|ice|icbc|ibm|hyundai|hyatt|hughes|htc|hsbc|how|house|hotmail|hotels|hoteles|hot|hosting|host|hospital|horse|honeywell|honda|homesense|homes|homegoods|homedepot|holiday|holdings|hockey|hkt|hiv|hitachi|hisamitsu|hiphop|hgtv|hermes|here|helsinki|help|healthcare|health|hdfcbank|hdfc|hbo|haus|hangout|hamburg|hair|guru|guitars|guide|guge|gucci|guardian|group|grocery|gripe|green|gratis|graphics|grainger|gov|got|gop|google|goog|goodyear|goodhands|goo|golf|goldpoint|gold|godaddy|gmx|gmo|gmbh|gmail|globo|global|gle|glass|glade|giving|gives|gifts|gift|ggee|george|genting|gent|gea|gdn|gbiz|gay|garden|gap|games|game|gallup|gallo|gallery|gal|fyi|futbol|furniture|fund|fun|fujixerox|fujitsu|ftr|frontier|frontdoor|frogans|frl|fresenius|free|fox|foundation|forum|forsale|forex|ford|football|foodnetwork|food|foo|fly|flsmidth|flowers|florist|flir|flights|flickr|fitness|fit|fishing|fish|firmdale|firestone|fire|financial|finance|final|film|fido|fidelity|fiat|ferrero|ferrari|feedback|fedex|fast|fashion|farmers|farm|fans|fan|family|faith|fairwinds|fail|fage|extraspace|express|exposed|expert|exchange|everbank|events|eus|eurovision|etisalat|esurance|estate|esq|erni|ericsson|equipment|epson|epost|enterprises|engineering|engineer|energy|emerck|email|education|edu|edeka|eco|eat|earth|dvr|dvag|durban|dupont|duns|dunlop|duck|dubai|dtv|drive|download|dot|doosan|domains|doha|dog|dodge|doctor|docs|dnp|diy|dish|discover|discount|directory|direct|digital|diet|diamonds|dhl|dev|design|desi|dentist|dental|democrat|delta|deloitte|dell|delivery|degree|deals|dealer|deal|dds|dclk|day|datsun|dating|date|data|dance|dad|dabur|cyou|cymru|cuisinella|csc|cruises|cruise|crs|crown|cricket|creditunion|creditcard|credit|cpa|courses|coupons|coupon|country|corsica|coop|cool|cookingchannel|cooking|contractors|contact|consulting|construction|condos|comsec|computer|compare|company|community|commbank|comcast|com|cologne|college|coffee|codes|coach|clubmed|club|cloud|clothing|clinique|clinic|click|cleaning|claims|cityeats|city|citic|citi|citadel|cisco|circle|cipriani|church|chrysler|chrome|christmas|chloe|chintai|cheap|chat|chase|charity|channel|chanel|cfd|cfa|cern|ceo|center|ceb|cbs|cbre|cbn|cba|catholic|catering|cat|casino|cash|caseih|case|casa|cartier|cars|careers|career|care|cards|caravan|car|capitalone|capital|capetown|canon|cancerresearch|camp|camera|cam|calvinklein|call|cal|cafe|cab|bzh|buzz|buy|business|builders|build|bugatti|budapest|brussels|brother|broker|broadway|bridgestone|bradesco|box|boutique|bot|boston|bostik|bosch|boots|booking|book|boo|bond|bom|bofa|boehringer|boats|bnpparibas|bnl|bmw|bms|blue|bloomberg|blog|blockbuster|blanco|blackfriday|black|biz|bio|bingo|bing|bike|bid|bible|bharti|bet|bestbuy|best|berlin|bentley|beer|beauty|beats|bcn|bcg|bbva|bbt|bbc|bayern|bauhaus|basketball|baseball|bargains|barefoot|barclays|barclaycard|barcelona|bar|bank|band|bananarepublic|banamex|baidu|baby|azure|axa|aws|avianca|autos|auto|author|auspost|audio|audible|audi|auction|attorney|athleta|associates|asia|asda|arte|art|arpa|army|archi|aramco|arab|aquarelle|apple|app|apartments|aol|anz|anquan|android|analytics|amsterdam|amica|amfam|amex|americanfamily|americanexpress|alstom|alsace|ally|allstate|allfinanz|alipay|alibaba|alfaromeo|akdn|airtel|airforce|airbus|aigo|aig|agency|agakhan|africa|afl|afamilycompany|aetna|aero|aeg|adult|ads|adac|actor|active|aco|accountants|accountant|accenture|academy|abudhabi|abogado|able|abc|abbvie|abbott|abb|abarth|aarp|aaa|onion)(?=[^0-9a-zA-Z@+-]|$))|(?:(?:한국|香港|澳門|新加坡|台灣|台湾|中國|中国|გე|ລາວ|ไทย|ලංකා|ഭാരതം|ಭಾರತ|భారత్|சிங்கப்பூர்|இலங்கை|இந்தியா|ଭାରତ|ભારત|ਭਾਰਤ|ভাৰত|ভারত|বাংলা|भारोत|भारतम्|भारत|ڀارت|پاکستان|موريتانيا|مليسيا|مصر|قطر|فلسطين|عمان|عراق|سورية|سودان|تونس|بھارت|بارت|ایران|امارات|المغرب|السعودية|الجزائر|البحرين|الاردن|հայ|қаз|укр|срб|рф|мон|мкд|ею|бел|бг|ευ|ελ|zw|zm|za|yt|ye|ws|wf|vu|vn|vi|vg|ve|vc|va|uz|uy|us|um|uk|ug|ua|tz|tw|tv|tt|tr|tp|to|tn|tm|tl|tk|tj|th|tg|tf|td|tc|sz|sy|sx|sv|su|st|ss|sr|so|sn|sm|sl|sk|sj|si|sh|sg|se|sd|sc|sb|sa|rw|ru|rs|ro|re|qa|py|pw|pt|ps|pr|pn|pm|pl|pk|ph|pg|pf|pe|pa|om|nz|nu|nr|np|no|nl|ni|ng|nf|ne|nc|na|mz|my|mx|mw|mv|mu|mt|ms|mr|mq|mp|mo|mn|mm|ml|mk|mh|mg|mf|me|md|mc|ma|ly|lv|lu|lt|ls|lr|lk|li|lc|lb|la|kz|ky|kw|kr|kp|kn|km|ki|kh|kg|ke|jp|jo|jm|je|it|is|ir|iq|io|in|im|il|ie|id|hu|ht|hr|hn|hm|hk|gy|gw|gu|gt|gs|gr|gq|gp|gn|gm|gl|gi|gh|gg|gf|ge|gd|gb|ga|fr|fo|fm|fk|fj|fi|eu|et|es|er|eh|eg|ee|ec|dz|do|dm|dk|dj|de|cz|cy|cx|cw|cv|cu|cr|co|cn|cm|cl|ck|ci|ch|cg|cf|cd|cc|ca|bz|by|bw|bv|bt|bs|br|bq|bo|bn|bm|bl|bj|bi|bh|bg|bf|be|bd|bb|ba|az|ax|aw|au|at|as|ar|aq|ao|an|am|al|ai|ag|af|ae|ad|ac)(?=[^0-9a-zA-Z@+-]|$))|(?:xn--[\\-0-9a-z]+))))(?::([0-9]+))?(\\/(?:(?:[a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]*(?:\\((?:[a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]+|(?:[a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]*\\([a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]+\\)[a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]*))\\)[a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]*)*[\\+\\-a-z\\u0400-\\u04FF0-9=_#\\/\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]|(?:\\((?:[a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]+|(?:[a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]*\\([a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]+\\)[a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]*))\\)))|(?:@[a-z\\u0400-\\u04FF0-9!\\*';:=\\+,\\.\\$\\/%#\\[\\]\\-\\u2013_~@\\|&\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\xFF\\u0100-\\u024F\\u0253\\u0254\\u0256\\u0257\\u0259\\u025B\\u0263\\u0268\\u026F\\u0272\\u0289\\u028B\\u02BB\\u0300-\\u036F\\u1E00-\\u1EFF]+\\/))*)?(\\?[a-z0-9!?\\*'@\\(\\);:&=\\+\\$\\/%#\\[\\]\\-_\\.,~|]*[a-z0-9\\-_&=#\\/])?))","flags":"gi"}