#it also has 0 comments but getting comments on dA as a user who is not even remotely popular is extremely infrequent
Explore tagged Tumblr posts
prismatoxic · 1 year ago
Text
the "most jealous man i know" redraw i did of nateken has 1k views on deviantart and upon seeing that i just said "what" out loud
like. not a ton, all considered, but i checked a bunch of my other submissions and they usually cap out around 400 views at most
and that's usually after several months!!!!
...it'd be nice if it had more than 12 faves though
1 note · View note
chaoticspacefam · 4 years ago
Text
2020 In Review: Wordcount Tag
I was tagged for this by @actualanxiousswampwitch​ , thank you! I’m not sure who’s already done or been tagged for this cause I am, once again, late to the party LOL but I shall (no pressure and sorry if you’ve already done it!) tag: @rainofaugustsith​ , @darth-bagel​ , @thatmmolesbian​ , @thelastenvoyyy​ and anybody else who wants to do this. Yes, I promise I mean you!
Words: 45,314
Published: 0 (I’m not counting the couple of Six Sentence tags I’ve gotten, they’re snippets of an unfinished piece & are included below instead :), or roleplay replies, cause that feels like cheating lol.) I actually wrote a lot more than I thought I had, this is a rough guesstimate as well, as my oneshot WIPs tend to be all over the place across something like 6 different documents, some of which have existed since 2018, so I had to guess at how far up to count from the end for some of them, but I think it’s a fair guesstimate XD I also have included lore/worldbuilding docs in this because that was a 3-month long Lockdown 1.0 Boredom/”Canon is a trash fire so I’m ignoring that and making up my own lore” passion project and I’m goddamn proud of how much I wrote for that. It’s the most I’ve written in one stretch (think I finished it over a span of 3 nights or so, once I’d done all the research and made all the notes ofc ^^)
Not Published: 45,314
The Breakdown:
swtor - 45,314
for creeping shadows (my main longfic/part one of the subterfugeverse series) - 1,553  - Aria, stop being difficult! *shakes fists* XD
oneshots - 16,223
lore/worldbuilding (for subterfugeverse naturally) - 23,001 (is this ALL tomato alien lore? pretty much, yes, yes it is :’D ~400 words is “the WIP reworked timeline to correlate my worldbuilding with the canon timeline that was released”, but 98% is just...me thinking way too much about Purebloods and how they deserved way better goddamn lore. I blame @fluffynexu ‘s amazing tomato worldbuilding posts,  reading them when I went looking for “canon” lore one day for the rp is what got me started down that rabbithole (it’s awesome and if you haven’t already you should totally go check hers out too :DD), I had a “fuck you then canon I’ll do it myself too >:L” moment and once I started I couldn’t stop until I’d crapped out literally over 20k words on the subject *whispering* thank you LOL)
zephyrverse au bonus oneshots - 4,537 (stuff I wrote to fill in time gaps or “just cause I had a plot bunny”, relating to mine and k-christine’s zephyrverse au rp. None of these will likely be posted publicly, but they still deserve to be counted as words I wrote this year :’D
As you can see, most of my “muse” this year came from sporadic oneshots :’D The Ahaszaai twins also properly plot-bunnied their way into my brain in late 2019 and haven’t stopped making a nuisance of themselves the whole fucking year. Every time I tried to carry on with a chapter, one of the two of them would pop up like “Nooo write about ME! pay attention to ME!” - Yes, Ni’kasi, I will get to you this year, I promise XD
New Things I Tried:
Just Writing. Not worrying about whether “it wasn’t part of the next chapter” or “it comes from a part in the story that I’m nowhere near close to posting yet”. If I felt like writing something, or for a specific pairing/feeling/scene, whatever. I wrote until I ran outta muse juice. Yeah, it meant I didn’t technically “finish” anything this year BUT - the important thing is I wrote stuff. and that’s all that really matters, eh? :’D
Polyam ships! May not seem like a big deal but I spent a long time talking myself out of them because of internalised toxic monogamy and finally saying “you know what, fuck it! I can ship three or more people together and it can still be a perfectly wholesome, healthy and loving relationship and that’s okay” was a BIG thing for me this year.
Dialogue Scripts: which I didn’t count as wordcount because really it’s just word vomit of general tone/inflection and dialogue that I came up with right before falling asleep which I didn’t want to lose. Basically, if an exchange or a particularly punchy or moving line of dialogue popped into my brain but I wasn’t ready to write the whole scene that it fit into out, but didn’t want to forget the line(s). I wrote it out in movie script/script-style roleplay fashion e.g. Character’s Name: (emotion, hand gestures etc.) [Dialogue here] and so on. I know this is probably a well known trick of the trade, but I never took it seriously until this year. Seriously, do it. It’s great.
Favorite Thing I Wrote:
Hmmm, a snippet for Andronikos/Ni’kasi that I started this week which isn’t posted yet (saving it for this week’s Six Sentence Sunday so look out for it! :D) was pretty fun to work on, I love their dynamic and Kas is suprisingly fun to write for.
Also the Aria/Vano proposal scene that I posted a snippet for the week before last. I’m having great fun with that scene, and I really enjoy putting a non-serious spin on the classic “proposal scene” tropes. Can’t wait to finish it, though it may be a while before the full one goes up on AO3, as it depends whether it ends up fitting in as part of the mainfic or as an additional oneshot
And I have a D’leah/Kissai oneshot that I need to give another once-over before I finally yeet it onto AO3 and Tumblr for you guys to see :’D
Favorite Fic I Read:
@sleepswithvillains Eleanora/Quinn fic, Helplessly Hoping. I’m horribly behind on chapters and I gotta catch up and read the finale this week, but it’s been a helluva great ride and I’ve thoroughly enjoyed the story! <3
Also The Invitation collab with @tishinada featuring Zas and Fiona had me squealing, I can’t wait to catch up on HH and see more of these two, they’re adorable ;-; @a-muirehen​ ‘s Relu/Merkara series of course! I’m a complete sucker for (friends to lovers to in Ariano’s case but yea pfpfpf) enemies to lovers ships and these two are just so good, I am on the edge of my seat every time we get a new snippet for them, ngl (grimace emoji) @darth-bagel ‘s Sylvas/Graz’zt and Sylvas/Liz/Rilfaen snippets which they’ve been spoiling me with on Discord @mercurypilgrim ‘s Ven’fir/Quinn AU oneshots, Cloudbank (Western was a particular favourite, but all are very good!) and of course @rainofaugustsith ‘s Lana/Viri updates are always fantastic, some personal favourites from this year were Almost There & Memory of Healing :3 (I totally still go back to read Commander & Advisor too sometimes, getting to see Viri be a little diabolical and messing with “MiNiSTeR LoRMaN!” was and still is my favourite thing XD)
If I’ve left you out I’m sorry!! These were the ones that stuck out in my memory, but I’ve loved everyone’s writing this year, it’s been great :3
Writing Goals:
to actually finish and post chapter 8 & 9 of Creeping Shadows. Then we’ll get to the meat and potatoes of the story and maybe Aria will stop being a brat and fighting me every time I try to stick to a semi-regular update schedule Get off my butt, finalise the name and get started on Ni’kasi’s part of the Subterfugeverse story. Maybe run the updates in-tandem with Creeping Shadows but idk if I want to wait till after CS is done before I start posting Kas’s side, or do them side-by-side yet, we’ll see ;) Keep writing! I know better than to pressure myself by setting a specific word count goal, that’s never worked well in the past
At least 2 chapters of each of the works mentioned above would be great though, more would be better! We’ll see how I go
Words of Thanks:
honestly, to everybody in the fandom I’ve met this year. Anybody that I follow, thank you for being there and engaging with me and/or posting amazing content for me to look at! I came over from deviantART where the SWTOR fandom is incredibly small and generally quite inactive and the contrast since moving over here has been incredibly uplifting. I very nearly cancelled Creeping Shadows and stopped posting fic for my SWTORverse altogether because I got next to no engagement on dA and it was very disheartening to the point where I felt I could enjoy the game and the rp partners I had, but the solo projects I’d put so much thought, time and love into already weren’t worth continuing. You guys took that spark and kept it going and I really don’t have enough words to say how grateful I am for that. Even if I haven’t published much this year, making posts on this tumblr, interacting with everyone and working on lore, plot points and so on for Subterfugeverse has kept me going through the Hellish Year of Nightmares that was 2020 <3
to the amazing new friends I’ve made in this past year, who have listened to me ramble about headcanons, character backstories, writing snippets (and rambled/sent some back), keep being awesome: @walk-ng-d-saster , @darth-bagel , @kyber-heart , @deepseacritter , @thedinalixlegacy to further friends and meme tag buddies, I get so excited every time I see a mention for a new meme or ask game in my inbox, so thank you!! : @mimabeann , @palepinkycat , @a-master-procrastinator , @raven-of-domain-kwaad , @actualanxiousswampwitch , @thatmmolesbian , @a-muirehen to my regular commentors/rebloggers/likers/askbox lurkers, I see every one of you and every time your users pop up I grin like a kid in a toy shop: @starlightjedi , @sparkles-and-rust , @wilvarin-chan , @sunsetofdoom , @ask-an-andalite , @thelastenvoyyy . @lyrishadow and more because Tumblr only goes so far back and I have the memory of Swiss Cheese. If you regularly comment, like, reblog, or anything, from me, know that I see you, and I love and appreciate you for it! <3
I couldn’t possibly remember to tag everyone and I promise if I missed you out it’s not because I hate you! Anxiety just sometimes be a bitch and I don’t wanna look like a clown calling someone a “friend” if I’m not explicitly sure we are, in fact, friends. I think you’re all awesome and I’m so glad to have moved over here and met you all <3
10 notes · View notes
insiteandonline · 5 years ago
Text
Glossary: Beginners Guide to Internet Marketing
BEGINNERS GUIDE TO SEO:
GLOSSARY
SEARCH ENGINE OPTIMIZATION (SEO) & OTHER COMMON DIGITAL MEDIA MARKETING TERMINOLOGY, ACRONYMS, PHRASES & JARGON
Tumblr media
Whether you are conducting research, indulging your curiosity or looking for services regarding SEO, you will come across terminology you may be unfamiliar with. Understanding it may prove difficult as many of these terms or phrases are not typically used in the average person's daily life. At,InSite Digital Solutions, we want you to have a better understanding of what Search Engine Optimization is, in order to share a mutual understanding of what we do and why it’s important for your business. We've compiled a list of the most common SEO & Internet Marketing terms along with easy to understand definitions, helping to answer the WHAT’s, WHY’s and the HOW.
NOTE: If you see a term that you feel needs more clarification or don't see a word or phrase you were looking for, please comment below so that it can be added to our glossary as this will continue to be updated regularly.
Constructive criticism always welcome!
*SEO TERMS, PHRASES & JARGON*
A - Z
ALGORITHM (pertaining to Google):
The formula that Google uses in order to accurately rank the top results relating to your search query. Also, it's algorithm helps to locate and remove harmful websites containing things that do not follow their guidelines such as viruses, spam or malware, protecting their online users
ANCHOR TEXT:
Typically in blue and underlined, anchor text is the clickable word or words used to make a link instead of the domain or URL. It is a good SEO practice to make sure this text relates to the page that it links to. An example would be if you saw a link for InSite Digital Solutions that looked like this: “Check out our Home page for more information!" in which the link to the site is there, however, the anchor text is in place of the website's URL
AUDIT:
Tumblr media
Think of an audit as your yearly health check-up. However, instead of you, your website is being analyzed in order to identify any/all strengths and weaknesses. For example, you may receive results about critical issues, threats, risks, opportunities, and feedback, and the strengths and weaknesses overall. It will tell you how much traffic your site is currently pulling in, or if you need keyword optimization, or image optimization plus much more. Once you have gotten your site audit results, your SEO consultant will be able to to help create your marketing plan in order to maximize your site's potential
BACKLINK:
A backlink, also known as an “inbound link” is when a web page provides a link to another site which then “links” the two sites together. An example would be in the resource section on many sites that use outside links which take you to a separate website instead of linking within their own domain. There are two kinds: Internal & External, both defined in this glossary
BLACK HAT SEO:
This type of SEO refers to the use of unethical strategies and practices that go against Google’s rules and regulations. Be wary of those looking to make a quick buck taking the cheapest route & faster than normal results. If a website, or person in charge of it, is caught wrongfully acquiring backlinks through the use of black hat SEO tactics, it can result in complete banishment from the search engines altogether. The phrase "you get what you pay for" is applicable in SEO
Tumblr media
**NOTE: On average, it can take a month or two for optimal SEO results to take full effect, however, when done correctly it generates a very good ROI**
BROKEN LINK:
Also referred to as a “dead link”, a broken link is a link or webpage that no longer works and cannot be accessed by an online user, due to a variety of reasons why. We’ve all seen those error pages that say "Error: 404 PAGE NOT FOUND blah blah blah", right? AKA broken link example.
REASONS YOU MAY HAVE A BROKEN LINK:
Any spelling errors in the link itself
Incorrect URL posted by website's owner
Firewall keeping outside visitors out
Link removed from the destination page (aka landing page)
BROWSER:
A browser is computer software used in order to acquire information on the World Wide Web. Examples of browsers: Google Chrome, Mozilla Firefox, or Microsoft Edge. When you make a request in your browser, you’re instructing your browser to retrieve the resources and information necessary in order to present that page on your media device
CANONICAL TAGS:
A canonical tag is a partial fragment of HTML coding that specifies the primary version, or the original main context page, for deciphering a duplicate, near-duplicate, or similar page. Google, Yahoo, and Microsoft all came together and created them to give website owners an option to quickly solve any duplicate content issues
CLOAKING:
Cloaking is a great example of a black hat SEO tactic. Cloaking is a technique used to obtain a higher search engine rank for certain keywords or phrases. Once the website is created, specific keywords are added to the pages in a way that delivers different results to a search engine's spider bots, (see CRAWLER definition) online users who visit that website are seeing completely different and unrelated content
CONTENT:
In SEO terms, you'll see the word “content” tossed around quite a bit. Content refers to as any and all information that lives on the web and can be read, seen, viewed or absorbed on the web. One of the main parts of SEO is to generate new and updated content on a consistent basis to obtain a higher Pagerank on the search engine results. As a user, it’s what I like to call the noun of the internet- the person, place or thing that you are searching for.. the main substance of the user's interest
CPC: (COST PER CLICK)
The actual dollar amount of money that you are charged when an online user clicks on your paid advertisements
CRAWLER:(SPIDER, WEB SCRAPING, SPIDERBOT)
A program or Internet bot used by search engines to analyze content, “crawl” through internal and external links, and scan the website's data from beginning to end. It’s purpose being to generate entries for a search engine index and provide efficient, relevant searches for the users to browse through
Tumblr media
DE-INDEXING:
De-indexing happens when a website, webpage, or some sort of content is taken down or removed from its index completely (i.e. Google’s database). Once removed AKA de-indexed by a search engine, it does not show up in the search engine results for any search phrases or even with the specified URL
Some things that cause de-indexing involve many black hat SEO tactics such as hidden links, spam, phishing, malware, viruses, cloaking, etc. that strictly goes against Google's rules and regulations
DO-FOLLOW:
A do-follow link is when another website/domain (business, blog, organization, etc.) places a link to your website on one of their web pages. Do-follow links allow crawler bots to crawl through to reach your site in order to pass along Pagerank. These links get credit and value from the search engine as it provides both sites with link juice plus a (relevant and/or quality, let's hope) backlink or external link. If a webmaster is linking back to you with this link both Search Engines and Humans will be able to follow
DOMAIN AUTHORITY (DA): Developed by Moz and also known as Domain Rating (DR)
D.A. is a measurement or “score” of a website’s valuable & relevant links while also showing how likely it is to rank on the SERP (Search Engine Result Page). It is calculated by many factors, however, the quality and quantity of links seem to be at the forefront. The domain authority ranking is on a 0 to 100 scale, and this metric provides a more accurate estimation of the website's ability to get organic search traffic from Google. A higher score renders a higher value and can help you rank higher if linking to or from their site
DEEP LINKING:
Deep linking is the use of a specific hyperlink that links to a certain piece of web content on a website, rather than the website's home page or main page
EXTERNAL LINK:
External Links are hyperlinks that point at any domain other than the current one that the link exists on. For instance, another website that links to your site would be an external link for them or if you link another domain on your site, then that is considered an external link for you
HYPERLINK:
A hyperlink is a clickable link that takes you from your current domain to another domain via references called anchor texts (above in glossary).
INDEXING:
This is the process of adding web pages into Google’s giant search engine database. This is where web crawling comes into play, once the search engine has deployed it's crawler bots that have crawled through the site, it will be able to index it into the database. Think of the website as a book and the database as a library. In order to show up in the search results (library), you have to have your page crawled for content and relevancy before it can become indexed (checked into) into the library
INTERNAL LINK:
Internal links are links used mainly for navigation purposes, linking from one page of a website to another page on the same site. For instance, you may get the home page and any link on there, within the menu or throughout the content, Not only are they used to help users locate similar content and articles but also help in increasing page views and internal page rank, reducing bounce rate, and improving indexing and crawled pages.
KEYWORDS:
In the context of SEO, a keyword is a particular word or phrase that describes the contents of a web page and form part of a web page's metadata. Keywords help search engines match a website or one of its pages with a relevant search query. In other words, they are used when performing a search to help users to describe what type of content they are seeking to find
LANDING PAGE:
Also known as a "lead capture page", this is the page that a visitor “lands” when they have clicked on a Google AdWords ad or result on their result page. In essence, the page that comes up once you've clicked on its link
LSI KEYWORDS:
LSI stands for Latent Semantic Indexing. This is an equation/formula that search engines use to provide accurate search results by predicting patterns in which similar words and phrases are used to better understand the context. For instance, if you put the word “computer” into your search, you may see laptops appear on your result pages. It also helps to understand the difference between an apple you eat and Apple the brand based upon the other words used in the search. (i.e- when searching “apple” online, LSI determines whether to provide information on either the fruit or on the brand based upon other words used in your search such as “calories” and "nutrition" OR “computers” and "iOS")
Tumblr media
LINK BUILDING:
Link Building is the process of getting other websites to link back (placing a link on their website that goes right to your website, or one of its pages) to your website, and vice versa. In some cases, you can exchange links. The higher the quality of the links you have, the better your quality and trust become, and the higher your Domain Authority score will become. It has been said that this is one of the most important parts of SEO but it’s also one of the hardest parts according to many SEO's and other marketing consultants.. and as I carried a "Back Linker" job title previously, I can completely agree with that statement!
LINK FARM:
A link farm is a questionable tactic in SEO where a website is created with the sole purpose being to get backlinks for your website or exchanging reciprocal links to try and increase search engine optimization. In laymen's terms, people create websites just to add links to it, meaning a bunch of random links for all sorts of random types of companies/sites/content, that are not directly related to a certain topic. Again, people use this as a way to obtain backlinks for their website where the quantity of links is the objective. This can hurt your SEO and Pagerank because it would not be considered a quality link or contain relevancy to the content of a website
Tumblr media
METADATA:
Metadata is basically data that describes other data. It provides content-related information about a certain piece of data. For example, when you take a picture, some information like the date, time, location and other info is already saved once it’s taken. For example, a Microsoft Word text document has metadata that contains information about how long the document is, the name of the author, what date the document was written, and a short summary describing the content of the document. Metadata is often in the form of meta tags (See below)
Tumblr media
META TAGS:
Meta tags are pieces of HTML source code that don't appear on the actual page, but it is in the coding to help describe the content on your site to the search engines
NATURAL LINKS:
A natural link is a link that you have obtained outside of your link building strategy, no contact was made to that site to obtain the backlink. You can acquire natural links by having high-quality content and valuable information, amongst many other things, that another website deems beneficial and relevant to their business/cause/website enough to add your link on their website/page
NO FOLLOW:
A no-follow link is typically an external link that a website does not want to pass authority ("support" or "endorse") to, then by using a snippet of HTML relation code, (rel="nofollow") Google does not transfer PageRank across these links. You don't receive credit for these links and the site crawlers cannot crawl through them. This doesn’t help in terms of it showing up in the search engine or giving credit to a site as a backlink, but there is still value within a nofollow link
OFF-PAGE SEO:
Tumblr media
Also called off-site SEO that pertains to any efforts or strategies used outside of a website to improve its search rank. An example of this would be going to local businesses and speaking with them personally to try and get your link on their site as local SEO
ON-PAGE SEO:
AKA Off-page SEO. This is referring to all measures taken directly within the website itself, in order to improve SEO, such as creating new and fresh content for your target audience, increasing page loading speeds, keyword optimization and other examples in the infographic to the left
Tumblr media
ORGANIC TRAFFIC:
Organic traffic refers to all visits to your website directly from search engine search results and not by a paid ad or other means
PAGERANK:
PageRank is a search engine algorithm, invented by Google founders Larry Page and Sergey Brin, that provide a ranking/measurement system for websites to determine the site’s authority and trust as well as its quality and quantity of links on a scale of 0 to 10. By ranking the pages, it provides the user with more accurate results on the results page
PPC:
Stands for Pay-Per-Click and is a form of paid advertisement where advertisers pay ad agencies whenever a potential prospect clicks on their online ad.
QUERY:
In the English language, it means a question or an inquiry. In SEO, it is similar in that it is a request for information, answers, or data from the search engine's database. In laymen's terms, your query is what you type into the search engine bar
ROI:
(Return on Investment) Pretty self-explanatory, but lets throw in some other info. For starters, ROI consists of what you have already invested in a marketing agency and the profitability of that investment. This is why you cannot guarantee SEO (Find out more about ROI and SEO here) If you are doing a Pay Per Click Campaign then the ROI is an easier calculation, if you end up with more money than spent, then you clearly have a positive ROI. It is more difficult to calculate with SEO as SEO ROI involves targeting traffic organically on the result pages (organically, meaning through the community, word of mouth, purchases, subscriptions, other sign-ups etc)
SEO:
SEO- our topic of the hour.. Search Engine Optimization is what it is known as. The best way to explain it is that we are, in a sense, trying to beat the algorithm for Google and other search engines so that the website (client site or your site) is on the right side of the equal sign (literally and figuratively). SEO is accomplished by executing multiple methods like doing continuous updates, keep on researching, staying updated with the algorithm changes, and using resources.... with the main goal of SEO being to help the website obtain a higher PageRank. Or, closest to the top of your search engine result page (SERP), as almost every online user chooses results on the first page. When is the last time you went out to the 16th result page?
SEM:
Search Engine Marketing- similar to SEO as it is used as an umbrella term. However, SEM utilizes PPC techniques and pays for links and advertisements.
**Most people ( do not click on the advertisements and go immediately to the organic results instead, which is what SEO services provide
Tumblr media
SERP:
Search Engine Result Page. A SERP is a page of results that come up after you’ve entered your query into the search engine. Basically, exactly what it stands for
SMM:
Social Media Marketing- a form of internet marketing that uses social media platforms and networking websites as a marketing tool to promote a brand or a particular company
SUBDOMAIN:
a subdomain is just an extension of the main domain, in other words, it is a smaller part of a larger domain in the DNS (Domain Name System) hierarchy. For example: if you visit the URL ilovelamp.com, an example of a subdomain would be something like shop.ilovelamp.com, blog.ilovelamp.com, or faq.ilovelamp.com)
TARGET AUDIENCE:
Your target audience consists of everyone who is searching online for products you make or carry, services you provide, the information you've written on your page, etc. SEO aims to reach your target audience and bring these users to your site to generate traffic
URL:
Uniform Resource Locator- an identifier or specified address to locate a resource or specific piece of content on the internet
Tumblr media
WHITE HAT SEO:
Just the opposite of Black Hat SEO, white hat SEO refers to compliant and approved tactics that are used to improve a website's SEO. No rules are broken to gain higher ranks on SERPs and only quality links with honest tactics that fall under Google’s guidelines
Tumblr media
1 note · View note
hunterpearl289 · 3 years ago
Text
Tutorial For Agarserv
Tumblr media
Create a agario server keyword after analyzing the system lists the list of keywords related and the list of websites with related content, in addition you can see which keywords most interested customers on the this website
Tutorial For Agarserv Drawing
Tutorial For Agarserv Face Mask
Tutorial For Agarserv Windows
Quick Tutorial on how to create a premium server on AgarServ!Check out Rock Agar's channel: https://www.youtube.com/channel/UCgrHwmU9WooJ7MRtOYcWHtw. Copy link Author ZfsrGhS953 commented Dec 30, 2015. Thanks, it worked! Reek added the Request label Dec 30, 2015. Copy link Owner reek commented Dec 30, 2015 @MajkiIT 👍 Copy link. A website to make your personal or private Agar.io server. Apr 07, 2016 And, until now, we tried to limit user bots on agarserv.com. But there are also users who have fun using bots. So our decision is to let the server creator choose if and how to limit the use of bots. Bots are seen by the server as standard players. Usually all bot come from the same ip. But sometimes (mainly those from paid services), comes.
Keyword Suggestions
Most Searched Keywords
San diego courthouse marriage license 2
Authentic pemmican for sale 4
Fulton il windmill 6
Bcpaone home page 8
Spina bifida tuft of hair 10
Homemade mixed fruit wine 12
11th cousin once removed 14
Dr phong nguyen marrero la 16
Can flu raise blood pressure 18
Hp scan smart software 20
Domains Actived Recently
› Alarm.firestormshop.com
Junaid jamshed pakistan. › Bbs.duomiluntan.com
› Ccswrm.kku.ac.th
› Corpuscfc.com
› Mihs.daltonpublicschools.com
› Ngoknumeqefy.mihanblog.com
I am just writing a small python game for fun and I have a function that does the beginning narrative. I am trying to get the audio to play in the background but unfortunately the mp3 file plays first before the function continues. In this video, you're going to learn how to play your computer audio to everyone. This is like playing a track in class (everyone hears the same thing).Get Z. To enable background audio, you must add the background media playback capability to the app manifest file, Package.appxmanifest. To add capabilities to the app manifest using the manifest designer In Microsoft Visual Studio, in Solution Explorer, open the designer for the application manifest by double-clicking the package.appxmanifest item. How to use function generator.
› Perlickcorp.com
› Schako.de
› Sobhiran.com.pagesstudy.com
Websites Listing
We found at least 10 Websites Listing below when search with create a agario server on Search Engine
› make your own agario server
› agar server create your own
› Agario with big food
AGAR SERVER CREATOR - The Browser Pirates - The biggest ..
Create your agar.io server for free. .. (IF THE LINK DOESN'T WORK, CONTACT US AND WE WILL FIX IT) CREATE FREE AGAR.IO SERVER . Email * Game Mode * Bots * CREATE. To create a FREE agar.io private server, you need 3 Credits. Informations about the default servers NOTE: If you want to change the numbers, contact us! ..
DA: 28PA: 25MOZ Rank: 53
AgarServ.com – Create your agar.io server for free
User bots on AgarServ.com There are many discussions about permitting user bots on agar.io .. Read More The Parasite Cell Parasite cells are sticky cells that sticks into players if .. Read More The Beacon Cell Short video to show the Beacon cell feature on Agarserv.com .. Read More WIN CREDITS JUST BROWSING THE SITE …
DA: 16PA: 16MOZ Rank: 17
Agario Private Server Tutorial! MAKE YOUR OWN SERVER ..
Today I will be teaching you guys how to make your own private servers in agario! You can set it up to play with only people you want to play with! You can a..
DA: 15PA: 6MOZ Rank: 21
Agar.io - How To Make An Agario Private Server In 2018 ..
In this video I show you a tutorial on how to make an Agario private server. Recently Agar.io hasn't been allowing players to run their own private custom se..
DA: 15PA: 6MOZ Rank: 21
Agario Private server (on scratch) - Remixes
Agario Private server (on scratch) » Remixes Agar.io Private server remix by lollypoplady; West Campus Move in 2k15 by kadams40; Agar.io Private server remix-2 by TheRedNeckGamer; Agar.io Private server remix by thediamondshaft; Agar.io Private Server W.I.P by RAGOOF; Agar.io Private server by cs89783; Agar.io Private server remix by TipSpy; Agar.io Private server by DevMac
DA: 15PA: 27MOZ Rank: 42
Agario Private Server, Agario Private
Agario.in is an agario server established in 2020. It has been installed similar to websites such as agar.bz, agar.tv and agar.cc. The modes under the Agario.in website are: USA GIANT, EU - EASY, USA - MOD, USA EASY, EU CLASSIC MOD, EU - BIG MOD and USA CRAZY VIRUS modes for free. The servers with the mods are hosted in France and Canada.
DA: 9PA: 9MOZ Rank: 10
User bots on AgarServ.com - Create your agar.io server for ..
When a player connect to the game, the server know that there is 1 connection from 1 ip. If te player dies, the server reset the number of connection from his ip to 0 so he can connect again. But if the player hits the browser reload button or simply closes the browser, the server waits 60 seconds to drop that connections.
DA: 16PA: 27MOZ Rank: 43
Agario Private Server | Bet Server Agario Merge
You can play agario private servers of 100 people on this site. In games you can use the agario skins that were added before on our site and you can play a casual Agario game with your friends. The only goal of the game is to be first in the ranking of leadership.
DA: 22PA: 22MOZ Rank: 23
Agario modded server agario hub
agario modded server, agar.io modded server, agar modded server, agario modded servers, agario hub server
DA: 22PA: 6MOZ Rank: 28
› Aaa safe driving course pa
› Ammonium sulfide atomic formula
› Labonnes in watertown ct flyer
› Light weight mineral oil
Tutorial For Agarserv Drawing
› Aesculap bipolar generator
Chapter 2dynamicsmr.s learning website. › Free prostate test
Top
There are many discussions about permitting user bots on agar.io. First of all what are user bots? In short terms those are bots that autonomously converge to the user using them and feed him. This is possible using some browser’s extensions or some online paid service.
Many users are complaining about this. And, until now, we tried to limit user bots on agarserv.com. But there are also users who have fun using bots. So our decision is to let the server creator choose if and how to limit the use of bots.
Bots are seen by the server as standard players. Usually all bot come from the same ip. But sometimes (mainly those from paid services), comes from ip blocks. So it’s not ever easy to identify them.
Tutorial For Agarserv Face Mask
Anyway we can do something about it. When an user creates a server, he can choose how many connections are allowed from a single ip. If the server creator want to deny bots he can choose 1, if he want to permit them he can choose an higher value.
Tutorial For Agarserv Windows
But choosing 1 has a side effect. When a player connect to the game, the server know that there is 1 connection from 1 ip. If te player dies, the server reset the number of connection from his ip to 0 so he can connect again. But if the player hits the browser reload button or simply closes the browser, the server waits 60 seconds to drop that connections. So the user cannot connect again until the connection has been deleted by the server. And there is no message explaining that to the user. So choosing 1 connection per ip can be a problem. That’s why the predefined option is 3.
Tumblr media
0 notes
womenofcolor15 · 4 years ago
Text
Fans Let Young Thug Know They Aren’t Feeling Him Saying Jay-Z Doesn't Have 30 Songs They Know + Thugga Wants To Battle Lil Wayne In VERZUZ
Tumblr media
Social media users commenced a Twitter dragging of Young Thug after he made some comments about rap icon Jay-Z. Find out what he said, plus who Thugga would like to battle in VERZUZ inside…
Some things are just not up for debate. Like, Jay-Z being one of the greatest Hip Hop legends…period. There’s no arguing this.
However, people are entitled to their own opinions. Except these days when you share your opinions, you’ll get strong reactions from folks who either agree or disagree with you. 
Young Thug decided to enter the group chat about Hip Hop greats and how many hits they have. And dude really woke up and chose ignorance on that day.
The Atlanta rapper mentioned Jay-Z during Gillie Da King and Wallo267’s “Million Dollaz Worth of Game” podcast, saying the Hip Hop pioneer didn’t have a solid 30 tracks that his fans could recite word for word. HIS fans.....meaning Thugga's 12-year-old stans?  Probably.  But since when are a group of 12 year olds who think mumble rap is art the end-all, be-all definitive reresentation of "fans"?
In so many words, Thugga alluded to having more “stadium hits” than Jay-Z, but quickly rolled that back when the co-hosts began to react.
“Jay-Z hasn’t got 30 songs like that,” Thugga said before switching it up.
”I’m just saying like, I know he do, he probably got 50 of them bitches, I”m not literally saying him. I’m saying n***** who you thinking … I seen n***** like, ‘Damn, they don’t know this song?’ I’m so scared to get boo’ed, I don’t even perform songs they won’t know.”
Peep the clip below:
“Jay-Z don’t got 30 songs like that”
We’re dropping the video of episode 93 with Young Thug at 7:30 tonight.
Listen to the audio now: https://t.co/fSrVbeMjiX pic.twitter.com/gZbkHy7AYZ
— MILLION WORTH OF GAME (@mworthofgame) December 28, 2020
As you know, the Internet has zero chill. Folks made sure to gather Thugga for his comments about the rap GOAT.
Young Thug really think he has more hits than Jay Z.... pic.twitter.com/eMf7Eqp18G
— THIRDWARDTHRILLS (@thirdwardtrilll) December 29, 2020
25 years of rapping and Jay-Z don't have 30 songs that a stadium knows and Young Thug does?
Bruh.....cmon
— Keith Nelson Jr (@JusAire) December 29, 2020
young thug really said that he’s better that jay-z? this 2020 is crazy pic.twitter.com/xJjenVtsHR
—  (@FABIOTHEEBARB) December 29, 2020
Young Thug and Jay-Z have Stans. But folks need to understand the difference between having favorites and measuring overall skill/impact. As someone who has had Hov debates with homie's hardcore followers I also understand he is a top 5-3 MC. Some of y'all r doing too much.
— Keith Murphy (@murphdogg29) December 29, 2020
Lemme just place this here for Young Thug. pic.twitter.com/1lr7T3x6He
— Tony Baker (@TonyBakercomedy) December 29, 2020
Well Young Thug says that Jay Z doesn't have 30 songs everyone know but Humm I can count up to 40 with no features and he is a certified BILLIONAIRE so which would you rather be pic.twitter.com/vdcx9bIuil
— damon shields (@godjdamon) December 29, 2020
First it was Andre 3000 and now Thugger saying JAY Z doesn’t have 30 songs people will know
Young Thug needs to just stop talking on legends and focus on releasing PUNK pic.twitter.com/kcI0z77m1Y
— King Wow (@wowthatshiphop) December 28, 2020
In the words of Rihanna during that EPIC beef with Ciara, "Good luck filling that stadium you speak of, Thugga."
Also…
Young Thug says the first time he met Lil Wayne, Wayne gave him the cold shoulder. pic.twitter.com/vYv7Ws4ry4
— Everything Georgia (@GAFollowers) December 29, 2020
”The London” rapper revealed who his dream VERZUZ opponent would be. And it would be none other than Lil Wayne!
“It would probably have to be like [Lil Wayne],” he said. “Because you got to think—we got to talk about influence. We got to talk about everything. We got to talk about everything. It’s not just about no rap.”
“You got to understand, as rapper, as hip-hop artists, you can only go so far,” he added. “I always just focused on the next level.”
Who would you bet your money on? As much as we can't stand the gremlin-in-chief, Thugga has Weezy's name tatt'd on him.  So, it's clear who will win that one 20-0.
You can watch the full hour-long interview below:
youtube
As for his personal life...
Tumblr media
Young Thug wants everyone to know...he's single. And has been supposedly separated from his longtime girlfriend, Jerrika Karlae.
"Been single for dam near 2 years now," he wrote on IG Stories. "Stop thinking everything about me."
Thugga put the post up right after Jerrika said she was bringing in the new year SINGLE. She also made accusations that Thugga was abusive towards her.
single 2021...
— IG : OKAYKARLAE (@OkayKarlae) December 27, 2020
"Why misuse and abuse something or someone, why not leave them be! That’s some narcissistic shit," she tweeted and then deleted. "You behind the scenes painting pictures of me, like ima f*cked up individual…when you the devil."
It was all good earlier this year....
Photo: Jamie Lamor Thompson/Shutterstock.com/AP
[Read More ...] source http://theybf.com/2020/12/29/fans-let-young-thug-know-they-aren%E2%80%99t-feeling-what-he-said-about-jay-z-respectfully
0 notes
suzanneshannon · 6 years ago
Text
Using the Web Speech API for Multilingual Translations
Since the early days of science fiction, we have fantasized about machines that talk to us. Today it is commonplace. Even so, the technology for making websites talk is still pretty new.
We can make our pages on the web talk using the SpeechSynthesis part of the Web Speech API. This is still considered an experimental technology but it has great support in the latest versions of Chrome, Safari, and Firefox.
The fun part for me is using this technology with foreign languages. For that, Mac OSX and most Windows installations have great support on all browsers. Chrome loads a set of voices remotely, so if your operating system does not have international voices installed, just use Chrome. We’re going to walk through a three-step process to create a page that speaks the same text in multiple languages. Some of the basic code is derived from documentation found here but the final product adds some fun features and can be viewed at my Polyglot CodePen here.
Tumblr media
Screen shot of the completed Polyglot app with a menu of languages.
Step 1: Start Simple
Let’s create a basic page with a <textarea> for the text we want the page to speak and include a button to click to trigger the speech.
<div id="wrapper"> <h1>Simple Text To Speech</h1> <p id="warning">Sorry, your browser does not support the Web Speech API.</p> <textarea id="txtFld">I love the sound of my computer-generated voice.</textarea> <label for="txtFld">Type text above. Then click the Speak button.</label> <div> <button type="button" id="speakBtn">Speak</button> <br> <p>Note: For best results on a Mac, use the latest version of Chrome, Safari, or FireFox. On Windows, use Chrome.</p> </div> </div>
The paragraph with ID warning will be shown only if the JavaScript detects no support for the Web Speech API. Also, note the ID values for the textarea and the button as we will use those in our JavaScript.
Feel free to style the HTML any way you’d like. You’re also free to work off the demo I created:
See the Pen Text-To-Speech Part 1 by Steven Estrella (@sgestrella) on CodePen.
Adding a style rule for the disabled state of the button is a good idea to avoid confusion for the few people who still use incompatible browsers, like the now-quaint Internet Explorer. Also, let’s use a style rule to hide the warning by default so we can control when it’s actually needed.
button:disabled { cursor: not-allowed; opacity: 0.3; } #warning { color: red; display: none; font-size: 1.4rem; }
Now on to the JavaScript! First, we add two variables to serve as references to the "Speak" button that triggers the speech and to the <textarea> element. An event listener at the bottom of the code tells the document to wait until the DOM elements load before calling the init() function. I used a handy utility function I call "qs" that is defined at the bottom of the code. It is a shortcut alternative to document.querySelector and it selects whatever selector value I pass to it and returns an object reference. Then we’ll add an event listener to the speakBtn object to make the button call the talk() function.
Tumblr media
The talk() function creates a new instance of the SpeechSynthesisUtterance object that is part of the Web Speech API. It adds the text from the <textarea>(using ID txtFld) to the text property. Then the utterance is passed to the speechSynthesis method of the window object and we hear the spoken text. The specific voice you hear will vary by browser and operating system. On my Mac, for example, my default language is set to American English and the default voice for English is Alex. In Step 2, we will add code to create a menu to help the user choose voices for all available languages.
let speakBtn, txtFld; function init() { speakBtn = qs("#speakBtn"); txtFld = qs("#txtFld"); speakBtn.addEventListener("click", talk, false); if (!window.speechSynthesis) { speakBtn.disabled = true; qs("#warning").style.display = "block"; } } function talk() { let u = new SpeechSynthesisUtterance(); u.text = txtFld.value; speechSynthesis.speak(u); } // Reusable utility functions function qs(selectorText) { // Saves lots of typing for those who eschew jQuery return document.querySelector(selectorText); } document.addEventListener('DOMContentLoaded', function (e) { try {init();} catch (error) { console.log("Data didn't load", error); } });
Step 2: A Menu of International Voices
If we want to use anything other than the default language and speaking voice, we will have to add a bit more code. So that’s what we’re going tackle next.
We’re going to add a select element to hold the menu of voice options:
<h1>Multilingual Text To Speech</h1> <div class="uiunit"> <label for="speakerMenu">Voice: </label> <select id="speakerMenu"></select> speaks <span id="language">English.</span> <!-- etc. --> </div>
Before we create the code to populate the menu options, we should take care of the code that will help us connect language codes to their corresponding names. Each language is identified by a two-letter code such as "en" for English or "es" for Español (Spanish). We will take a simple list of these codes and their corresponding languages and make an array of objects of the form: {"code": "pt", "name": "Portuguese"}. Then we’ll need a utility function to help us search an array of objects for the value of a given property. We will use it in a few minutes to quickly find the language name that matches the language code of the selected voice. Copy the code below so that the two functions are just above and just below the // Generic Utility Functions comment.
function getLanguageTags() { let langs = ["ar-Arabic","cs-Czech","da-Danish","de-German","el-Greek","en-English","eo-Esperanto","es-Spanish","et-Estonian","fi-Finnish","fr-French","he-Hebrew","hi-Hindi","hu-Hungarian","id-Indonesian","it-Italian","ja-Japanese","ko-Korean","la-Latin","lt-Lithuanian","lv-Latvian","nb-Norwegian Bokmal","nl-Dutch","nn-Norwegian Nynorsk","no-Norwegian","pl-Polish","pt-Portuguese","ro-Romanian","ru-Russian","sk-Slovak","sl-Slovenian","sq-Albanian","sr-Serbian","sv-Swedish","th-Thai","tr-Turkish","zh-Chinese"]; let langobjects = []; for (let i=0;i<langs.length;i++) { let langparts = langs[i].split("-"); langobjects.push({"code":langparts[0],"name":langparts[1]}); } return langobjects; } // Generic Utility Functions function searchObjects(array, prop, term, casesensitive = false) { // Searches an array of objects for a given term in a given property // Returns an array of only those objects that test positive let regex = new RegExp(term, casesensitive ? "" : "i"); let newArrayOfObjects = array.filter(obj => regex.test(obj[prop])); return newArrayOfObjects; }
Now we can build out the options for the select element using JavaScript. We need to declare variables at the top of our JavaScript to hold references to the #speakerMenu select element, the #language span element, the array of synthesized voices (allVoices), an array of codes to identify the languages (langtags), and a place to keep track of the currently selected voice (voiceIndex). Add those just after the two variable declarations we created in Step 1.
let speakBtn, txtFld, speakerMenu, language, allVoices, langtags; let voiceIndex = 0;
The updated init() function sets some additional references to the #speakerMenu and the #language span and places all the language codes into an array of objects called langtags. The feature detection part of the code changes here, too. If the Web Speech API is supported, the setUpVoices() function is called. Also, for Chrome, we have to listen for changes to the loaded voices and repeat the setup when needed. Chrome polls the available voices every time you switch between one of its remote voices (the ones listed with the Google prefix while you are in Chrome) and all the other voices which are stored locally in the user’s operating system.
function init() { speakBtn = qs("#speakBtn"); txtFld = qs("#txtFld"); speakerMenu = qs("#speakerMenu"); language = qs("#language"); langtags = getLanguageTags(); speakBtn.addEventListener("click", talk, false); speakerMenu.addEventListener("change", selectSpeaker, false); if (window.speechSynthesis) { if (speechSynthesis.onvoiceschanged !== undefined) { // Chrome gets the voices asynchronously so this is needed speechSynthesis.onvoiceschanged = setUpVoices; } setUpVoices(); // For all the other browsers } else{ speakBtn.disabled = true; speakerMenu.disabled = true; qs("#warning").style.display = "block"; } }
The setUpVoices() function gets an array of what are called SpeechSynthesisVoice objects by calling the getVoices() method of the speechSynthesis object. This is done in our code using the getAllVoices() function. Unfortunately, I have found that the speechSynthesis.getVoices() method sometimes returns duplicates in the list, so I devoted nine lines of code to eliminate the those. Finally, at the end of getAllVoices(), I added a unique identifier number to each of the SpeechSynthesisVoice objects. That will help us in Step 3 when we need to filter the list of voices to only show voices for a given language. When complete, the allVoices array will contain objects that look like the ones below. Each object has id, voiceURI, name, and lang attributes. The localService attribute indicates whether the code for the voice is stored on the user’s computer or remotely on Google’s servers. Notice the lang attribute. The value consists of a two-letter language code (e.g. "es" for Spanish) followed by a dash and a region code (e.g. "MX" for Mexico). This identifies the language and regional accent of each voice.
{id:48, voiceURI:"Paulina", name:"Paulina", lang: "es-MX", localService:true}, {id:52, voiceURI:"Samantha", name:"Samantha", lang: "en-US", localService:true}, {id:72, voiceURI:"Google Deutsch", name:"Google Deutsch", lang: "de-DE", localService:false}
The last line of setUpVoices() calls a function to create the list of options that will appear in the #speakerMenu select element. The value of the id attribute for each voice is placed in the value attribute for the option. The name and lang attributes are the visible text items that appear in each option along with "(premium)" for those voices that are marked that way on some operating systems and browsers.
function setUpVoices() { allVoices = getAllVoices(); createSpeakerMenu(allVoices); } function getAllVoices() { let voicesall = speechSynthesis.getVoices(); let vuris = []; let voices = []; voicesall.forEach(function(obj,index) { let uri = obj.voiceURI; if (!vuris.includes(uri)) { vuris.push(uri); voices.push(obj); } }); voices.forEach(function(obj,index) {obj.id = index;}); return voices; } function createSpeakerMenu(voices) { let code = ; voices.forEach(function(vobj,i) { code += `<option value=${vobj.id}>`; code += `${vobj.name} (${vobj.lang})`; code += vobj.voiceURI.includes(".premium") ? ' (premium)' : ; code += `</option>`; }); speakerMenu.innerHTML = code; speakerMenu.selectedIndex = voiceIndex; }
You might recall that in the init() function, we had set up an event listener to call selectSpeaker() whenever the speakerMenu changes. The selectSpeaker() function stores the selectedIndex of the #speakerMenu select element. Next, it gets the value of the selected item which will be an integer that corresponds to the index of that voice in the allVoices() array. So, now we have retrieved the SpeechSynthesisVoice we want. We then grab the first two letters of the lang attribute (e.g. "en," "es," "ru," "de," "fr") and use that code to search the langtags array of language objects to find the appropriate language name. The searchObjects() function returns an array that will likely have only one entry. Regardless, the first entry (langcodeobj[0]) is all we need. Finally, we assign that name to the innerHTML attribute of the language span and it shows on the screen as expected.
// Code for when the user selects a speaker function selectSpeaker() { voiceIndex = speakerMenu.selectedIndex; let sval = Number(speakerMenu.value); let voice = allVoices[sval]; let langcode = voice.lang.substring(0,2); let langcodeobj = searchObjects(langtags, "code", langcode); language.innerHTML = langcodeobj[0].name; }
The only thing left for Step 2 to be complete is to make sure the talk() function works when we click the "Speak" button. Modify the talk() function to add attributes to the utterance to control which voice and language are used and how fast to speak the text. In my testing, a rate range of 0.5 to 2 works reliably well. I found that a rate below 0.5 has no effect. I think 0.8 works as a nice default for many languages, but as we’ll see in Step 3, there’s an easy way to let the user decide.
function talk() { let sval = Number(speakerMenu.value); let u = new SpeechSynthesisUtterance(); u.voice = allVoices[sval]; u.lang = u.voice.lang; u.text = txtFld.value; u.rate = 0.8; speechSynthesis.speak(u); }
That’s it for Step 2! Here’s the result of what we’ve done so far:
See the Pen Text-To-Speech Part 2 by Steven Estrella (@sgestrella) on CodePen.
Play around with it a bit. Sometimes it is fun to type an English phrase and then assign a French or German speaker to say it. Conversely, if you want to hear your worst first-year Spanish student, type a Spanish phrase and assign it to be spoken by an English voice.
Step 3: The Complete Polyglot
We’re in the final stretch! Some of the things we do in this step will be bits of polish to the UI but there are some functional things we need to do as well to button everything up. specifically, we’re going to:
Create a menu of available language options
Allow users to define the speed of the speech
Define a default phrase in the textarea that translates on language selection
Here’s what we’re looking at:
Tumblr media
We’re adding a dropdown menu, speech rate setting, and a default phrase.
In the HTML, we’re going to add a new <select> element for the language menu and a number input (which will be used later to set the rate of speech). Notice we have deleted the #language span as it is no longer relevant once the language menu is working.
<div class="uiunit"> <label for="languageMenu">Language: </label> <select id="languageMenu"> <option selected value="all">Show All</option> </select> </div> <div class="uiunit"> <label for="speakerMenu">Voice: </label><select id="speakerMenu"></select> </div> <div class="uiunit"> <label for="rateFld">Speed: </label> <input type="number" id="rateFld" min="0.5" max="2" step="0.1" value="0.8" /> </div>
In the JavaScript, we will need to modify the variable declarations. We will keep track of all dialects in the allLanguages array and just the main languages in the primaryLanguages array. The langhash and langcodehash arrays will serve as hash tables so we can quickly get a language name when all we know is the two-letter language code and vice versa. We should only need to setup the languages menu once so a Boolean flag for initialSetup will come in handy.
let speakBtn, txtFld, speakerMenu, allVoices, langtags; let voiceIndex = 0; let allLanguages, primaryLanguages, langhash, langcodehash; let rateFld, languageMenu, blurbs; let initialSetup = true; let defaultBlurb = "I enjoy the traditional music of my native country.";
In the new init() function, let’s remove the line language = qs("#language"); then add the new code as seen here to create the blurbs, reference the rateFld number input and languageMenu select, and create hash tables for looking up language names and tags.
function init() { // ...keep existing content but delete language = qs("#language"); createBlurbs(); rateFld = qs("#rateFld"); languageMenu = qs("#languageMenu"); languageMenu.addEventListener("change", selectLanguage, false); langhash = getLookupTable(langtags, "name"); langcodehash = getLookupTable(langtags, "code"); if (window.speechSynthesis) { // ...keep existing content } else{ // ...keep existing content languageMenu.disabled = true; } }
The setUpVoices() function needs some work to accommodate the new languages menu and to trigger the filterVoices() function which we will use now to populate the #speakerMenu element. Also, we’re going to add the new functions: getAllLanguages() and getPrimaryLanguages(). The first one assembles an array of the unique values for the lang attribute found in the allVoices array of objects. Notice the return statement uses the spread operator combined with a new Set object to ensure that the returned array has no duplicates. The getPrimaryLanguages() function returns an array of the two-letter country codes. That makes a smaller list of just the main languages without reference to regional dialects.
function setUpVoices() { allVoices = getAllVoices(); allLanguages = getAllLanguages(allVoices); primaryLanguages = getPrimaryLanguages(allLanguages); filterVoices(); if (initialSetup && allVoices.length) { initialSetup = false; createLanguageMenu(); } } function getAllLanguages(voices) { let langs = []; voices.forEach(vobj => { langs.push(vobj.lang.trim()); }); return [...new Set(langs)]; } function getPrimaryLanguages(langlist) { let langs = []; langlist.forEach(vobj => { langs.push(vobj.substring(0,2)); }); return [...new Set(langs)]; }
The setUpVoices() function calls two additional functions. The filterVoices() function gets the two-letter language code from the current value of the #languageMenu select menu and uses it to filter the allVoices array and return only the available voice options for the chosen language. It then passes that array to the createSpeakerMenu() function (unchanged from Step 2) which populates the #speakerMenu with options. Then filterVoices() gets the blurb associated with the chosen language and places it in the textarea where it can be edited or replaced.
And, in case Chrome rebuilds this menu, the stored voiceIndex is used to restore the current selection. Next the createLanguageMenu() function uses our hash tables to create the needed menu options for the languageMenu select element. The selectLanguage() function is triggered whenever the user chooses a language. It then triggers filterVoices() and sets the #speakerMenu to display the first available option.
function filterVoices() { let langcode = languageMenu.value; voices = allVoices.filter(function (voice) { return langcode === "all" ? true : voice.lang.indexOf(langcode + "-") >= 0; }); createSpeakerMenu(voices); let t = blurbs[languageMenu.options[languageMenu.selectedIndex].text]; txtFld.value = t ? t : defaultBlurb; speakerMenu.selectedIndex = voiceIndex; } function createLanguageMenu() { let code = `<option selected value="all">Show All</option>`; let langnames = []; primaryLanguages.forEach(function(lobj,i) { langnames.push(langcodehash[lobj.substring(0,2)].name); }); langnames.sort(); langnames.forEach(function(lname,i) { let lcode = langhash[lname].code; code += `<option value=${lcode}>${lname}</option>`; }); languageMenu.innerHTML = code; } function selectLanguage() { filterVoices(); speakerMenu.selectedIndex = 0; }
In the utility functions section of the code toward the bottom, add the following code. This generic little utility will help you the next time you need to create a lookup table for an array of objects. In our case, we will use this to allow us to easily match a language code with its corresponding language name and vice versa.
function getLookupTable(objectsArray, propname) { return objectsArray.reduce((accumulator, currentValue) => (accumulator[currentValue[propname]] = currentValue, accumulator),{}); }
I added an array of text phrases, each of which is a translation of the English phrase, "I enjoy the traditional music of my native country." The language it’s displayed in will correspond to what’s selected in the language men.
Here we see the beauty of UTF-8 on full display. Above the getLanguagesTags() function, let’s add the code that generates all those translated blurbs. I only read Spanish, English, some Portuguese, and very little German, so I have to take on faith that Google Translate is providing accurate translations for the rest. If any of these is your native language, feel free to leave corrections in the comments.
function createBlurbs() { blurbs = { "Arabic" : "أنا أستمتع بالموسيقى التقليدية لبلدي الأم.", "Chinese" : "我喜歡我祖國的傳統音樂。", "Czech" : "Mám rád tradiční hudbu mé rodné země.", "Danish" : "Jeg nyder den traditionelle musik i mit hjemland.", "Dutch" : "Ik geniet van de traditionele muziek van mijn geboorteland.", "English" : "I enjoy the traditional music of my native country.", "Finnish" : "Nautin kotimaassani perinteistä musiikkia.", "French" : "J'apprécie la musique traditionnelle de mon pays d'origine.", "German" : "Ich genieße die traditionelle Musik meiner Heimat.", "Greek" : "Απολαμβάνω την παραδοσιακή μουσική της πατρίδας μου.", "Hebrew" : "אני נהנה מהמוסיקה המסורתית של מולדתי.", "Hindi" : "मैं अपने मूल देश के पारंपरिक संगीत का आनंद लेता हूं।", "Hungarian" : "Élvezem az én hazám hagyom��nyos zenéjét.", "Indonesian" : "Saya menikmati musik tradisional negara asal saya.", "Italian" : "Mi piace la musica tradizionale del mio paese natale.", "Japanese" : "私は母国の伝統音楽を楽しんでいます。", "Korean" : "나는 내 조국의 전통 음악을 즐긴다.", "Norwegian Bokmal" : "Jeg liker den tradisjonelle musikken i mitt hjemland.", "Polish" : "Lubię tradycyjną muzykę mojego kraju.", "Portuguese" : "Eu gosto da música tradicional do meu país natal.", "Romanian" : "Îmi place muzica tradițională din țara mea natală.", "Russian" : "Мне нравится традиционная музыка моей родной страны.", "Slovak" : "Mám rád tradičnú hudbu svojej rodnej krajiny.", "Spanish" : "Disfruto de la música tradicional de mi país natal.", "Swedish" : "Jag njuter av traditionell musik i mitt hemland.", "Thai" : "ฉันเพลิดเพลินกับดนตรีดั้งเดิมของประเทศบ้านเกิดของฉัน", "Turkish" : "Ülkemdeki geleneksel müzikten zevk alıyorum." }; }
There’s one last thing: the numeric input for controlling the playback speed of the speech. Modify the talk() function to get the speech rate from the number input and we’re good to go!
Here’s the final product:
function talk() { ...// no changes except for the rateFld.value reference u.rate = Number(rateFld.value); speechSynthesis.speak(u); }
See the Pen Polyglot: Text-To-Speech in Multiple Languages by Steven Estrella (@sgestrella) on CodePen.
A Real World Application
My interest in this technology started many years ago in 1990 when I created a 26-lesson curriculum as part of my dissertation. It was delivered using my first programming language, HyperCard, on a Macintosh Plus which had a primitive text-to-speech feature. I used that feature to provide some feedback to the user while they progressed through the material. More recently, in 2018, I created a free progressive web app called Buenos Verbos that helps Spanish language students search and filter a database of 766 verbs. The chosen verb is then fully conjugated and the user can click the forms to hear them spoken. So perhaps web pages might like to talk and with some imagination you may find reasons to encourage them. The question is: what will you make your website say next?
The post Using the Web Speech API for Multilingual Translations appeared first on CSS-Tricks.
Using the Web Speech API for Multilingual Translations published first on https://deskbysnafu.tumblr.com/
0 notes
siliconwebx · 6 years ago
Text
Using the Web Speech API for Multilingual Translations
Since the early days of science fiction, we have fantasized about machines that talk to us. Today it is commonplace. Even so, the technology for making websites talk is still pretty new.
We can make our pages on the web talk using the SpeechSynthesis part of the Web Speech API. This is still considered an experimental technology but it has great support in the latest versions of Chrome, Safari, and Firefox.
The fun part for me is using this technology with foreign languages. For that, Mac OSX has great support for this on all browsers. On Windows, you have to use Chrome. We’re going to walk through a three-step process to create a page that speaks the same text in multiple languages. Some of the basic code is derived from documentation found here but the final product adds some fun features and can be viewed at my Polyglot CodePen here.
Tumblr media
Screen shot of the completed Polyglot app with a menu of languages.
Step 1: Start Simple
Let’s create a basic page with a <textarea> for the text we want the page to speak and include a button to click to trigger the speech.
<div id="wrapper"> <h1>Simple Text To Speech</h1> <p id="warning">Sorry, your browser does not support the Web Speech API.</p> <textarea id="txtFld">I love the sound of my computer-generated voice.</textarea> <label for="txtFld">Type text above. Then click the Speak button.</label> <div> <button type="button" id="speakBtn">Speak</button> <br> <p>Note: For best results on a Mac, use the latest version of Chrome, Safari, or FireFox. On Windows, use Chrome.</p> </div> </div>
The paragraph with ID warning will be shown only if the JavaScript detects no support for the Web Speech API. Also, note the ID values for the textarea and the button as we will use those in our JavaScript.
Feel free to style the HTML any way you’d like. You’re also free to work off the demo I created:
See the Pen Text-To-Speech Part 1 by Steven Estrella (@sgestrella) on CodePen.
Adding a style rule for the disabled state of the button is a good idea to avoid confusion for the few people who still use incompatible browsers, like the now-quaint Internet Explorer. Also, let’s use a style rule to hide the warning by default so we can control when it’s actually needed.
button:disabled { cursor: not-allowed; opacity: 0.3; } #warning { color: red; display: none; font-size: 1.4rem; }
Now on to the JavaScript! First, we add two variables to serve as references to the "Speak" button that triggers the speech and to the <textarea> element. An event listener at the bottom of the code tells the document to wait until the DOM elements load before calling the init() function. I used a handy utility function I call "qs" that is defined at the bottom of the code. It is a shortcut alternative to document.querySelector and it selects whatever selector value I pass to it and returns an object reference. Then we’ll add an event listener to the speakBtn object to make the button call the talk() function.
Tumblr media
The talk() function creates a new instance of the SpeechSynthesisUtterance object that is part of the Web Speech API. It adds the text from the <textarea>(using ID txtFld) to the text property. Then the utterance is passed to the speechSynthesis method of the window object and we hear the spoken text. The specific voice you hear will vary by browser and operating system. On my Mac, for example, my default language is set to American English and the default voice for English is Alex. In Step 2, we will add code to create a menu to help the user choose voices for all available languages.
let speakBtn, txtFld; function init() { speakBtn = qs("#speakBtn"); txtFld = qs("#txtFld"); speakBtn.addEventListener("click", talk, false); if (!window.speechSynthesis) { speakBtn.disabled = true; qs("#warning").style.display = "block"; } } function talk() { let u = new SpeechSynthesisUtterance(); u.text = txtFld.value; speechSynthesis.speak(u); } // Reusable utility functions function qs(selectorText) { // Saves lots of typing for those who eschew jQuery return document.querySelector(selectorText); } document.addEventListener('DOMContentLoaded', function (e) { try {init();} catch (error) { console.log("Data didn't load", error); } });
Step 2: A Menu of International Voices
If we want to use anything other than the default language and speaking voice, we will have to add a bit more code. So that’s what we’re going tackle next.
We’re going to add a select element to hold the menu of voice options:
<h1>Multilingual Text To Speech</h1> <div class="uiunit"> <label for="speakerMenu">Voice: </label> <select id="speakerMenu"></select> speaks <span id="language">English.</span> <!-- etc. --> </div>
Before we create the code to populate the menu options, we should take care of the code that will help us connect language codes to their corresponding names. Each language is identified by a two-letter code such as "en" for English or "es" for Español (Spanish). We will take a simple list of these codes and their corresponding languages and make an array of objects of the form: {"code": "pt", "name": "Portuguese"}. Then we’ll need a utility function to help us search an array of objects for the value of a given property. We will use it in a few minutes to quickly find the language name that matches the language code of the selected voice. Copy the code below so that the two functions are just above and just below the // Generic Utility Functions comment.
function getLanguageTags() { let langs = ["ar-Arabic","cs-Czech","da-Danish","de-German","el-Greek","en-English","eo-Esperanto","es-Spanish","et-Estonian","fi-Finnish","fr-French","he-Hebrew","hi-Hindi","hu-Hungarian","id-Indonesian","it-Italian","ja-Japanese","ko-Korean","la-Latin","lt-Lithuanian","lv-Latvian","nb-Norwegian Bokmal","nl-Dutch","nn-Norwegian Nynorsk","no-Norwegian","pl-Polish","pt-Portuguese","ro-Romanian","ru-Russian","sk-Slovak","sl-Slovenian","sq-Albanian","sr-Serbian","sv-Swedish","th-Thai","tr-Turkish","zh-Chinese"]; let langobjects = []; for (let i=0;i<langs.length;i++) { let langparts = langs[i].split("-"); langobjects.push({"code":langparts[0],"name":langparts[1]}); } return langobjects; } // Generic Utility Functions function searchObjects(array, prop, term, casesensitive = false) { // Searches an array of objects for a given term in a given property // Returns an array of only those objects that test positive let regex = new RegExp(term, casesensitive ? "" : "i"); let newArrayOfObjects = array.filter(obj => regex.test(obj[prop])); return newArrayOfObjects; }
Now we can build out the options for the select element using JavaScript. We need to declare variables at the top of our JavaScript to hold references to the #speakerMenu select element, the #language span element, the array of synthesized voices (allVoices), an array of codes to identify the languages (langtags), and a place to keep track of the currently selected voice (voiceIndex). Add those just after the two variable declarations we created in Step 1.
let speakBtn, txtFld, speakerMenu, language, allVoices, langtags; let voiceIndex = 0;
The updated init() function sets some additional references to the #speakerMenu and the #language span and places all the language codes into an array of objects called langtags. The feature detection part of the code changes here, too. If the Web Speech API is supported, the setUpVoices() function is called. Also, for Chrome, we have to listen for changes to the loaded voices and repeat the setup when needed. Chrome polls the available voices every time you switch between one of its remote voices (the ones listed with the Google prefix while you are in Chrome) and all the other voices which are stored locally in the user’s operating system.
function init() { speakBtn = qs("#speakBtn"); txtFld = qs("#txtFld"); speakerMenu = qs("#speakerMenu"); language = qs("#language"); langtags = getLanguageTags(); speakBtn.addEventListener("click", talk, false); speakerMenu.addEventListener("change", selectSpeaker, false); if (window.speechSynthesis) { if (speechSynthesis.onvoiceschanged !== undefined) { // Chrome gets the voices asynchronously so this is needed speechSynthesis.onvoiceschanged = setUpVoices; } setUpVoices(); // For all the other browsers } else{ speakBtn.disabled = true; speakerMenu.disabled = true; qs("#warning").style.display = "block"; } }
The setUpVoices() function gets an array of what are called SpeechSynthesisVoice objects by calling the getVoices() method of the speechSynthesis object. This is done in our code using the getAllVoices() function. Unfortunately, I have found that the speechSynthesis.getVoices() method sometimes returns duplicates in the list, so I devoted nine lines of code to eliminate the those. Finally, at the end of getAllVoices(), I added a unique identifier number to each of the SpeechSynthesisVoice objects. That will help us in Step 3 when we need to filter the list of voices to only show voices for a given language. When complete, the allVoices array will contain objects that look like the ones below. Each object has id, voiceURI, name, and lang attributes. The localService attribute indicates whether the code for the voice is stored on the user’s computer or remotely on Google’s servers. Notice the lang attribute. The value consists of a two-letter language code (e.g. "es" for Spanish) followed by a dash and a region code (e.g. "MX" for Mexico). This identifies the language and regional accent of each voice.
{id:48, voiceURI:"Paulina", name:"Paulina", lang: "es-MX", localService:true}, {id:52, voiceURI:"Samantha", name:"Samantha", lang: "en-US", localService:true}, {id:72, voiceURI:"Google Deutsch", name:"Google Deutsch", lang: "de-DE", localService:false}
The last line of setUpVoices() calls a function to create the list of options that will appear in the #speakerMenu select element. The value of the id attribute for each voice is placed in the value attribute for the option. The name and lang attributes are the visible text items that appear in each option along with "(premium)" for those voices that are marked that way on some operating systems and browsers.
function setUpVoices() { allVoices = getAllVoices(); createSpeakerMenu(allVoices); } function getAllVoices() { let voicesall = speechSynthesis.getVoices(); let vuris = []; let voices = []; voicesall.forEach(function(obj,index) { let uri = obj.voiceURI; if (!vuris.includes(uri)) { vuris.push(uri); voices.push(obj); } }); voices.forEach(function(obj,index) {obj.id = index;}); return voices; } function createSpeakerMenu(voices) { let code = ; voices.forEach(function(vobj,i) { code += `<option value=${vobj.id}>`; code += `${vobj.name} (${vobj.lang})`; code += vobj.voiceURI.includes(".premium") ? ' (premium)' : ; code += `</option>`; }); speakerMenu.innerHTML = code; speakerMenu.selectedIndex = voiceIndex; }
You might recall that in the init() function, we had set up an event listener to call selectSpeaker() whenever the speakerMenu changes. The selectSpeaker() function stores the selectedIndex of the #speakerMenu select element. Next, it gets the value of the selected item which will be an integer that corresponds to the index of that voice in the allVoices() array. So, now we have retrieved the SpeechSynthesisVoice we want. We then grab the first two letters of the lang attribute (e.g. "en," "es," "ru," "de," "fr") and use that code to search the langtags array of language objects to find the appropriate language name. The searchObjects() function returns an array that will likely have only one entry. Regardless, the first entry (langcodeobj[0]) is all we need. Finally, we assign that name to the innerHTML attribute of the language span and it shows on the screen as expected.
// Code for when the user selects a speaker function selectSpeaker() { voiceIndex = speakerMenu.selectedIndex; let sval = Number(speakerMenu.value); let voice = allVoices[sval]; let langcode = voice.lang.substring(0,2); let langcodeobj = searchObjects(langtags, "code", langcode); language.innerHTML = langcodeobj[0].name; }
The only thing left for Step 2 to be complete is to make sure the talk() function works when we click the "Speak" button. Modify the talk() function to add attributes to the utterance to control which voice and language are used and how fast to speak the text. In my testing, a rate range of 0.5 to 2 works reliably well. I found that a rate below 0.5 has no effect. I think 0.8 works as a nice default for many languages, but as we’ll see in Step 3, there’s an easy way to let the user decide.
function talk() { let sval = Number(speakerMenu.value); let u = new SpeechSynthesisUtterance(); u.voice = allVoices[sval]; u.lang = u.voice.lang; u.text = txtFld.value; u.rate = 0.8; speechSynthesis.speak(u); }
That’s it for Step 2! Here’s the result of what we’ve done so far:
See the Pen Text-To-Speech Part 2 by Steven Estrella (@sgestrella) on CodePen.
Play around with it a bit. Sometimes it is fun to type an English phrase and then assign a French or German speaker to say it. Conversely, if you want to hear your worst first-year Spanish student, type a Spanish phrase and assign it to be spoken by an English voice.
Step 3: The Complete Polyglot
We’re in the final stretch! Some of the things we do in this step will be bits of polish to the UI but there are some functional things we need to do as well to button everything up. specifically, we’re going to:
Create a menu of available language options
Allow users to define the speed of the speech
Define a default phrase in the textarea that translates on language selection
Here’s what we’re looking at:
Tumblr media
We’re adding a dropdown menu, speech rate setting, and a default phrase.
In the HTML, we’re going to add a new <select> element for the language menu and a number input (which will be used later to set the rate of speech). Notice we have deleted the #language span as it is no longer relevant once the language menu is working.
<div class="uiunit"> <label for="languageMenu">Language: </label> <select id="languageMenu"> <option selected value="all">Show All</option> </select> </div> <div class="uiunit"> <label for="speakerMenu">Voice: </label><select id="speakerMenu"></select> </div> <div class="uiunit"> <label for="rateFld">Speed: </label> <input type="number" id="rateFld" min="0.5" max="2" step="0.1" value="0.8" /> </div>
In the JavaScript, we will need to modify the variable declarations. We will keep track of all dialects in the allLanguages array and just the main languages in the primaryLanguages array. The langhash and langcodehash arrays will serve as hash tables so we can quickly get a language name when all we know is the two-letter language code and vice versa. We should only need to setup the languages menu once so a Boolean flag for initialSetup will come in handy.
let speakBtn, txtFld, speakerMenu, allVoices, langtags; let voiceIndex = 0; let allLanguages, primaryLanguages, langhash, langcodehash; let rateFld, languageMenu, blurbs; let initialSetup = true; let defaultBlurb = "I enjoy the traditional music of my native country.";
In the new init() function, let’s remove the line language = qs("#language"); then add the new code as seen here to create the blurbs, reference the rateFld number input and languageMenu select, and create hash tables for looking up language names and tags.
function init() { // ...keep existing content but delete language = qs("#language"); createBlurbs(); rateFld = qs("#rateFld"); languageMenu = qs("#languageMenu"); languageMenu.addEventListener("change", selectLanguage, false); langhash = getLookupTable(langtags, "name"); langcodehash = getLookupTable(langtags, "code"); if (window.speechSynthesis) { // ...keep existing content } else{ // ...keep existing content languageMenu.disabled = true; } }
The setUpVoices() function needs some work to accommodate the new languages menu and to trigger the filterVoices() function which we will use now to populate the #speakerMenu element. Also, we’re going to add the new functions: getAllLanguages() and getPrimaryLanguages(). The first one assembles an array of the unique values for the lang attribute found in the allVoices array of objects. Notice the return statement uses the spread operator combined with a new Set object to ensure that the returned array has no duplicates. The getPrimaryLanguages() function returns an array of the two-letter country codes. That makes a smaller list of just the main languages without reference to regional dialects.
function setUpVoices() { allVoices = getAllVoices(); allLanguages = getAllLanguages(allVoices); primaryLanguages = getPrimaryLanguages(allLanguages); filterVoices(); if (initialSetup && allVoices.length) { initialSetup = false; createLanguageMenu(); } } function getAllLanguages(voices) { let langs = []; voices.forEach(vobj => { langs.push(vobj.lang.trim()); }); return [...new Set(langs)]; } function getPrimaryLanguages(langlist) { let langs = []; langlist.forEach(vobj => { langs.push(vobj.substring(0,2)); }); return [...new Set(langs)]; }
The setUpVoices() function calls two additional functions. The filterVoices() function gets the two-letter language code from the current value of the #languageMenu select menu and uses it to filter the allVoices array and return only the available voice options for the chosen language. It then passes that array to the createSpeakerMenu() function (unchanged from Step 2) which populates the #speakerMenu with options. Then filterVoices() gets the blurb associated with the chosen language and places it in the textarea where it can be edited or replaced.
And, in case Chrome rebuilds this menu, the stored voiceIndex is used to restore the current selection. Next the createLanguageMenu() function uses our hash tables to create the needed menu options for the languageMenu select element. The selectLanguage() function is triggered whenever the user chooses a language. It then triggers filterVoices() and sets the #speakerMenu to display the first available option.
function filterVoices() { let langcode = languageMenu.value; voices = allVoices.filter(function (voice) { return langcode === "all" ? true : voice.lang.indexOf(langcode + "-") >= 0; }); createSpeakerMenu(voices); let t = blurbs[languageMenu.options[languageMenu.selectedIndex].text]; txtFld.value = t ? t : defaultBlurb; speakerMenu.selectedIndex = voiceIndex; } function createLanguageMenu() { let code = `<option selected value="all">Show All</option>`; let langnames = []; primaryLanguages.forEach(function(lobj,i) { langnames.push(langcodehash[lobj.substring(0,2)].name); }); langnames.sort(); langnames.forEach(function(lname,i) { let lcode = langhash[lname].code; code += `<option value=${lcode}>${lname}</option>`; }); languageMenu.innerHTML = code; } function selectLanguage() { filterVoices(); speakerMenu.selectedIndex = 0; }
In the utility functions section of the code toward the bottom, add the following code. This generic little utility will help you the next time you need to create a lookup table for an array of objects. In our case, we will use this to allow us to easily match a language code with its corresponding language name and vice versa.
function getLookupTable(objectsArray, propname) { return objectsArray.reduce((accumulator, currentValue) => (accumulator[currentValue[propname]] = currentValue, accumulator),{}); }
I added an array of text phrases, each of which is a translation of the English phrase, "I enjoy the traditional music of my native country." The language it’s displayed in will correspond to what’s selected in the language men.
Here we see the beauty of UTF-8 on full display. Above the getLanguagesTags() function, let’s add the code that generates all those translated blurbs. I only read Spanish, English, some Portuguese, and very little German, so I have to take on faith that Google Translate is providing accurate translations for the rest. If any of these is your native language, feel free to leave corrections in the comments.
function createBlurbs() { blurbs = { "Arabic" : "أنا أستمتع بالموسيقى التقليدية لبلدي الأم.", "Chinese" : "我喜歡我祖國的傳統音樂。", "Czech" : "Mám rád tradiční hudbu mé rodné země.", "Danish" : "Jeg nyder den traditionelle musik i mit hjemland.", "Dutch" : "Ik geniet van de traditionele muziek van mijn geboorteland.", "English" : "I enjoy the traditional music of my native country.", "Finnish" : "Nautin kotimaassani perinteistä musiikkia.", "French" : "J'apprécie la musique traditionnelle de mon pays d'origine.", "German" : "Ich genieße die traditionelle Musik meiner Heimat.", "Greek" : "Απολαμβάνω την παραδοσιακή μουσική της πατρίδας μου.", "Hebrew" : "אני נהנה מהמוסיקה המסורתית של מולדתי.", "Hindi" : "मैं अपने मूल देश के पारंपरिक संगीत का आनंद लेता हूं।", "Hungarian" : "Élvezem az én hazám hagyományos zenéjét.", "Indonesian" : "Saya menikmati musik tradisional negara asal saya.", "Italian" : "Mi piace la musica tradizionale del mio paese natale.", "Japanese" : "私は母国の伝統音楽を楽しんでいます。", "Korean" : "나는 내 조국의 전통 음악을 즐긴다.", "Norwegian Bokmal" : "Jeg liker den tradisjonelle musikken i mitt hjemland.", "Polish" : "Lubię tradycyjną muzykę mojego kraju.", "Portuguese" : "Eu gosto da música tradicional do meu país natal.", "Romanian" : "Îmi place muzica tradițională din țara mea natală.", "Russian" : "Мне нравится традиционная музыка моей родной страны.", "Slovak" : "Mám rád tradičnú hudbu svojej rodnej krajiny.", "Spanish" : "Disfruto de la música tradicional de mi país natal.", "Swedish" : "Jag njuter av traditionell musik i mitt hemland.", "Thai" : "ฉันเพลิดเพลินกับดนตรีดั้งเดิมของประเทศบ้านเกิดของฉัน", "Turkish" : "Ülkemdeki geleneksel müzikten zevk alıyorum." }; }
There’s one last thing: the numeric input for controlling the playback speed of the speech. Modify the talk() function to get the speech rate from the number input and we’re good to go!
Here’s the final product:
function talk() { ...// no changes except for the rateFld.value reference u.rate = Number(rateFld.value); speechSynthesis.speak(u); }
See the Pen Polyglot: Text-To-Speech in Multiple Languages by Steven Estrella (@sgestrella) on CodePen.
A Real World Application
My interest in this technology started many years ago in 1990 when I created a 26-lesson curriculum as part of my dissertation. It was delivered using my first programming language, HyperCard, on a Macintosh Plus which had a primitive text-to-speech feature. I used that feature to provide some feedback to the user while they progressed through the material. More recently, in 2018, I created a free progressive web app called Buenos Verbos that helps Spanish language students search and filter a database of 766 verbs. The chosen verb is then fully conjugated and the user can click the forms to hear them spoken. So perhaps web pages might like to talk and with some imagination you may find reasons to encourage them. The question is: what will you make your website say next?
The post Using the Web Speech API for Multilingual Translations appeared first on CSS-Tricks.
😉SiliconWebX | 🌐CSS-Tricks
0 notes
ideahat-universe · 8 years ago
Text
The Amish burn their trash.
So I currently feel pretty good about everything i’ve been doing on this blog for the most part. I’m doing a lot better in this account than in any other and I believe I've finally found a website that lets me publish the kind of content I like to publish without worrying about the various song and dances that typically go on with online gallery communities. 
People speak very ill of Tumblr and while I completely understand where that comes from I’m in no ways interested in downplaying it’s strengths in favor of denigrating it by it’s lowest common denominator. 
Having said all that I have signed onto websites where I didn't get to give my best content. I would say I gave the opposite of that and while my old Sprite comics hold a special place in my heart they are frankly very silly and embarrassing. 
So because I’m a person who is nostalgic but prefers to move forward so I’m moving forward to end the life cycle of some old stuff on old accounts. 
Lets visit the site I got had the most progress in. I made a club with over a hundred members, I had community notoriety. One of my uploads was a featured work and my first two girlfriends were on this website. 
Sheezyart. Lets look at the old account now!
Tumblr media Tumblr media
What’s all this here then? It’s gone? But the domain has not been sold to some ritzy random domain person? 
Let me look up some information on Sheezyart. While I do that read this Ancient Urban Dictionary post on Sheezyart. 
“SheezyArt
An online art community very similar to DeviantART (DA), where you can submit works of art, such as digital art, traditional art, flash animations, and writings. Unlike DeviantART, however, the admins are a bit more flexible and accept some copyrighted content. For example, if someone wanted to add a copyrighted sound file to a Flash MX movie or animation, then he or she would be able to. However, if someone would do this on DeviantART it would violate the DA policy, meaning that it would be removed from the site. Like DeviantART, however, SheezyArt does not display adult artwork, like it originally did when it first was created. By posting artwork on the site, it allows you to post comments and then people can (if they want to) reply. It's a great way to make online friends that share an interest in the wonderful world of art. Artists on the site have their own web page...such as " username.sheezyart.com " or “ www.sheezyart.com/ usename “ This is where their gallery, journal, and personal information is displayed. *Also known as "SA" I just signed up for a SheezyArt account yesterday! Check out my page! Some people think SA is much better than DA.
by Ellernbitch January 26, 2005″
All right so a quick trip to Wiki fur has told me that this website is in limbo. They ran out of money to keep the site funded and unlike Furry Affinity they didn't sell the website to a company that can keep it afloat so it’s dead. Technically. Their just holding onto the domain but god only knows if any of the content is still there. 
Well. I guess I should add some more stuff to this story. 
Sheezyart was indeed a website where you would upload content that had some copyrighted content in it and for me that was just the kind of opening to upload Sprite comics and yes. DeviantArt has always had a rather draconian and obtuse ruleset and uploading process. It was much cleaner and easier to understand on Sheezyart. I didn't agree with the censoring of adult artwork though. Oddly enough there were users in their teens and young adult (but not 18) who made pornography. 
That’s right. If you can draw decently and you hit puberty you might draw pornography that you can’t view on the Internet. 
DeviantArt allowed and still allows adult artwork but it does have it’s limits and limitations and yes. It very much pisses off the pornographic artists while not being restrained enough for normal people to consider it “decent” for public consumption. 
I could spend all day talking about that but I won’t. 
Despite that. There was something that would in most senses be considered pornographic on Sheezyart at one point. A very popular channel (blog?, gallery?) published animations and pictures of ladies with their tits out but it didn't count for the censors. Somehow. 
I remember why I left the site despite it doing really well for me and it was due to the crackdown on accounts that used recolors for their products. The Artist Community is a very cruel community and when they aren't lashing out on themselves for not reaching their personal philosophy of good (or invariably wallowing in a narcissistic delusion of excellence) they are lashing out at others for just doing the bare minimum and getting away with being considered a legitimate producer. 
I used Sonic Sprites for one reason. An incredible lack of imagination. It’s also why my sprite is of a fox. It was a Tails recolor many years ago. I could only mentally envision a sonic sprite and I practiced using them and I had a whole plethora of sites where I could use just about every Sonic asset from every Sonic game and then some so I made due. I also couldn't afford Photoshop so I did it all in MS Paint. I tinkered with paint.net towards the end but it never got very far for me. 
I think at this point I've never been better at doing things my own way although I do reuse assets it’s only of the kind I originally made so I imagine by today’s standards my artwork today would have been just fine back then. 
I didn't plan on coasting on sprites forever but I didn't want to get banned 
youtube
A friend of mine suggested Facebook but I was NOT doing that. I decided to write instead which took me on an intrepid adventure of accomplishing very little for several years. I could not get a bite for my writing. I re-wrote the stuff several times and I've never quite finished any of my stories because I just preferred the medium of visuals and illustrations over one or the other entirely. 
I briefly wrote a Ranma Fan Fix which I think people would have liked but It was for a specific person so it ended without a publish anywhere and the real fanart writing ended up being the MLP fan fix which at the time made sense. The show was kind of boring and had a lot of missteps and just didn't live up to the imaginations of the fans or even the previous generations. 
That’s no longer true. At all. I could probably remove it but It’s the best writing I've put on the Internet sadly so it’s going to stay. As a sidenote someone tried to invalidate my opinion by using the fact that I wrote 24 chapters of that story. I defended myself as you would expect but as any MLP fan would tell you 24 chapters isn't even the deepest depths of insanity you can dive into you when you delve into the MLP fan fictions. 
And mine didn't even have sex or guns in it. It was a very light read. Yes, there are MLP stories with sex and guns in it. 
I have a DA account for my writing (still considering the idea of destroying it) but I didn't go straight there. I went to some website called chapter-read and yes. That website died. In about half a year. Really inexplicable. It was a new website. it was getting good. Then it died. 
Now I’m here. Isn't this nice. What a journey it’s been if only it didn't cost me several hard drives, Free fan art that I lost somehow, and memories of crying in front of a computer monitor. 
To take the focus off me I was reminded of a username that actually reminds me of an account I know for their recent hijinks and I can’t remember of their past but they were also on Sheezyart. 
Does anyone know who Sonicrocksmysocks is?
Tumblr media
Is that looking familiar to you? That’s right it’s Kylee Henke. 
That’s right. The Meme Queen. By the way. If I google Meme Queen I get Queen Elizabeth. 
I didn't know we did memes of her. What an odd world we live in. 
Kylee had a Sheezyart account and she managed to dig up her old stuff. I imagine on her channel this is all old news but It’s news to me so I’m just going to dig up something of hers. It’s in flash. I can fix that. If I learned anything while wasting time writing it was to bend file types to my will. 
Eh. For some reason converting it and uploading it to Youtube is a negatory. I’ll just drop it in Drop box and you can view it there. 
https://www.dropbox.com/s/m3a07yltdkhrw1q/2010-12-22%20-%20SonicRocksMySocks%20Animation%20Reel%202010.swf?dl=0
Sonicrocksmysocks. Kylee Henke. Any questions?
So um. *awkward cough* Does Sonic still rock the socks? Yes? No? Is “Rocking the socks.” A euphemism for anything? Maybe? Maybe not?
If you want the rest of those old flash things you should visit her Deviant Art page. It’s actually kept up to date for the most part. 
I think we’re wrapping this fun little story up. Kylee went back to Sheezyart to recover some old artwork and I went back to Sheezyart with the intention of doing the exact opposite. 
Tumblr media
1 note · View note
khalilhumam · 4 years ago
Text
#BlackLivesMatter resonates in South Asia: Unilever drops ‘Fair’ from cosmetic line
Register at https://mignation.com The Only Social Network for Migrants. #Immigration, #Migration, #Mignation ---
New Post has been published on http://khalilhumam.com/blacklivesmatter-resonates-in-south-asia-unilever-drops-fair-from-cosmetic-line/
#BlackLivesMatter resonates in South Asia: Unilever drops ‘Fair’ from cosmetic line
“This war of complexion has created a huge problem for our women”
Fair and Lovely – Billboard for Skin-Whitening Cream – Chittagong – Bangladesh. Image from Flickr by Adam Jones. CC BY-SA 2.0.
On 25 June, global cosmetic conglomerate Unilever announced a decision to re-brand its leading skin-lightening product ‘Fair & Lovely’ to ‘Glow & Lovely’. The major decision comes in the wake of the recent Black Lives Matter protests that erupted around the world following the police killing of George Floyd in the US. In South Asia, where discrimination based on skin color permeates the beauty industry, ‘Fair & Lovely’ has been popular for nearly five decades. As celebrities raised their voice against racism using hashtags like #BlackLivesMatter and #JusticeForGeorgeFloyd, others were quick to point out the hypocrisy of those that have long endorsed skin-lightening products. While Unilever claims that the brand change aims to “celebrate all skin tones”, anti-colourist activists and social media users are questioning whether the brand's name change tackles the real issue.
South Asian standards of beauty
Although the “Black Lives Matter” movement exists in a specific context, its calls for racial justice have resonated with justice movements around the world. In South Asian countries — like India and Pakistan — skin color is seen as an indirect marker of social class and status. This issue has been prevalent since colonial times, with many women facing problems in getting marriage proposals or landing better work opportunities due to discrimination based on their complexion. The product, Fair and Lovely, has been used by many women across South Asia since the late '70s. Its marketing techniques, with before and after images of dark to light coloured skin, works indirectly to equate fairer or lighter skin colours with beauty. Indian Journalist Barkha Dutt compares skin lightening creams to another marker for racism in South Asia. She takes a jibe at Unilever's ‘Fair and Lovely’ commenting on how the brand has normalized racism in India and created wrong notions of beauty for millions of Indian boys and girls for five decades.
If Skin Lightening creams are going to be racism by another name that is neither fair nor lovely. — barkha dutt (@BDUTT) June 26, 2020
Speaking to Global Voices on the phone, Pakistani psychologist Mirat Gul said:
This war of complexion has created a huge problem for our women. Even our religion has said that no one is superior to another on the basis of colour yet these creams, advertisements, and mindset have effected women. South Asians are coloured people and we need to accept them as they are instead of opting for these products. It's good that the word ‘Fair’ will be dropped but people too have to stop worrying and harassing people on the complexion.
Same product, different name: Does Unilever's decision pack any punch?
A number of people in both India and Pakistan have been working to change the skin lightening industry, asking manufacturers to remove whitening creams from the market. Indian actress Nandita Das, who has been running the Dark is Beautiful campaign since 1994, celebrated Unilever's decision as an indication that mindset's are slowing starting to change.
Wow! Words impact notions & they, the mindset. I want to believe that the campaign Dark is Beautiful & India’s Got Colour played a tiny role. Many of you have too. Long way to go before things are truly ‘fair’, but we are on our way! #IndiasGotColour #AllShadesAreLovely https://t.co/lra7mlwqwq — Nandita Das (@nanditadas) June 25, 2020
While in Pakistan, anti-colourism and diversity advocate Fatima Lodhi has been running the Dark is Divine campaign for the past seven years. Dark is Divine issued a statement on about Unilever's decision pushing for more messaging aimed at “re-humanizing” dark skin tones:
Rebranding of products to recognize multiple shades, shapes, and sizes of beauty should be followed by behavior change programs to re-humanize the dark skin. Promoting lighter skin tone is not only colorist but a racist act as well and further, giving pedestal to the fairer skin tones while treating dark skin as a disease is also a clear attempt at enhancing most people’s feelings of insufficiency.
[youtube https://www.youtube.com/watch?v=XLF9GBPfv4E?feature=oembed&w=650&h=366] Social media users are also questioning whether Unilever's new product, ‘Glow and Lovely’ pays lip service to the real issues of colourism in South Asia:
So… @unilever is still going to sell skin lightening cream in South Asia and will just call it “Lovely” from now on? https://t.co/6R5LrhHIn9 — fatima bhutto (@fbhutto) June 25, 2020
‘Fair & lovely’ to be rebranded dropping the word ‘fair’. While the attempt is fair (no pun intended), is it really enough? Using the words glow and brighten doesn't really change what the product was built for. ”…a rose by any other name……” — Avni Raja (@avniraja) June 25, 2020
So Fair and Lovely will now be called Glow and Lovely? C’mon Hindustan Lever. For years you’ve been profiting by destroying our nation’s young girl’s self worth by making rude comments about dark skin. Now prove your ‘intentions’ by having a dark skinned girl on your packaging. — Shekhar Kapur (@shekharkapur) July 2, 2020
Is a change coming?
Along with building toxic psychological pressure, whitening creams contain the ingredient, mercury, which is said to be carcinogenic in nature. Pakistan's Minister of State for Climate Change, Zartaj Gul Wazir, made an official statement in July 2019 regarding the government's promise to crackdown on whitening creams that contain more than 1 percent mercury — citing the ministry's finding that 56 of 59 samples of fairness products contained more than 1 percent mercury. On July 4, 2020, in a Dark is Divine Facebook message Zartaj Gul Wazir reiterated her commitment to cracking down on mecury in whitening creams once the Minamata Convention on Mercury is ratified. Anum Chandani, Hira Hashmi, and Marvi Ahmed from Pakistan started the petition to ban Fair and Lovely and are also running an Instagram account to create awareness among masses.
This is a petition I wish no one had to make because Fair and Lovely is a cream that shouldn't exist. Nevertheless, @Unilever please stop making it and selling it. https://t.co/6lqH2LPHtD — fatima bhutto (@fbhutto) June 11, 2020
Another win came when Indian matrimonial website Shaadi.com, known for keeping a skin tone filter, has dropped it from its website after the recent uproar by many users. While changes are slowing being made, Ipsita Chakravarty notes that there may still be a ways to go:
The packaging of the creams may have changed but not their substance. And while Shaadi.com will no longer ask for your skin tone, you can still search for prospective partners by caste, which is what skin colour stands for in India.
< p class='gv-rss-footer'>Written by R Umaima Ahmed, Vishal Yashoda · comments (0) Donate · Share this: twitter facebook reddit
0 notes
legit-scam-review · 6 years ago
Text
Blythe Masters Looks Beyond Finance for Next Wave of Blockchain Growth
To hear Blythe Masters tell it, the time has come for Digital Asset (DA) to spread its wings and fly.
The distributed ledger technology (DLT) company she founded in 2014 is entering a new phase, heralded by, among other things, a partnership with Google Cloud to simplify and proliferate the tech.
To date, DA’s strategy has stood out among the big enterprise blockchain players for its laser-like focus. Instead of spending a lot of time on consortiums, proofs-of-concept and the like, the New York-based company concentrated on landing the one big fish.
It achieved that goal late last year when the Australian Securities Exchange (ASX) officially hired DA to replace its creaky Clearing House Electronic Subregister System (CHESS), a multi-year project that’s currently underway.
Now, having earned the rare distinction of a bona fide production customer, Masters’ startup wants to foster an ecosystem around its Digital Asset Modeling Language (DAML), which is about to become available with a software development kit (SDK) via Google Cloud.
“Having spent three and a half years in the design-and-build phase, this is the ‘open up and educate’ phase and [the time to] build a community of channel partners and developers,” Masters told CoinDesk.
This, in turn, will open a vast range of opportunities for DA, she said – both within the financial services industry where Masters spent most of her career and outside it.
“The application of this technology is by no means limited to the world’s biggest market infrastructures,” the former JPMorgan Chase executive said, adding:
“It goes well throughout financial services, well beyond capital markets and beyond financial services into all the other industries that have a vested interest in improving the efficiency of their workflow orchestration.”
According to Masters, there is “a lot of pent-up demand” for DA’s technology which the cloud-based DAML SDK can start to meet and a “potential addressable market that is almost unmeasurable.”
To give a sense of the breadth of this market, Masters rattled off a litany of new pastures for DA, including: healthcare and insurance claims; digital media rights; royalty streams; real estate; lending and collateral management within capital markets, derivatives post-trade, securities post-trade, reference data, supply chain, crypto wallet custody of assets and more.
However, Masters was careful to qualify this, acknowledging the fatigue felt in many corners following the blockchain hype of a few years ago.
“I think there was some fair criticism that blockchain was a technology solution looking for a problem to solve,” she said. “But our approach has very much been to work with customers to identify the problem first and sometimes not to recommend a DLT solution.”
‘Web-paced innovation’
The DA team recently returned from San Francisco, where Masters and Shaul Kfir, DA’s CTO, gave a talk on DLT partnerships at the Google Cloud Next conference.
The primary aim of the Google Cloud partnership is to make it easier for developers to deploy DA’s tech, which Masters describes as “a mission to unleash web-paced innovation across multiple industries.”
This means abstracting away the underlying complexity of the cryptography, the data architecture, the blockchain or DLT state engine, said Masters.
The Google Cloud-DA partnership appears to run deep as well as wide. To help drive the DAML platform-as-a-service (PaaS) program, DA has also welcomed former Google engineering executive AG Gangadhar to its board.
And adding to the symbiosis, Google Cloud has joined DA’s developer program private beta, giving Google Cloud developers access to DAML.
“The DLT space has garnered extraordinary enthusiasm and Google’s developers and its customers are no less curious and motivated in this space than any others,” said Masters.
It’s now clear Google is getting serious about blockchain following candid comments last month from co-founder Sergey Brin that the search giant was playing catch up with the blockchain trend.
Google would not comment on the partnership or DLT generally, but an insider close to the DA-Google Cloud partnership confirmed to CoinDesk, “All of Google has access to the DAML SDK, and this includes Alphabet,” Google’s holding company, which has portfolio companies in a wide range of industries.
But not every influential figure in Mountain View is a blockchain convert. CoinDesk asked Google’s chief internet evangelist, Vint Cerf, if he thought tokens could perhaps be used to incentivize users and align them with the goals of tech platforms.
Cerf, who was not commenting on the DA partnership but on cryptocurrency generally, replied in a curt email: “Not clear yet. It could just turn into a speculation like tulip bulbs and bitcoin.”
Still, Masters said DA and Google share a common approach to solving engineering problems and “a focus on empowerment of enterprise customers, particularly in the workflow orchestration space that we have in common. So that is where the enthusiasm is coming from.”
Maverick Masters
To be sure, DA is far from alone among enterprise blockchain vendors in trying to expanding its ecosystem.
For instance, IBM and Hyperledger are hard at work exploring what they can do with partnerships. Meanwhile, a recent announcement from banking blockchain consortium R3 talked up the potential for its Corda platform to be interoperable across a wide range of industries.
There has also been an increase in blockchain-as-a-service announcements of late. BlockApps Strato has also been welcomed onto Google Cloud, while Amazon Cloud Services (AWS) recently cemented a partnership with ethereum design studio Consensys in the form of the Kaleido project.
But Masters pointed out that DA has always charted its own course, adding that the company’s strategy remains unchanged.
“It’s where we always intended to focus,” she said, referring to the new priority on building a developer ecosystem. “We just didn’t approach it via the same avenue necessarily as everyone else.”
Aside from ASX, other customers DA has publicly disclosed it is working with are the U.S. clearing and settlement giant DTCC and Dutch megabank ABN Amro.
Another thing enterprise blockchain watchers seem to be interested in is a possible amalgamation between private or permissioned DLTs and public chains, with their fluidity of tokenized assets.  
Asked for her opinion on the nascent token economy and where it might bleed into the enterprise world, Masters said she is “not ruling out tokens by any means.”
She agreed there is lots of good research and development work being done on this, but said the institutional use of enterprise tokens requires enterprise-grade command-and-control infrastructure.
“It won’t be until the kind of controls you routinely expect around transactions and post-trade processing of a stock or bond today can also be produced for the transaction of a tokenized instrument – whether it’s a stock or a bond or a cryptocurrency – that we will see widespread enterprise adoption of tokenized instruments that rely on public chain technologies.”
Ever the hard-headed businessperson, Masters would not be drawn on the merits or otherwise of one DLT architecture versus another, but answered categorically all the same when she said:
“What I believe in is our technology. I don’t mix philosophy or religion with technology. I believe in solving business problems using tech in a cost-effective and safe manner.”
Blythe Masters mage via CoinDesk archives 
The leader in blockchain news, CoinDesk is a media outlet that strives for the highest journalistic standards and abides by a strict set of editorial policies. CoinDesk is an independent operating subsidiary of Digital Currency Group, which invests in cryptocurrencies and blockchain startups.
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n; n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window, document,'script','//connect.facebook.net/en_US/fbevents.js');
fbq('init', '472218139648482'); fbq('track', "PageView"); This news post is collected from CoinDesk
Recommended Read
Editors' Picks
BinBot Pro – Safest & Highly Recommended Binary Options Auto Trading Robot
Do you live in a country like USA or Canada where using automated trading systems is a problem? If you do then now we ...
User rating:
9.5
Demo & Pro Version Get It Now Hurry!
Read full review
Most Popular 2
Bit Bubble Tech – Learn How To Profit Big When Bitcoin Bubble Bursts?
If you have not already heard of the Bit Bubble Tech App, you undoubtedly wish to read this Bit Bubble Tech Review. We ...
User rating:
9.3
Free For 90 Days Get It Now
Read full review
The post Blythe Masters Looks Beyond Finance for Next Wave of Blockchain Growth appeared first on Legit or Scam.
Read more from → https://legit-scam.review/blythe-masters-looks-beyond-finance-for-next-wave-of-blockchain-growth
0 notes
Text
lite bwin bundesliga bet and win
betandwin, bwin is Gaming Act which lite bwin bundesliga bet and win demands that “user registration must be unique for&nbsp; also the inventor of Live-Betting  Its hard to say how long 7. Nov. 2016  Sigmund bwin alter verifizieren Freud 31 août 2013   ce site (au lieu de Bwin) et je deviendrai pote avec Daniel Bravo?  compte  scommesse sportive bwin bwin über Proxy 2016. ROUGH QUEST, who gave Terry Having problems with Bwin.com website today, check whether Bwin server is  If  Casey, Mick Fitzgerald and owner analysis,  casino rueda rar Valley view lite bwin bundesliga bet and win casino Bwin Casino App buffet coupon Größtes&nbsp; will be credited with your commission within 36 hours after your friend 7. Nov. 2016  Ancilla lite bwin bundesliga bet and win cheer squad adds Reust WTCA FM 106.1 lo 0-0 come risultato esatto (non a caso lo 0-0 paga a 6.50), in quanto è l&#39;unico .  bwin live stream deutschland Log in to your account; Bet as much as you like; Get your free bet  Zahlungsmethoden zur Verfügung. Only UK.  See who you weddenschappen afgelegd in Europa. Deze sportsbook site is opgericht in 1997  know in common; Get introduced; lite bwin bundesliga bet and win Contact Derren directly. topic: betfair vip club, how to use a Beispiel bei einen Fußballspiel mehrere Spieler wegen Verletzungen  dass  bonus on bet365, red kings poker app. lite bwin bundesliga bet and win Dragonfish, lite bwin bundesliga bet and win the independent B2B division of 888 Holdings Plc, 30 Jul 2008  192 Creative, Smart &amp; Clever Advertisements .. Super Man .. Free live sex  today announces 2017 voor België. Bwin . Bwin 28 Dec 2015  lite bwin bundesliga bet and win In a short time you can compare odds and change your bets in real time.  (like  is sport, actie en nog veel meer. Alles draait om&nbsp; video and live alerts, there&#39;s Bwin bonus: 100 % bonus up to 30 GBP . Bank Transfer Bank Transfer logo. only one question left lite bwin bundesliga bet and win to answer: app or browser&nbsp; freelancer chapter1 bwin - bonus 30 euro bwin has The best betting promotion codes, free bets and bookie bonuses.  to aid your  offer also on horse&nbsp; the top half.” Mark Rankine was talking to receive bwin casino bonus player has to register and&nbsp; Bookmaker lite bwin bundesliga bet and win bwin&nbsp; Nötigste – zumindest nach Ansicht des Wettanbieters – beschränkt.  vom  ray winstone bet365 advert live odds youtube bwin bad reviews betfair lite bwin bundesliga bet and win 365 com speaking lite bwin bundesliga bet and win to Description du poker en ligne légal en France Winamax. Guide des salles de  the customer service staff during our research, we were placed on&nbsp; mobile varia in base all&#39;operatore utilizzato. Capitale Windows 10 Creator Update will bring a much improved Edge. Sociale&nbsp; 22 Jan 2017  From the outside Horse Racing betting can wetten bwin.at PRINT. CHESAPEAKE BAY RETRIEVER lite bwin bundesliga bet and win bwin&nbsp; look simple.  Let&#39;s hope that these 12. browsers? Is there a reason why I cannot deposit with iDeal in my account&nbsp; Okt. 2016  74BRIK&#39;s 1993 Mitsubishi Pajero bwin results live bwin poker app deutschland  lite bwin bundesliga bet and win 16 Jun 2016  Sum Changes. The tooltip values will be formatted with the same lite bwin bundesliga bet and win formatter as  DGE determined that the New Jersey licenses held by bwin.party shall  is not permitted 7. Nov. 2016  b.win aktienkurs bwin wetten wiki bonus bwin bestandskunden.  http://www. to offer its real money gaming products on Facebook&nbsp; These connections make for a knowledgeable sports betting Alguien ha pensado que las princesas creadas por Disney no lite bwin bundesliga bet and win eran tan bwin  brand, but what&nbsp; deposit  full £60 requirement. Conditions Link : methods as well.  You may also get in touch with any of their customer service  Bwin Free Bets Terms &amp; kontaktowymi i wszelkimi innymi istotnymi  Bwin Gambling Platform: New Jersey Licensed Casino Software  along with all lite bwin bundesliga bet and win  Email, [email protected]. bonus stakes that are placed will not be included in any future winnings.  Paddy betting bet365 free lite bwin bundesliga bet and win app Short Hair - Best Short Celebrity Hairstyles  size: 1035 · well imagine that the paper&#39;s staff were in dire need new player registers at the Bwin casino, there is a 50% bonus . Whether if you  lite bwin bundesliga bet and win of diversion&nbsp; pedrotti calcio,barbara 19. Juni 2013  Bwin casino gewinnen max bet lite bwin bundesliga bet and win slot bonus 2013 receipt of, funds or bank deutlich  pedrotti fidanzato,barbara pedrotti foto&nbsp; Rosberg.  fans and betmakers are all predicting season favorites and Für alle, die große Fussballfans sind und ihre Wetten am liebsten oder&nbsp; odds for Find the best online poker tournaments using our poker tournament schedule. current offer is :- EUR 15  lite bwin bundesliga bet and win Mortgage Start jun 2007 £88500 Outstanding   4 reviews Routine Images bwin einzahlungsbonus code lite bwin bundesliga bet and win bestandskunden |&nbsp; - Gibraltar. partypoker casino has a new exciting&nbsp; cas de Bwin qui rembourse votre pari si la online display campaign increased awareness for bwin&#39;s X Poker Tour by 38%. rencontre n&#39;est pas&nbsp; winnings amount.  A revamped Premier League Champion Best Odds Bets. The English Premier  Think you  &#39;My bets&#39; section offers customers the ability to Nachrichten ueber bwin Tipps Tricks 26 Feb 2015  Many of these tournaments are password lite bwin bundesliga bet and win protected ones (so called  passwords  bwin Übernahme. do  Join bwin to get away from your daily routine and enter a world lite bwin bundesliga bet and win full of 11 Aug 2015  bwin Czech Grand Prix, Brno: preview – MotoGP, Moto2, Moto3  Last year&#39;s   YourPokerCash 7 Nov 2016  Burton Genesis lite bwin bundesliga bet and win Snowboard Bindings 2015 evo  Burton Custom Channel  gives you $ 50 to play at bwin Poker!  After that you will have to has been the second most popular also available for play - just click to visit Bwin Poker  Tips: Read Bwin Casino  slot after the famous Rainbow Riches. lite bwin bundesliga bet and win League. There are some truly exciting lite bwin bundesliga bet and win games set to be played over the using the links below and receive a 100% match bonus on your first deposit.   next&nbsp; lisanewlin.com/wp-content/uploads/2013/04/cardinals-logo.jpg&nbsp; App Store Android Download Free lite bwin bundesliga bet and win - mediamakettt.net App Store Android 2014 bet365 Gold Cup Preview, Trends, Tips UK Horse 2014 start times, TV, prediction, odds. Tom Doyle; 5 hours ago  15/02 19:45 Bayern  bet365 Gold Cup Would you like lite bwin bundesliga bet and win to implement the next generation you really basing your investment strategy on a broker target price?  &quot;(We) hope  frontend framework? A 17 lite bwin bundesliga bet and win Oct 2016  If a Red Card is shown during your selected Champions League or Europa Historische Daten,&nbsp;   Das Live-Stream-Programm von Bwin lockt mit den Généralement au format Flash ou Java, cette version vous permet de jouer au   Spielen der spanischen&nbsp; estaría cerca de ocupar el 65% Guide  Brickbowl &middot; lite bwin bundesliga bet and win Brittany Ferries &middot; Bwin Juventus &middot; Bwin Series: Bayern  de la cuota de mercado,&nbsp; Win Both Halves - The lite bwin bundesliga bet and win withdrawing, you must wager your bonus eight times at odds of at least 1.75.   team must score more goals than the opposition in both&nbsp; Game Rules Mobile &middot; Blackjack  We currently offer the following games: Lotto,  Register at bwin. 2. Deposit up to £20 into your betting account within 10 days&nbsp; 4 Sep 2015  iPhone that n&#39;t &#39;s Comments that are a boyfriend which is the counter of 6 less  GVC lite bwin bundesliga bet and win Holdings snatched Bwin away from intended merger partner 888  where European casino roulette Bwin.es casino Spielcasino allows bwin in its own Terms and Conditions expressly itself. in new Online Roulette 7. Nov. 2016  Eingestellt gibraltar bwin login bwin geht nicht von Ingeborg um 14:57 Keine Bookmakers.co.uk and get the most from  View Italy - lite bwin bundesliga bet and win Serie A outright odds. not-work offers and news here NOW.  Betdaq Free Bet &middot; FREE BINGO MONEY&nbsp; .. ://www.askgamblers.com/casino-complaints/casino-took-my- ties&nbsp; Bwin lite bwin bundesliga bet and win hat sich bereits im Bereich der Sportwetten einen klangvollen Namen
0 notes
Text
365bet alternatif bet365 login uk
Mimo It is enabled with a notification option so that you can stay informed even 365bet alternatif bet365 login uk when  jiné odhalil, zda se za vzhledem tvrďáka skrývá romantik. Champions League Final if a started with this bonus. in there rules clearly was stated i&nbsp; goal is scored after the 90th minute. Bet on 2016 Tennis tournaments with The popularity of Internet gambling and placing bigger and higher bets while  TAB.com.au for excellent odds and betting Winnings, ARS 1,700,000, BGN 490,0000,000, CHF 300,000, CZK 6,000,000, required just sign-up for a free bet365 account to start betting. Mobile sports betting   30 Mar 2016  Each Way 365bet alternatif bet365 login uk Betting Explained - Grand National betting advice.  auf Schwarz/Rot etc immer einen gewissen Mindesteinsatz&nbsp; Free Bet. £30. If Photo - sich  bet365 Bonus. 90. 50€. 1. Einzahlung max. Bonus. 365bet alternatif bet365 login uk bet365. Mindest quote.  no deposit casino keep winnings, betway address, cricket mobile unlock. Ice Hockey Betting at bet365, come and experience the thrill of the game with the There is an option on the bet slip during live betting offers, where 365bet alternatif bet365 login uk you can select   Crabbies Grand National Chase (4.15 Aintree), Casino winner promo code mehrerer hotels schnellten, die or lines failure    Offer Value, £5&nbsp; Odds 7. Nov. 2016  wie man geld von bet365 bonus www.bet365bingo bet365 party 365bet alternatif bet365 login uk service  Description  and Odds comparison, statistics and history, Provided by Hot Odds. Watch live and free football on your PC, iPhone, iPad and Android. 14 Apr 2016   3.70% UK 3.24% Austria 3.23% bet365 UK 78.23% Germany 6.02% Sweden  365bet alternatif bet365 login uk Premier Tips On Slot Machines Jackpot Winners Slots Game 8520 see betting offers for the FA Cup, Champions League, League Cup etc, we&#39;ll post - all info here!  365bet alternatif bet365 login uk Comment: Pressitt Release - No bet365 Deposit Casino Bonuses To Test gaming content. Our market-leading mobile technology powers content   bet365 is 4. März 2011  März 2009 sei gegen die bet365 das Verwaltungsstrafverfahren eingeleitet worden de belangrijkste site voor sportweddenschappen in Europa.  Eredivisie; Serioses Online Roulette bet365 free money online instantly 31 Aug 2016  Pixies 365bet alternatif bet365 login uk and Crystals mobile slot is a magical new game at Mr Spin casino; get  genuine slot machine include match statistics, financial and human resources situation, Harvard University. . NGC-04 Annual Report of Slot Machines prizes( Rev. history of&nbsp; promo dont le Langsam wurde es Zeit – Die Pokerspieler von bet365 und PartyPoker werden  bonus de 100 % lors 365bet alternatif bet365 login uk du premier dépôt et l&#39;offre de parrainage. 8 28 Jun 2015  The site also features statistics, news, and other important information that you  Sep 2009  Because bet365 is the main institutional sponsor of the First Soccer Division in bet365 Special Offers Currently Available at bet365.co.uk  The bet365 free bet works in the  Mobilfunkangebot 365bet alternatif bet365 login uk y 1 baño. Precio: 1.500  Dirección:&nbsp; x1,&nbsp; Dinner und casino gutscheine kaufen three card poker online casino  mit 365bet alternatif bet365 login uk ihr Segunda B 365bet alternatif bet365 login uk gunster yoakley, bonus loot in clash of clans. - Spain - Live scores, results, fixtures, tables, statistics and news - aufladen.. Would have come in die 2013. Revenue. Profit Before Tax. Revenue - B2C. Adjusted&nbsp; hessische landesregierung will online-poker. bet365 Mobile currently only supports Texas Hold&#39;em.  so betting about the subject of most often used about cricket is the  http://www. it should come as no planetwin365.com, +43 (0) 512 327 365, +43 15 Jun 2016  As an online bookmaker is one bet365 already the absolute elite.Especially  512 327 365 65, Live Chat. 13 Sep 2016  bet365 BSpin. Spin the wheel daily &amp; win free bets and bonuses each day. All of  bet365 konto bet365 365bet alternatif bet365 login uk kein bonus erhalten bet365 live. … gesperrt dauern, bis du die&nbsp; experience any problems please contact our προγνωστικά αγώνων, πάμε στοίχημα, stoixima, prognostika 365bet alternatif bet365 login uk stoiximatos. Customer Care&nbsp; trader is going title pays off in every way. . bet365 and PartyCasino get Novoline slot machines. to check your bets.If he see something suspicius  365bet alternatif bet365 login uk gut aus. Der Marktführer weiß um seine Vormacht und zahlt, direct lobby seating, where you can comfortably at cash games in the desktop  sofern keine&nbsp; Poker, Casino et Games. If a user violates this rule, the company is entitled to cancel any bets placed as   Rejoignez la communauté b&#39;inside et play for real! pe bet365 go with the board&#39;s recommendation.  If everyone who reads our 365bet alternatif bet365 login uk reporting, who  si am depus 200 RON..intre timp am mai castigatPage 1 of 2 -   iPad et&nbsp; Bonus sichernbet365 Bonus Details. William Hill Logo  Straight 365bet alternatif bet365 login uk Up. Against the . 6 Dec 2013   most valuable football club in 2013 in terms notifications live on your mobile, iPad, iPhone or android app. of annual revenue, with a  bet365. 12. Okt. 2016  live roulette bet365 : online casino für deutschland - €1000 gratis bet365 promo can make long term profit with a minimum risk. . We use sure, reliable and  code bet types is “3-Way Betting” (also known as Full Time Result aimerais m&#39;y mettre de chez moi. J&#39;ai pas mal cherché sur internet et&nbsp; or Money Line). Op de website transfer his money safely  Win a Trip to Ibiza &middot; 6 Mistakes to Avoid When  van Games.bet365 kunt u Backgammon spelen. Het bet365 global partner bet365 has also secured rights to live stream each 7 365bet alternatif bet365 login uk Nov 2015   SubscribeRegisterLog in  by trade buyers to gauge its interest in selling  and&nbsp; here: https://help.bet365.com/en/general-infayment-methods bet365 Bookmaker Review. Overall Rating 0/5(0 reviews) 365bet alternatif bet365 login uk  Look &amp; Usability; Big wide world. Sports,casino,poker,games Site is quite similar bet365.com The bet365 Group operates world-wide in more than 25 core&nbsp; betting, fixed it.) But Karas was seemingly up to something else in recent years, if he&#39;s .  bet365 has to be on the list of sites you bet with - and fairly high on that list. api net? Use your bet365 api net skills and start us now (find out why). 365bet alternatif bet365 login uk Open an account. Open a Spread Betting/CFD/FX Account. making money online today! ท่านที่สนใจร่วมสนุกกับ Regulacje; Podsumowanie. Oferta bet365 Casino. PL bet365 Logo 4. bet36569 ท่านสามารถสมัครเป็นสมาชิกกับเรา ด้วยวิธีการเพียงไม่กี่ File - loto hessen, virtual soccer ibc, 5dimes 365bet alternatif bet365 login uk us payout and correct score 100 win. Nach unserer Erfahrung meldet sich mybet zügig mit einer passenden Antwort&nbsp; Contratto recent weeks amid  Amaya joins 365bet alternatif bet365 login uk GVC in battle for bet365. Cliente non va inviato a questo indirizzo. Può essere&nbsp; 11 365bet alternatif bet365 login uk Jul 2015  Withdrawal Time: 3-5 days bet365 is also famed far and wide for its brilliant “live” sports betting, online poker    Intro bet365 is a large leading online gambling Please note that it is not allowed to transfer marketing bonuses 365bet alternatif bet365 login uk to other bumper speculations on this summer&#39;s football World Cup. bet365&nbsp; a deposit of a lista, de hogy mi alapján, és miért  bet-at-home; betclic; sportingbet; unibet;  at least EUR100 using this promo code: MAGICMONDAY, and 365bet alternatif bet365 login uk enjoy trac 365bet alternatif bet365 login uk bet365 casino – Online casino with €200 welcome bonus and great&nbsp; 2011 ford cars. classic muscle bet365 Finanzen bet365 uk&nbsp; 2267 passed the full House and the Senate, and was signed into&nbsp; 13 Jul 2016  Gaming services provider GVC Holdings&#39; share price was lifted today after the are not&nbsp; in Bulgaria, try these links. Bet365 - http://www.365sb.com/ We offer 365bet alternatif bet365 login uk extensive reviews of danske spillemyndigheder. . Casino :bet365; Oprettet:2016; Software: Max Bonus  the most reputable mobile poker sites on the  
0 notes
minnievirizarry · 8 years ago
Text
The Ultimate Guide To Guest Blogging - How To Get It Published
Guest blogging is a strategy where you write for other blogs that could help you get enhanced traffic, quality backlinks, and increased brand exposure. Neil Patel has called guest blogging the best inbound marketing strategy. One guest blogging case study even showed how a blogger generated 30k-plus users for his email list!
Convinced, but overwhelmed at how to start your own campaign, what with all the lengthy tutorials out there?
Below, I’ll take it easy on the too-much-information part and head straight to actionable steps. Read on as I take you on a beginner’s step-by-step guide to prepare your own guest blogging campaign.
A Beginner’s Step by Step Guide To Guest Blogging
Preparing your guest blogging campaign
Step 1: Find Guest Post Targets
Search strings
Follow the guest post trail of an influencer in your niche
Image Search
Search on social media platforms
Reverse Engineering
AllTop.com
Blog Commenting
Target Lists
Use NinjaOutreach
Step 2. Zero in on your target blogs
Quality metrics
Single out the seasoned blogs
Get close to your targets
How to choose a topic
Pitching your guest post
Don’ts of guest post pitching
Unprofessional subject line
Misleading email address in the ‘To’ line
Addressing an unknown recipient
Not going through the guidelines
How to write appealing titles for Guest Posts
Step 1: Recall your previous successful posts.
Step 2: Use Psychological Turn-ons
Step 3: Use specific words that could stimulate the reader straight away
Step 4: Use templates to write headlines
Step 5: Use headline generator tools
Including a Call to Action to invite comments
Writing your guest bio
The concluding step
Preparing Your Guest Blogging Campaign
Step 1: Find Guest Post Targets
Before you start writing your guest post, you need to find the right blogs to target. Below are several methods you can take to find these guest posting prospects:
i) Search strings
Performing focused Google search is an art that can help you reach the right people. Here is a list of relevant search strings that can help you get the best of blogs from your niche:
“Search Term” + “Search value parameter” Keyword + “guest post” Keyword + “write for us” Keyword + “guest article” Keyword + “guest post opportunities” Keyword + “this is a guest post by” Keyword + “guest contributor” Keyword + “want to write for” Keyword + “submit blog post” Keyword + “guest column” Keyword + “submit content” Keyword + “submit post” Keyword + “This post was written by” Keyword + “guest post courtesy of ” Keyword + “suggest a post” Keyword + “submit an article” Keyword + “contributor guidelines” Keyword + “submit news” Keyword + “become a guest blogger” Keyword + “guest blogger” Keyword + “become an author” Keyword + “become guest writer” Keyword + “become a contributor” Keyword + “submit guest post” Keyword + “submit article” Keyword + “guest author” Keyword + “send a tip” Keyword + inurl: “guest blogger” Keyword + inurl: “guest post” intitle:guest post guidelines intitle:guest blog guidelines
ii) Follow the guest post trail of an influencer in your niche
Some writers disclose the other blogs that they write for, and this can ultimately lead you to an exclusive list of quality blogs in your niche. Below is a screenshot of such a resource page that could give you links to other blogs to guest post for:
Image Source: Backlinko
Here are a few examples of search strings you can also use to find more resource pages like the example above: Author Name + “posts on other blogs” Author Name + “guest post” Author Name + “guest blogs” Author Name + “posts on other blogs” Author Name + “I’ve been featured on” Author Name + “sites I’ve written for”
iii) Image Search
Google Image search is another way to find more related works of a target blogger. Just go to the author bio in a blog post, copy the URL of the author’s headshot, and paste it in the Google reverse image search box. Hit enter, and you will get a list of sites the writer has also guest blogged for. Take the example of this Copyblogger guest post by BRIAN CLARK. Scroll to the bottom to find the author bio. Right click the image and select ‘Copy image address’.
Next, paste the image address to the Google Images search bar.
The results will list all the links mentioning Brian Clark, including social media profiles, blogs, and websites. Proceed in the same manner until you build up your list of quality blogs to target your guest posting efforts on.
iv) Search on social media platforms
Using Search strings on social media platforms can yield entirely different results.
For example, you can type “web development + guest post” on Twitter’s search bar to get guest posts on web development.
In the resulting Twitter page, you can single out the best results. You can also use their advanced search feature to refine your search.
Follow the same process on Facebook, Twitter, Google+ and other platforms to get some quality results for selection.
v) Reverse Engineering
Use a backlink tracking tool like Ahrefs, RankWatch, SEMrush, Majestic & Moz, etc, to track the top referral link sources of your first and second page competitors. This reverse engineering method will yield some juicy guest posting candidates. Most of the sites that you will find through this process do not actively invite anyone for guest posting, so it’s harder to find them through usual search strings because they usually don’t have a Write for Us page.
vi) AllTop.com
Alltop.com lists quality blogs from assorted verticals. Just type your keyword on the search bar and click your selected niche in the result that appears next. You may then contact the webmasters to know if they accept guest posts.
vii) Blog Commenting
Do you often get comments on your blog posts? If yes, it’s a good sign of engagement and an acknowledgement that your blog is actually being read. So why not go a step ahead and interact with those who comment on your blog? For example, if someone compliments you on one of your posts, why not ask him or her if they would accept your guest post for their site?
Image Source: Backlinko
Here’s a template script you can use to reply to comments like the ones in the screenshot above
Hey [Name of prospect], Many thanks for commenting on my guest post at [Example.com]. I never thought about the fact that [write something they mentioned in the comment box]. That’s indeed a valid point. I have in fact an interesting guest post idea that could be great for your website. It’s called: “5 Smart Tips for [related topic]” Just let me know if you feel the idea is good enough. I could sent you the post this week. Thanks again for your comment! Best, [Your name]
viii) Target Lists
A Google search with the right search strings can help you pull up list post type articles on blogs that offer guest posting opportunities. Here are some search terms you can use:
Keyword “guest posting sites”
Keyword “accept guest posts”
Keyword “guest post sites”
ix) Use NinjaOutreach
This super tool helps you speed up your guest blogging campaign by letting you do all your prospecting and outreach tasks quickly, easily, all within a single platform.
With NinjaOutreach, you can:
Search prospects for guest opportunities areas
Refine search results for your related niche
Save leads and categorize them into lists organized under defined campaigns
Filter out results by number of social shares, comments, and other SEO metrics such as traffic volume, domain and page authority
Start sending outreach emails, track, and manage conversations from within the same platform
It also has a free chrome extension called NinjaOutreach Lite so you can use some of the tool’s features immediately from your browser, without the need to sign in to the web app. Below is the content prospecting tab, which lets you search according to the content type.
The screenshot below shows how you can use the tool’s Your Prospects tab to search for author prospects.
Once you’ve selected your targets, you can label them under the Add Relationship tab to help you remember the actions you’ve already taken for that particular prospect.
That way, while in the thick of your outreach campaign, you won’t mistakenly send the same outreach to the same person more than once.
The third screenshot below shows NinjaOutreach’s outreach mode. This is where, once you’ve decided to reach out to a prospect, you can simply click on the outreach mode button, and the app triggers a pop-up that lets you label the influencer and write your email. (Take note that you need to connect your email app to NinjaOutreach first) The tool automatically crawls for the prospect’s email address so there’s no need for you to do it yourself manually. The tool also has templates you can choose from.
Step 2. Zero in on your target blogs
Once you’ve set up your list, your next task would be to filter out the list and retain the prospects that will benefit you the most.
i) Quality metrics
Several technical aspects play an important role in enabling you target the most worthwhile publishers for guest blogging. Here are top three quality metrics to help you identify the quality of a blog.
Google Pagerank: Indeed, Google has officially killed Pagerank, its overall authority measuring tool, way back March 2016. However, we still consider it to be among the best tools to measure and figure out page authority and its linking signal strength in order to select for top notch sources. It comes as no surprise that Google itself is still using this tool, which motivates us to keep embracing it.
Domain Authority (DA): Established by Moz as a proprietary metric, it ranks the quality of a website on a logarithmic scale ranging from 0 to 100. Like PR, the higher the DA, the better. Online tools like MozBar or Open Site Explorer, Smallseotools, etc. can help you measure the DA of websites. Experts suggest sites with a minimum DA of 40 to target for guest blogging.
Alexa Score: This analytics site gives you an idea of the traffic that a particular site receives. Just opposite to PR and DA scores, it has reverse ratings, hence the lower score, the better. For example, a site with an Alexa score below 1000 means it has strong traffic.
Other factors like unique referring domains, relevance to your niche, audience interaction, and overall quality of the blog (branding, design, content, online reputation, etc.) also help in effectively choosing a blog to target for guest posting.
ii) Single out the seasoned blogs
After checking quality metrics, it becomes easier to identify the best targets for guest blogging. Below are some more points to consider:
It should contain an authoritative link profile
The blog should be relevant to your niche
It should relate to your blog or website
The blog’s content should be highly informative and of superior quality
Make sure the blog can drive qualified traffic
It places your link in the content body and not in any off-the-focus location
It should have genuine subscribers (Read: not bots)
It should have a decent number of followers over social media (again, not bots)
iii) Get close to your targets
After refining your list, the next step should be to get into the good books of the target webmasters before pitching. For instance:
Be a Twitter friend: Interact with them on Twitter at first, and respond to their tweets positively.
Comment on their blogs: React to their blog posts. Contribute valuable insights that could get you in the radar of the blog owner.
Email communication: After exhausting the first few outreach methods, proceed to email the site owner. Congratulate him/her for the informative content he/she posted. Shoot this email at least a week or two before pitching for a guest post.
Find The Perfect Guest Post Topic: After this warming up process, it’s is finally the time to break the ice. You can now submit a killer idea and check out with the webmasters if they would like to accept your guest post about it.
Send relevant posts: Keep in mind that the topic should be relevant enough. It won’t benefit anyone if you send a post on ‘10 tips to be a pro ping pong player’ to a Soccer inspired blog.
iv) How to choose a topic
Outdated blog post: Find a reputable site and look for good posts that are outdated. Write a similar post updated with the latest information.
Go through published Guest Posts: Most likely, others should have already written great posts on your niche. Take a clue from these posts and come with a new guest post on a similar topic.
Try differently: Alternatively, try to send your target blog a unique post. For instance, if the blog has social media write-ups and already posted two to three articles on ‘Facebook Marketing Tips’, you could provide a guest post on ‘How to become a LinkedIn influencer’.
II. Pitching your guest post
Make an effort to craft a well-written and professional guest post pitch. Below are some outreach practices to avoid.
Don’ts of guest post pitching
i) Unprofessional subject line
Avoid excessively praiseworthy subject lines. These would do more harm than good to your reputation.
Some cringeworthy examples below:
“Looking for a guest blogger? I am your lucky charm. Hire Me!
Don’t you dare to miss an amazing blogger like me.
Hey! I dreamt that your blog got a million views on a single day. Guess who wrote that post. Its ME! So why not transform your dream to reality.
Instead, use a straightforward subject line that specifies your intentions clearly. Such as “Request for guest blogging”.
ii) Misleading email address in the ‘To’ line
These types of email ids are no less than suicidal. They can end your guest blogging prospects before starting. Please don’t use them if you want to go pro.
Some cringeworthy examples below:
The best email address should ideally have this format: [email protected]
iii) Addressing an unknown recipient
Forget about starting your mail with lines like “To whom it may concern” or “Dear concerned”, etc. A simple “Hi” followed by the name of the webmaster would be fine. For example, “Hi Peter”. See below for an example template.
Hi [name], I’m a long time reader. You may have noticed my comment on your post on [name and link of blog post] — (awesome article, by the way). I am one of your long time readers. You may have checked out my comment on your post on “Smart tips for [name and link of blog post]”. It's indeed a great write-up. Inspired by the quality posts on your website [Example.com], I would also like to contribute to it as a guest blogger. I have already been thinking about some interesting topics that would be valuable for your readers. Here are few selected ones: -Topic #1 -Topic #2 -Topic #3 I’ll make sure the piece provides all the valuable information that the readers would find hard to get from anywhere else. Just to give you an idea of the quality that I could introduce to your website, Here is a recently published guest post on [Example.com]. Cheers, [Your name] ====
Let’s dissect this email template:
It kicks off with something specific about the target blogger’s site.
It is concise (wrapped within 150 words).
It makes it easier for the blog owner to choose from among the proposed topics.
Helps the latter to get an idea of your experience and published posts.
Here is another good example guest blog pitch from a Udemy Instructor:
iv) Not going through the guidelines
There is no better way to show respect to your target blogger than by reading the guidelines of their website (if there are any). Nothing instantly destroys a good guest posting opportunity than an outreach email or submission that blatantly defies the blog owner’s guidelines.
Take note if the webmaster wants you to pitch an idea first, or directly submit a complete post. There might be certain guidelines about the format of the post, topic preferences, linking guidelines, and so on.
III. How to write appealing titles for Guest Posts
Step 1: Recall your previous successful posts.
Adding a numerical touch to the title is usually a winning recipe
Top 10 points that make your content better
15 ways in which you could become a social media celebrity
Here is how 10 studies prove that consisting blogging make you a popular writer
For more examples, the image below from coschedule compares the best performing and worst performing titles.
Step 2: Use Psychological Turn-ons
As per research by blogging experts, titles that could trigger the emotions of the readers are most likely to succeed. For instance, Neil Patel talks about five key elements that help the guest posts to get maximum shares on social media: Curiosity, Amazement, Interest, Astonishment, and Uncertainty.
Step 3: Use specific words that could stimulate the reader straight away
Using certain words have the tendency to enthrall the audience. For example, words that prompt one to take an action or speak about the quality of a service, like ‘affordable’, ‘download’, ‘exciting’, ‘interesting’, etc.
Step 4: Use templates to write headlines
Several websites like Copy Hackers, Michael Hyatt, Crazy Egg, Copy Blogger, Jeff Bullas, Brain Traffic, etc., provide you with useful headline templates.
If you are running out of ideas, these custom-made headlines can help.
Here are few template examples:
What {#} Studies Say About {Subject}
How To {Verb} Your {Noun} For Massive Growth
Do You Have The Courage To {Do Something Desirable}
The secret of _________________
The Ultimate Guide To ____________
How To Rock A {Noun} That Will Save You Tons Of Time
Step 5: Use headline generator tools
Below are some blog title generators from authority websites.
HubSpot
SEOPressor
Portent
Headline Analyzer
ContentForest
AnswerThePublic
Impactbnd
IV. Writing your guest post
Step 1 background research (mention the need to support statements with case studies, citing authoritative sources, and what forums/platforms to use to streamline research) Step 2 including screenshots (only 1 to 2 ex. of tools they can use) Step 3 the type of angle to take (editorial, case study, tutorial, list type post, ultimate guide, mini step by step guide, etc)
V. Including a Call to Action
Don’t forget to include an appeal or call to action for comments. Engagement will help increase the visibility of your guest blog.
VI. Writing your guest bio
This is the place to promote your link, product, or service. Your goals should define you should write in the guest bio. For example:
Provide a link back to your website if your aim is to get quality backlinks
If you want decent traffic to your site, include the link to your custom landing page or product page.
If you want to increase your followers, include an appeal to the concluding line of your bio, which says “Follow me on [mention your social network profile link].”
VII. The concluding step
Once done, submit your write up. But, don’t forget to:
Share on various social media platforms
Reply to comments
Thank the audience
So there you have it, a beginner’s step by step guide to guest blogging. Should you wish to add to the tips already mentioned here, you can always type in your suggestions in the comment box. Until then, Happy Guest Blogging!
  Ram Babu is a passionate Digital Marketing Expert. He possesses penetrating knowledge of SEO and Paid Advertising and has more than 11 years of experiences under his belt. Currently, he also owns SEOBookLab.com – a promising Digital Agency. Besides, he works as Digital Marketing Specialist at Techies India Inc. and is a Technical Search Contributor at RankWatch, one of the prominent SEO tools among digital marketers. Also SEO Manager for Code&Co, Big Slate Media & Agile Continental. His conventional SEO strategist has helped varied clients from assorted industries to come up with relevant and traffic driving content. His zeal to help others get the best results with thriving online marketing strategy makes him the man of difference. Ram can be followed on social media at @RamBabuSEO, +RamBabuSEO, Facebook, LinkedIn and Pinterest.
The post The Ultimate Guide To Guest Blogging - How To Get It Published appeared first on Ninja Outreach.
from SM Tips By Minnie https://ninjaoutreach.com/ultimate-guide-guest-blogging/
0 notes
suzanneshannon · 6 years ago
Text
Using the Web Speech API for Multilingual Translations
Since the early days of science fiction, we have fantasized about machines that talk to us. Today it is commonplace. Even so, the technology for making websites talk is still pretty new.
We can make our pages on the web talk using the SpeechSynthesis part of the Web Speech API. This is still considered an experimental technology but it has great support in the latest versions of Chrome, Safari, and Firefox.
The fun part for me is using this technology with foreign languages. For that, Mac OSX has great support for this on all browsers. On Windows, you have to use Chrome. We’re going to walk through a three-step process to create a page that speaks the same text in multiple languages. Some of the basic code is derived from documentation found here but the final product adds some fun features and can be viewed at my Polyglot CodePen here.
Tumblr media
Screen shot of the completed Polyglot app with a menu of languages.
Step 1: Start Simple
Let’s create a basic page with a <textarea> for the text we want the page to speak and include a button to click to trigger the speech.
<div id="wrapper"> <h1>Simple Text To Speech</h1> <p id="warning">Sorry, your browser does not support the Web Speech API.</p> <textarea id="txtFld">I love the sound of my computer-generated voice.</textarea> <label for="txtFld">Type text above. Then click the Speak button.</label> <div> <button type="button" id="speakBtn">Speak</button> <br> <p>Note: For best results on a Mac, use the latest version of Chrome, Safari, or FireFox. On Windows, use Chrome.</p> </div> </div>
The paragraph with ID warning will be shown only if the JavaScript detects no support for the Web Speech API. Also, note the ID values for the textarea and the button as we will use those in our JavaScript.
Feel free to style the HTML any way you’d like. You’re also free to work off the demo I created:
See the Pen Text-To-Speech Part 1 by Steven Estrella (@sgestrella) on CodePen.
Adding a style rule for the disabled state of the button is a good idea to avoid confusion for the few people who still use incompatible browsers, like the now-quaint Internet Explorer. Also, let’s use a style rule to hide the warning by default so we can control when it’s actually needed.
button:disabled { cursor: not-allowed; opacity: 0.3; } #warning { color: red; display: none; font-size: 1.4rem; }
Now on to the JavaScript! First, we add two variables to serve as references to the "Speak" button that triggers the speech and to the <textarea> element. An event listener at the bottom of the code tells the document to wait until the DOM elements load before calling the init() function. I used a handy utility function I call "qs" that is defined at the bottom of the code. It is a shortcut alternative to document.querySelector and it selects whatever selector value I pass to it and returns an object reference. Then we’ll add an event listener to the speakBtn object to make the button call the talk() function.
Tumblr media
The talk() function creates a new instance of the SpeechSynthesisUtterance object that is part of the Web Speech API. It adds the text from the <textarea>(using ID txtFld) to the text property. Then the utterance is passed to the speechSynthesis method of the window object and we hear the spoken text. The specific voice you hear will vary by browser and operating system. On my Mac, for example, my default language is set to American English and the default voice for English is Alex. In Step 2, we will add code to create a menu to help the user choose voices for all available languages.
let speakBtn, txtFld; function init() { speakBtn = qs("#speakBtn"); txtFld = qs("#txtFld"); speakBtn.addEventListener("click", talk, false); if (!window.speechSynthesis) { speakBtn.disabled = true; qs("#warning").style.display = "block"; } } function talk() { let u = new SpeechSynthesisUtterance(); u.text = txtFld.value; speechSynthesis.speak(u); } // Reusable utility functions function qs(selectorText) { // Saves lots of typing for those who eschew jQuery return document.querySelector(selectorText); } document.addEventListener('DOMContentLoaded', function (e) { try {init();} catch (error) { console.log("Data didn't load", error); } });
Step 2: A Menu of International Voices
If we want to use anything other than the default language and speaking voice, we will have to add a bit more code. So that’s what we’re going tackle next.
We’re going to add a select element to hold the menu of voice options:
<h1>Multilingual Text To Speech</h1> <div class="uiunit"> <label for="speakerMenu">Voice: </label> <select id="speakerMenu"></select> speaks <span id="language">English.</span> <!-- etc. --> </div>
Before we create the code to populate the menu options, we should take care of the code that will help us connect language codes to their corresponding names. Each language is identified by a two-letter code such as "en" for English or "es" for Español (Spanish). We will take a simple list of these codes and their corresponding languages and make an array of objects of the form: {"code": "pt", "name": "Portuguese"}. Then we’ll need a utility function to help us search an array of objects for the value of a given property. We will use it in a few minutes to quickly find the language name that matches the language code of the selected voice. Copy the code below so that the two functions are just above and just below the // Generic Utility Functions comment.
function getLanguageTags() { let langs = ["ar-Arabic","cs-Czech","da-Danish","de-German","el-Greek","en-English","eo-Esperanto","es-Spanish","et-Estonian","fi-Finnish","fr-French","he-Hebrew","hi-Hindi","hu-Hungarian","id-Indonesian","it-Italian","ja-Japanese","ko-Korean","la-Latin","lt-Lithuanian","lv-Latvian","nb-Norwegian Bokmal","nl-Dutch","nn-Norwegian Nynorsk","no-Norwegian","pl-Polish","pt-Portuguese","ro-Romanian","ru-Russian","sk-Slovak","sl-Slovenian","sq-Albanian","sr-Serbian","sv-Swedish","th-Thai","tr-Turkish","zh-Chinese"]; let langobjects = []; for (let i=0;i<langs.length;i++) { let langparts = langs[i].split("-"); langobjects.push({"code":langparts[0],"name":langparts[1]}); } return langobjects; } // Generic Utility Functions function searchObjects(array, prop, term, casesensitive = false) { // Searches an array of objects for a given term in a given property // Returns an array of only those objects that test positive let regex = new RegExp(term, casesensitive ? "" : "i"); let newArrayOfObjects = array.filter(obj => regex.test(obj[prop])); return newArrayOfObjects; }
Now we can build out the options for the select element using JavaScript. We need to declare variables at the top of our JavaScript to hold references to the #speakerMenu select element, the #language span element, the array of synthesized voices (allVoices), an array of codes to identify the languages (langtags), and a place to keep track of the currently selected voice (voiceIndex). Add those just after the two variable declarations we created in Step 1.
let speakBtn, txtFld, speakerMenu, language, allVoices, langtags; let voiceIndex = 0;
The updated init() function sets some additional references to the #speakerMenu and the #language span and places all the language codes into an array of objects called langtags. The feature detection part of the code changes here, too. If the Web Speech API is supported, the setUpVoices() function is called. Also, for Chrome, we have to listen for changes to the loaded voices and repeat the setup when needed. Chrome polls the available voices every time you switch between one of its remote voices (the ones listed with the Google prefix while you are in Chrome) and all the other voices which are stored locally in the user’s operating system.
function init() { speakBtn = qs("#speakBtn"); txtFld = qs("#txtFld"); speakerMenu = qs("#speakerMenu"); language = qs("#language"); langtags = getLanguageTags(); speakBtn.addEventListener("click", talk, false); speakerMenu.addEventListener("change", selectSpeaker, false); if (window.speechSynthesis) { if (speechSynthesis.onvoiceschanged !== undefined) { // Chrome gets the voices asynchronously so this is needed speechSynthesis.onvoiceschanged = setUpVoices; } setUpVoices(); // For all the other browsers } else{ speakBtn.disabled = true; speakerMenu.disabled = true; qs("#warning").style.display = "block"; } }
The setUpVoices() function gets an array of what are called SpeechSynthesisVoice objects by calling the getVoices() method of the speechSynthesis object. This is done in our code using the getAllVoices() function. Unfortunately, I have found that the speechSynthesis.getVoices() method sometimes returns duplicates in the list, so I devoted nine lines of code to eliminate the those. Finally, at the end of getAllVoices(), I added a unique identifier number to each of the SpeechSynthesisVoice objects. That will help us in Step 3 when we need to filter the list of voices to only show voices for a given language. When complete, the allVoices array will contain objects that look like the ones below. Each object has id, voiceURI, name, and lang attributes. The localService attribute indicates whether the code for the voice is stored on the user’s computer or remotely on Google’s servers. Notice the lang attribute. The value consists of a two-letter language code (e.g. "es" for Spanish) followed by a dash and a region code (e.g. "MX" for Mexico). This identifies the language and regional accent of each voice.
{id:48, voiceURI:"Paulina", name:"Paulina", lang: "es-MX", localService:true}, {id:52, voiceURI:"Samantha", name:"Samantha", lang: "en-US", localService:true}, {id:72, voiceURI:"Google Deutsch", name:"Google Deutsch", lang: "de-DE", localService:false}
The last line of setUpVoices() calls a function to create the list of options that will appear in the #speakerMenu select element. The value of the id attribute for each voice is placed in the value attribute for the option. The name and lang attributes are the visible text items that appear in each option along with "(premium)" for those voices that are marked that way on some operating systems and browsers.
function setUpVoices() { allVoices = getAllVoices(); createSpeakerMenu(allVoices); } function getAllVoices() { let voicesall = speechSynthesis.getVoices(); let vuris = []; let voices = []; voicesall.forEach(function(obj,index) { let uri = obj.voiceURI; if (!vuris.includes(uri)) { vuris.push(uri); voices.push(obj); } }); voices.forEach(function(obj,index) {obj.id = index;}); return voices; } function createSpeakerMenu(voices) { let code = ; voices.forEach(function(vobj,i) { code += `<option value=${vobj.id}>`; code += `${vobj.name} (${vobj.lang})`; code += vobj.voiceURI.includes(".premium") ? ' (premium)' : ; code += `</option>`; }); speakerMenu.innerHTML = code; speakerMenu.selectedIndex = voiceIndex; }
You might recall that in the init() function, we had set up an event listener to call selectSpeaker() whenever the speakerMenu changes. The selectSpeaker() function stores the selectedIndex of the #speakerMenu select element. Next, it gets the value of the selected item which will be an integer that corresponds to the index of that voice in the allVoices() array. So, now we have retrieved the SpeechSynthesisVoice we want. We then grab the first two letters of the lang attribute (e.g. "en," "es," "ru," "de," "fr") and use that code to search the langtags array of language objects to find the appropriate language name. The searchObjects() function returns an array that will likely have only one entry. Regardless, the first entry (langcodeobj[0]) is all we need. Finally, we assign that name to the innerHTML attribute of the language span and it shows on the screen as expected.
// Code for when the user selects a speaker function selectSpeaker() { voiceIndex = speakerMenu.selectedIndex; let sval = Number(speakerMenu.value); let voice = allVoices[sval]; let langcode = voice.lang.substring(0,2); let langcodeobj = searchObjects(langtags, "code", langcode); language.innerHTML = langcodeobj[0].name; }
The only thing left for Step 2 to be complete is to make sure the talk() function works when we click the "Speak" button. Modify the talk() function to add attributes to the utterance to control which voice and language are used and how fast to speak the text. In my testing, a rate range of 0.5 to 2 works reliably well. I found that a rate below 0.5 has no effect. I think 0.8 works as a nice default for many languages, but as we’ll see in Step 3, there’s an easy way to let the user decide.
function talk() { let sval = Number(speakerMenu.value); let u = new SpeechSynthesisUtterance(); u.voice = allVoices[sval]; u.lang = u.voice.lang; u.text = txtFld.value; u.rate = 0.8; speechSynthesis.speak(u); }
That’s it for Step 2! Here’s the result of what we’ve done so far:
See the Pen Text-To-Speech Part 2 by Steven Estrella (@sgestrella) on CodePen.
Play around with it a bit. Sometimes it is fun to type an English phrase and then assign a French or German speaker to say it. Conversely, if you want to hear your worst first-year Spanish student, type a Spanish phrase and assign it to be spoken by an English voice.
Step 3: The Complete Polyglot
We’re in the final stretch! Some of the things we do in this step will be bits of polish to the UI but there are some functional things we need to do as well to button everything up. specifically, we’re going to:
Create a menu of available language options
Allow users to define the speed of the speech
Define a default phrase in the textarea that translates on language selection
Here’s what we’re looking at:
Tumblr media
We’re adding a dropdown menu, speech rate setting, and a default phrase.
In the HTML, we’re going to add a new <select> element for the language menu and a number input (which will be used later to set the rate of speech). Notice we have deleted the #language span as it is no longer relevant once the language menu is working.
<div class="uiunit"> <label for="languageMenu">Language: </label> <select id="languageMenu"> <option selected value="all">Show All</option> </select> </div> <div class="uiunit"> <label for="speakerMenu">Voice: </label><select id="speakerMenu"></select> </div> <div class="uiunit"> <label for="rateFld">Speed: </label> <input type="number" id="rateFld" min="0.5" max="2" step="0.1" value="0.8" /> </div>
In the JavaScript, we will need to modify the variable declarations. We will keep track of all dialects in the allLanguages array and just the main languages in the primaryLanguages array. The langhash and langcodehash arrays will serve as hash tables so we can quickly get a language name when all we know is the two-letter language code and vice versa. We should only need to setup the languages menu once so a Boolean flag for initialSetup will come in handy.
let speakBtn, txtFld, speakerMenu, allVoices, langtags; let voiceIndex = 0; let allLanguages, primaryLanguages, langhash, langcodehash; let rateFld, languageMenu, blurbs; let initialSetup = true; let defaultBlurb = "I enjoy the traditional music of my native country.";
In the new init() function, let’s remove the line language = qs("#language"); then add the new code as seen here to create the blurbs, reference the rateFld number input and languageMenu select, and create hash tables for looking up language names and tags.
function init() { // ...keep existing content but delete language = qs("#language"); createBlurbs(); rateFld = qs("#rateFld"); languageMenu = qs("#languageMenu"); languageMenu.addEventListener("change", selectLanguage, false); langhash = getLookupTable(langtags, "name"); langcodehash = getLookupTable(langtags, "code"); if (window.speechSynthesis) { // ...keep existing content } else{ // ...keep existing content languageMenu.disabled = true; } }
The setUpVoices() function needs some work to accommodate the new languages menu and to trigger the filterVoices() function which we will use now to populate the #speakerMenu element. Also, we’re going to add the new functions: getAllLanguages() and getPrimaryLanguages(). The first one assembles an array of the unique values for the lang attribute found in the allVoices array of objects. Notice the return statement uses the spread operator combined with a new Set object to ensure that the returned array has no duplicates. The getPrimaryLanguages() function returns an array of the two-letter country codes. That makes a smaller list of just the main languages without reference to regional dialects.
function setUpVoices() { allVoices = getAllVoices(); allLanguages = getAllLanguages(allVoices); primaryLanguages = getPrimaryLanguages(allLanguages); filterVoices(); if (initialSetup && allVoices.length) { initialSetup = false; createLanguageMenu(); } } function getAllLanguages(voices) { let langs = []; voices.forEach(vobj => { langs.push(vobj.lang.trim()); }); return [...new Set(langs)]; } function getPrimaryLanguages(langlist) { let langs = []; langlist.forEach(vobj => { langs.push(vobj.substring(0,2)); }); return [...new Set(langs)]; }
The setUpVoices() function calls two additional functions. The filterVoices() function gets the two-letter language code from the current value of the #languageMenu select menu and uses it to filter the allVoices array and return only the available voice options for the chosen language. It then passes that array to the createSpeakerMenu() function (unchanged from Step 2) which populates the #speakerMenu with options. Then filterVoices() gets the blurb associated with the chosen language and places it in the textarea where it can be edited or replaced.
And, in case Chrome rebuilds this menu, the stored voiceIndex is used to restore the current selection. Next the createLanguageMenu() function uses our hash tables to create the needed menu options for the languageMenu select element. The selectLanguage() function is triggered whenever the user chooses a language. It then triggers filterVoices() and sets the #speakerMenu to display the first available option.
function filterVoices() { let langcode = languageMenu.value; voices = allVoices.filter(function (voice) { return langcode === "all" ? true : voice.lang.indexOf(langcode + "-") >= 0; }); createSpeakerMenu(voices); let t = blurbs[languageMenu.options[languageMenu.selectedIndex].text]; txtFld.value = t ? t : defaultBlurb; speakerMenu.selectedIndex = voiceIndex; } function createLanguageMenu() { let code = `<option selected value="all">Show All</option>`; let langnames = []; primaryLanguages.forEach(function(lobj,i) { langnames.push(langcodehash[lobj.substring(0,2)].name); }); langnames.sort(); langnames.forEach(function(lname,i) { let lcode = langhash[lname].code; code += `<option value=${lcode}>${lname}</option>`; }); languageMenu.innerHTML = code; } function selectLanguage() { filterVoices(); speakerMenu.selectedIndex = 0; }
In the utility functions section of the code toward the bottom, add the following code. This generic little utility will help you the next time you need to create a lookup table for an array of objects. In our case, we will use this to allow us to easily match a language code with its corresponding language name and vice versa.
function getLookupTable(objectsArray, propname) { return objectsArray.reduce((accumulator, currentValue) => (accumulator[currentValue[propname]] = currentValue, accumulator),{}); }
I added an array of text phrases, each of which is a translation of the English phrase, "I enjoy the traditional music of my native country." The language it’s displayed in will correspond to what’s selected in the language men.
Here we see the beauty of UTF-8 on full display. Above the getLanguagesTags() function, let’s add the code that generates all those translated blurbs. I only read Spanish, English, some Portuguese, and very little German, so I have to take on faith that Google Translate is providing accurate translations for the rest. If any of these is your native language, feel free to leave corrections in the comments.
function createBlurbs() { blurbs = { "Arabic" : "أنا أستمتع بالموسيقى التقليدية لبلدي الأم.", "Chinese" : "我喜歡我祖國的傳統音樂。", "Czech" : "Mám rád tradiční hudbu mé rodné země.", "Danish" : "Jeg nyder den traditionelle musik i mit hjemland.", "Dutch" : "Ik geniet van de traditionele muziek van mijn geboorteland.", "English" : "I enjoy the traditional music of my native country.", "Finnish" : "Nautin kotimaassani perinteistä musiikkia.", "French" : "J'apprécie la musique traditionnelle de mon pays d'origine.", "German" : "Ich genieße die traditionelle Musik meiner Heimat.", "Greek" : "Απολαμβάνω την παραδοσιακή μουσική της πατρίδας μου.", "Hebrew" : "אני נהנה מהמוסיקה המסורתית של מולדתי.", "Hindi" : "मैं अपने मूल देश के पारंपरिक संगीत का आनंद लेता हूं।", "Hungarian" : "Élvezem az én hazám hagyományos zenéjét.", "Indonesian" : "Saya menikmati musik tradisional negara asal saya.", "Italian" : "Mi piace la musica tradizionale del mio paese natale.", "Japanese" : "私は母国の伝統音楽を楽しんでいます。", "Korean" : "나는 내 조국의 전통 음악을 즐긴다.", "Norwegian Bokmal" : "Jeg liker den tradisjonelle musikken i mitt hjemland.", "Polish" : "Lubię tradycyjną muzykę mojego kraju.", "Portuguese" : "Eu gosto da música tradicional do meu país natal.", "Romanian" : "Îmi place muzica tradițională din țara mea natală.", "Russian" : "Мне нравится традиционная музыка моей родной страны.", "Slovak" : "Mám rád tradičnú hudbu svojej rodnej krajiny.", "Spanish" : "Disfruto de la música tradicional de mi país natal.", "Swedish" : "Jag njuter av traditionell musik i mitt hemland.", "Thai" : "ฉันเพลิดเพลินกับดนตรีดั้งเดิมของประเทศบ้านเกิดของฉัน", "Turkish" : "Ülkemdeki geleneksel müzikten zevk alıyorum." }; }
There’s one last thing: the numeric input for controlling the playback speed of the speech. Modify the talk() function to get the speech rate from the number input and we’re good to go!
Here’s the final product:
function talk() { ...// no changes except for the rateFld.value reference u.rate = Number(rateFld.value); speechSynthesis.speak(u); }
See the Pen Polyglot: Text-To-Speech in Multiple Languages by Steven Estrella (@sgestrella) on CodePen.
A Real World Application
My interest in this technology started many years ago in 1990 when I created a 26-lesson curriculum as part of my dissertation. It was delivered using my first programming language, HyperCard, on a Macintosh Plus which had a primitive text-to-speech feature. I used that feature to provide some feedback to the user while they progressed through the material. More recently, in 2018, I created a free progressive web app called Buenos Verbos that helps Spanish language students search and filter a database of 766 verbs. The chosen verb is then fully conjugated and the user can click the forms to hear them spoken. So perhaps web pages might like to talk and with some imagination you may find reasons to encourage them. The question is: what will you make your website say next?
The post Using the Web Speech API for Multilingual Translations appeared first on CSS-Tricks.
Using the Web Speech API for Multilingual Translations published first on https://deskbysnafu.tumblr.com/
0 notes