text:
Business-boosting delivery services becoming increasingly popular
Alan J. Liddle 1 | Oct 04, 2010
While delivery can be tough on some profit margins, operators are finding that offering the service can address both their appetite for sales and the consumer's hunger for convenience.
Long a key component of pizza operations around the country, delivery is being explored by a growing number of restaurateurs, from fast-casual players to frozen-yogurt chains, as a way of boosting volume and offering a service not available from their competition.
San Francisco bicycle messengers are finding they have to compete these days for street and sidewalk space with Johnny Rockets malt shop crewmembers, thanks to a franchisee there who is testing a delivery program.
For Matt Johnson, who owns three Johnny Rockets stores in San Francisco, it made sense to test free bicycle delivery for $10 minimum orders at his Chestnut Street location. He said it demonstrates a commitment to auto traffic reduction and "a convenient way for San Franciscans to enjoy their Johnny Rockets' favorites."
Johnson said that after two months, with little promotion, the store averages about five requests a day to have food delivered via the $500 custom-painted cruiser bicycle it keeps parked out front. That volume makes it feasible to handle deliveries using existing staff and a slightly tweaked insurance policy, he indicated.
"It adds to the whole ambience of the restaurant," Johnson said. "Instead of just having a delivery sign on any old car, we have a retro bike ridden by our guys in their [old-style] uniforms, and it all contributes to our retro image."
The Lake Forest, Calif.-based Johnny Rockets chain includes 295 full-service, diner-style restaurants offering burgers, specialty sandwiches, fries and shakes.
Depending on results at the Chestnut Street restaurant after some additional marketing is applied, Johnson said he might expand delivery service to his other stores.
Though many pizza chains have long offered delivery — and some sandwich chains heavily market their delivery capabilities, including 995-unit Jimmy John's of Champaign, Ill. — a growing number of chains, franchisees, small groups and independents are adding delivery as a way to build sales in a tough economic environment.
• More than 300 franchised Subway restaurants in the Washington, D.C., area, which have been testing delivery service for patrons paying fees and meeting minimum order requirements since fall 2009.
• The 98-unit Los Angeles-based Pinkberry frozen-yogurt chain, which is 16 months into a test of delivery that has expanded to 42 units in California, Colorado, New York City and Texas. Pinkberry officials said deliveries are handled by store employees using insulated bags. The service is free with a minimum $10 order in Colorado, New York and Texas, but carries a $2 charge in California for orders of less than $15.
• Wow Bao of Chicago, a fast-casual Asian-foods concept owned by Lettuce Entertain You Enterprises Inc., which last November began offering bicycle delivery at two of its three locations.
Some U.S.-based chains also are leveraging their experience overseas for development of delivery programs at home.
At last fall's Multi-Unit Foodservice Operators conference in Dallas, Julio Ramirez, Burger King Corp.'s executive vice president of global operations, said the 12,150-unit chain provided some form of delivery services in 12 countries.
"There are countries where they are not as litigious as in the United States, and there they do deliveries on motorcycles, by foot and other ways," Ramirez said, commenting on the possible legal liabilities attached to sending employees or agents with food to homes or businesses. He explained that with delivery service comes the need to map out logical radii around a restaurant within which delivery is practical and the need to develop new operational procedures.
"We're doing delivery in the States, and we're using the model we use in other countries," he said.
Geoff Alexander, vice president and managing partner of LEYE's Wow Bao group, said most of his bicycle delivery sales come during a two-hour period at lunch on weekdays. Customers within seven square blocks of participating restaurants who place orders of $10 or more may request that their food be delivered for a $2.75 fee. Delivery sales amount to about $500 per restaurant per week on average, he said.
Alexander said that Wow Bao uses an outside bicycle messenger service that charges $5 per delivery. He said that approach means that he does not have to hire new staff or reallocate existing-store employees, buy bicycles or worry about insurance, which is maintained by the outside service.
Wow Bao's use of an outside delivery service results in a lower profit margin per transaction, as the chain pays a $2.25 subsidy for each delivery. However, Alexander indicated that is acceptable to his group because of the much higher average ticket for such orders — $26 for delivered food versus $6.25 for dine-in or carryout patrons. That higher ticket means that even after deducting messenger service fees, Wow Bao's delivery transactions bring in more than three times the profit, dollarwise, of operators who handle their own delivery service.
Wow Bao is gaining exposure as well as sales through its delivery program, which features riders carrying bright red, backpack-style food bags that are covered with the chain's logo. A mini trailer can be fastened to a bicycle to carry large catering orders, as well.
"You can order online for pickup, delivery or shipping from both wowbao.com and from our Facebook page at facebook.com/hotasianbuns," Alexander said.
Wow Bao also uses Twitter to promote its delivery service, offering up such tweets as, "Rainy day outside, stay dry inside and order Wow Bao bicycle delivery."
"We're definitely feeling good about it," Alexander said of the delivery business. "It allows us to grow our customer base and business, without any additional labor or seats."
Contact Alan J. Liddle at [email protected]
.
TAGS: Technology Marketing Operations News

redpajama_set_name: RedPajamaCommonCrawl


The Hotel Victoria is a stylish and historic boutique hotel located in the heart of the city, close to attractions and to shopping.
Rooms are fresh and chic, with a monochrome decor splashed with delightful lime green and sleek hardwood flooring. Choose a standard or business room, or opt for a deluxe room for a little added space and a mini fridge. All rooms feature free wifi and ipod docking stations so you can bring your favourite music along with you.
Over Easy serves a delicious breakfast and lunch menu, boasting 'the best eggs benny in town', in its charming dining room.
The hotel is in a great central position, just a short walk to several different shopping districts, attractions and many excellent theatres. Take a stroll east to the historic St Lawrence Market, the city's biggest market, home to over 120 vendors selling a vast range of goods, or head north up Yonge Street for some of the city's best mainstream shopping, with the famous Eaton shopping centre, and Dundas Square, which hosts many live events and festivals.
It is a pleasant stroll west to the impressive CN Tower and its revolving restaurant and the popular Ripley's Aquarium, while a wander south brings you to the lively waterfront.


In this video workshop Erika Footman gives a detailed explanation of how singers can better connect with the lyrics of a song.
"Singers are historically storytellers," Erika explains in the beginning of this workshop. She feels like the art of storytelling is getting lost among young singers, because many of them don't know how to connect with the lyrics anymore. She shares her knowledge on how to better detect the feelings transported in a song and become a storyteller when singing.
We communicate through language and transport our feelings with words. This enables us to understand how someone feels and thereby connect with him or her. To be able to transport feelings through a song, a singer needs to connect with the lyrics he is about to sing.
Erika shows how this is done by using the technique herself on the song "You know I'm no good" by Amy Winehouse. By first going through the lyrics and then reading them out loud to herself, she paints a picture of the situations and finds out what the text is actually about. Thus, she finds out which emotions are implied. These emotions should later be transported to the audience by her singing and the feelings in her voice. Using inflections and other vocal techniques we learned about in earlier workshops can help.
Watch how to connect with lyrics and become a storyteller yourself!


"Good introduction and overview (without a deep-dive) of APIs of scikit-learn library with accompanying Jupyter notebook material. It's good for grasping the structure of the techniques available in data science process." 5 out 5 stars.
Machine Learning with scikit-learn LiveLessons is your guide to the scikit-learn library, which provides a wide range of algorithms in machine learning that are unified under a common and intuitive Python API. Most of the dozens of classes provided for various kinds of models share the large majority of the same calling interface. Quite often you can easily substitute one algorithm for another with very little or no change in your underlying code. This enables you to explore the problem space quickly and often to arrive at an optimal—or at least satisficing—approach to your problem domain or datasets.
The scikit-learn library is built on the foundations of the numeric Python stack. It uses NumPy for its fundamental data structures and optimized performance, and it plays well with pandas and matplotlib. It is free software under a BSD license. The great bulk of machine learning programming in Python is done with scikit-learn–at least outside the specialized domain of deep neural networks.
David Mertz has been involved with the Python community for 20 years, with data science, (under various previous names) and with machine learning since way back when it was more likely to be called "artificial intelligence." He was a director of the Python Software Foundation for six years and continues to serve on, or chair, a variety of PSF working groups.
He has also written quite a bit about Python: the column Charming Python for IBM developerWorks, for many years; Text Processing in Python (Addison-Wesley, 2003); and two short books for O'Reilly. He created the data science training program for Anaconda, Inc., and was a senior trainer for them.
Lesson 1: What Is Machine Learning?
The first lesson addresses many of the essential concepts in machine learning. The main tasks that can be accomplished with ML are addressed. It then turns to issues of dimensionality, of feature engineering and selection, and of feature/variable types. Finally, the lesson delves into concerns practical in working with machine learning libraries and systems.
At the end of this lesson you have a broad understanding of all the main concepts used in machine learning.
The second lesson covers preparation of a dataset for machine learning models. In the real world, data always arrives messy and flawed. Before you can get to applying machine learning techniques, it is almost always necessary to massage, filter, and generally to clean up your data.
Exploration and cleaning of datasets typically utilizes Pandas, which is a rich library for exactly those tasks. This lesson does most of its work using that tool. Pandas is not a requirement for scikit-learn per se, but they play very well together.
At the end of this lesson you have an initial sense of how to get a "feel" for your data and are able to think about likely problems and anomalies within novel datasets. After many years of practice as a working data scientist, you will be highly skilled at these same judgements.
One of the main techniques used within machine learning–specifically within what we call supervised machine learning–is classification. That is the subject matter of Lesson 3. As discussed in Lesson 1, classification is trying to match a collection of multiple features to a categorical target–that is, the prediction is that a newly observed item belongs to one of n known classes.
There are many algorithms for performing classification; a large number of them are available in scikit-learn. This lesson covers a number of different classifiers and some features of each are compared. This lesson provides a first exposure to the scikit-learn APIs, which are mostly similar across its numerous classes, both for classifiers and for other models and transformations.
At the end of this lesson you have a sense of the range of classifiers available and some context for choosing among them in your own datasets and for your own goals.
Within supervised machine learning, the two basic types of models are classifiers and regressors. Both have precedent in standard statistics, but machine learning techniques go beyond the "closed form" mathematical techniques that precede them. The lesson includes a number of regressors, starting from the linear regression family that is common in general statistics.
This lesson also introduces some of the sample datasets that are bundled with scikit-learn, and that can often be a useful starting point for exploring techniques and coding styles.
By the end of this lesson, you have an understanding of most of the regression models available in scikit-learn.
As well as supervised learning–i.e., classification and regression, which have been covered in prior lessons–there are various models of unsupervised learning as well. When we do not have any a priori idea about what the target of an algorithm is, an approach we can still take is to look at how complex multi-dimensional features cluster into distinct categories. This is very common to find in datasets.
This lesson provides an overview of a number of clustering algorithms and uses them to create synthetic classifications of several datasets. It gives you some hands-on experience with the minor differences in the scikit-learn API needed to work in an unsupervised rather than supervised domain. For clustering, it is especially useful to try to visualize or explore the classifications produced by models since they do not necessarily have obvious names for the classes. Such visualization is explored in this lesson.
Most of the models in scikit-learn–or indeed, in any other machine learning library–utilize what are called "hyperparameters" in the domain. This concept was explored in Lesson 1 but explored in more depth here.
When a model is trained, it gains configuration data, often called "parameters." These are the data that define what it means for a model to be trained on one dataset versus another and are attached to the model object. However, almost all algorithms in machine learning also utilize hyperparameters to control exactly what variation of the basic algorithm is used (or cut-offs assumed), constants that are utilized in underlying formulae, or other algorithmic variations. These hyperparameters are usually used in creating model instances and before any actual training is performed. In many cases, their values can dramatically change the effectiveness and success of a model.
It is often, even usually, difficult to judge in advance the best choice of hyperparameters. Therefore, performing what is called a "grid search" over the parametric space of hyperparameters is often desirable. Scikit-learn contains wrapper classes that both emulate the APIs of underlying models and provide easy access to the basic operation of a grid search.
Prior lessons approached choosing and training models using relatively naive feature sets drawn from the underlying datasets. However, when you need to work on problems with real-world complexity, often the features you are initially provided by a dataset are not powerful enough to achieve the model effectiveness you need.
Of course, some data simply does not contain the necessary intrinsic force. But most of the time it requires extra work to tease out the "features of the features" that are actually most useful for your purposes. These initial steps are called "feature engineering" and "feature selection." The former involves constructing synthetic features based on the raw features you are given by various combinations of scaling them, combining them, handling outliers, or transforming the representation of features. The latter, feature selection, involves reducing the number of features you utilize, often subsequent to multiplying that number in feature engineering steps, to select only those that are most predictive. Sometimes feature selection is needed simply to make training a model computationally tractable.
Prior lessons have illustrated a variety of techniques for preparing and transforming data and for selection of models and hyperparameters of models. Very often, when you have combined and refined these steps in a particular way relevant to your domain, you would like to be able to encapsulate those steps.
The scikit-learn abstraction and classes, called pipelines, enable this combination of steps while maintaining the same APIs that have now become familiar. There are a variety of components that you can combine using pipelines, but producing a combined object that follows the same API as those components is a very useful programming style, which this lesson covers.
Earlier lessons utilized the simple train_test_split() function to divide data that was used in training models. This function is perfectly sufficient for exploratory purposes, but at a final stage when you are interested in more rigorous validation of models in preparation for production, you probably want to consider more robust train/test split strategies.
This lesson covers the numerous classes provided by scikit-learn for robust train/test splits.


As a member of our client, you will be working on applications which enable thousands of employees to provide service to our customers on a daily basis.
You will use tools and technologies including Adobe Experience Manager, J2EE, JSP, Sling, JSTL/Servlet, OSGI, Oracle PL/SQL, HTML, Dynamic HTML, HTML5, Ajax, Jquery, and Bootstrap to build web-based solutions.
You enjoy working collaboratively in a fast-paced team environment to analyze and creatively solve complex problems. You want to transform the way we work on the inside to improve the experience we deliver on the outside.
Bachelor's degree in Computer Science, Information Systems.
Working knowledge of one or more of the following; J2EE, JSP, Sling, JSTL/Servlet, OSGI, Oracle PL/SQL, HTML, Dynamic HTML, HTML5, Ajax, Jquery, and Bootstrap.
Exposure to DevOps and CI/CD tools (Jenkins, Ansible, Jira, Maven, Fortify, SonarQube, Git, Stash).


text:
namespace atom {

// static
void RemoteCallbackFreer::BindTo(v8::Isolate* isolate,
                                 v8::Local<v8::Object> target,
                                 int object_id,
                                 content::WebContents* web_contents) {
  new RemoteCallbackFreer(isolate, target, object_id, web_contents);
}

RemoteCallbackFreer::RemoteCallbackFreer(v8::Isolate* isolate,
                                         v8::Local<v8::Object> target,
                                         int object_id,
                                         content::WebContents* web_contents)
    : ObjectLifeMonitor(isolate, target),
      content::WebContentsObserver(web_contents),
      object_id_(object_id) {
}

RemoteCallbackFreer::~RemoteCallbackFreer() {
}

void RemoteCallbackFreer::RunDestructor() {
  base::string16 channel =
      base::ASCIIToUTF16("ELECTRON_RENDERER_RELEASE_CALLBACK");
  base::ListValue args;
  args.AppendInteger(object_id_);
  Send(new AtomViewMsg_Message(routing_id(), channel, args));

  Observe(nullptr);
}

void RemoteCallbackFreer::RenderViewDeleted(content::RenderViewHost*) {
  delete this;
}

}  // namespace atom

redpajama_set_name: RedPajamaGithub


I ended up shooting a lot of video for the month of October. My vlog was split into 2 parts with 2 special extras. This part is for Berg, my pet bunny.
I know a lot of you YouTubers and my followers on social media love my bunny, Berg. I shot some video footage of him in September 2017, so I hope you enjoy watching him going about his bunny business.


text:
De rio-madeiramiersluiper (Epinecrophylla amazonica) is een zangvogel uit de familie Thamnophilidae.

Verspreiding en leefgebied
Deze soort komt voor in centraal Brazilië en noordelijk Bolivia, in het gebied ten westen van de Madeirarivier, een zijrivier van de Amazonerivier.

Thamnophilidae
Dier uit het Neotropisch gebied
IUCN-status niet bedreigd

redpajama_set_name: RedPajamaWikipedia


"I have been living in a condo in Downtown San Diego that is managed by High Tide for the past year. As someone who has moved around a decent amount while in college, as well as the past few years after graduating, I have had to deal with my fair share of property management companies - most of which have not been pleasant. Thankfully, my experience with High Tide has been the exact opposite.
"Having recently made the transition from being a homeowner to being a tenant I was worried about the prospect of having a difficult landlord to deal with. Instead, I was fortunate enough to find a property managed by High Tide. From the first time I spoke with Jay on the phone he has been professional, responsive, and very pleasant to work with. The condo I moved into was having some work done prior to the move and he kept me informed of the progress at all times and was polite and patient with my many questions and phone calls.
Everything they do from the lease signing to the move-in is very thorough and professional. Since moving in I have been impressed by how quickly they've responded to even the smallest maintenance detail or request. Jay and Seung are nice, friendly people who are a pleasure to work with.


38 weeks today! C'mon Baby! We are ready for you! Although my mom would prefer that you wait for her (she comes in 12 days), I definitely wouldn't mind if you decided to come a liiiiittle early. Hehe.
So many of my friends have been having early first babies lately. I'd be lying if I said I wasn't jealous. I'm super uncomfortable and it's getting harder to fight against that all too famous pregnancy waddle. But all the annoyances seem to diminish when I stand in front of our little baby's wardrobe and look at all the adorable clothes he'll soon be wearing! I can't wait!
Symptoms: Difficulty sleeping, frequent urination, lower back pain, Braxton Hicks.
How I'm feeling: I'm in a constant state of tiredness!
This entry was posted on Jan 16, 2015 and is filed under Pregnancy . You can follow any responses to this entry through the RSS 2.0 . You can leave a response .


text:
Having a tattoo of your employers' logo is just 'creepy'
Sacked New York Times editor Jill Abramson will struggle to shift the mark of her former employer
Mon, May 19, 2014, 01:00 Updated: Mon, May 19, 2014, 12:19
Lucy Kellaway
The New York Times publisher Arthur Sulzberger Jr, center, and Jill Abramson, right, who was sacked as editor of the New York Times last week, celebrate the four Pulitzers won by The Times in 2013. File photograph: Ruth Fremson/The New York Times
When you get fired, the most important thing is to put it swiftly behind you. That is going to be quite hard for Jill Abramson, who was sacked as editor of the New York Times last week but who has part of the newspaper's logo tattooed on her back.
To ink a curly black gothic "T" into your skin is the most tragically misplaced act of loyalty to an employer I've ever heard of. It is even less explicable than getting tattooed with the name of a current love. At least then a) there is a chance that the object of your affections will be charmed rather than horrified and b) it is at least possible that the two might stay together forever.
By contrast, to have your employer's name branded indelibly on to your skin makes no sense at all. Far from being pleased, your boss is more likely to think it creepy and weird. Jobs are not for life any more. All jobs end; often they end badly.
The only other case I can find in which employees have had the company's logo emblazoned on their bodies is at Rapid Realty, an attention-seeking New York real estate firm.
More than 70 staff have now become what it calls "tattoo brand ambassadors" and have had a pair of Rs inked on arms and heads, while one beefy looking chap has a vast picture of the company's store front tattooed across one half of his bulging six-pack.
"It's no big secret. Our agents love where they work . . . and they're not afraid to show it," says the company. Nor is it a secret that they were offered a pay rise in return for disfiguring themselves, which might also have shaped their decision.
Outlasts the job
Maybe it seemed a good deal at the time, but one assumes it will seem less so once they realise that a tattoo always outlasts a job in real estate – or in journalism.
Yet just before she was fired, Ms Abramson gave an interview in which she made the idea of getting permanently marked with your employer's logo sound a little less crazy. "It's become for me a strange form of personal hieroglyphics," she explained. "I think they eventually, when I finish doing them, will tell the story of me, of where I lived, and what things have been important to me." So far, she has four, of which two are for the "institutions that I revere, that have shaped me". A curly "T" for the Times, and a crimson "H" for Harvard.
Suddenly one sees a whole new use for tattoos. As the NYT's first female editor, Ms Abramson had always been something of a trendsetter. But this new fashion could be far, far bigger. With the H and the T she has made herself a global leader in wearable CVs.
The idea would be to mark your body with the names you most wanted to associate yourself with. The tattoos would be a more painful and permanent version of the badges that boy scouts have been sewing on to their sleeves for over a hundred years. Whereas the boy's badges say "insect study" and "archery" and "fire safety", the grown-up equivalent would say Cambridge, Google and Goldman Sachs.
"To have your employer's name branded indelibly on to your skin makes no sense at all. Far from being pleased, your boss is more likely to think it creepy and weird.
The only thing Ms Abramson did wrong was to have them on her back, where they could only be seen if she pitched up to work in a backless dress – generally not a great look for working women of a certain age. Instead, she ought to have had her wearable CV tattooed down her arm or hand – or even on her neck or forehead. Then every time she wanted to impress, those institutions that shaped her would be proudly on public view.
Visually disgusting
The idea of the wearable CV strikes me as no more visually disgusting than tattoos of butterflies or skulls or barbed wire – and a lot more useful.
It would have the advantage of freeing people from having to drop into conversations tiresome boasts about what university they went to, as everyone would be able to see that for themselves.
It would also mean that if at a party you spotted someone heavily inked with establishment names you could make a point of talking to them or of avoiding them – according to your preferences.
If Ms Abramson has showed us one excellent use for tattoos in professional life, a loutish Manchester United football fan has recently demonstrated another. While the former editor's tattoos are a display of achievement, his represent a darker side of office politics.
Back in February, disgusted at his team's performance, the fan had "Moyes out!" inked across a hairy buttock.
When the luckless David Moyes was fired as manager last month, the fan went back to the parlour and had the words "job complete" added underneath. The lesson: when arse-kissing is not called for, arse-dissing might work instead.
– (Copyright The Financial Times Limited 2014)
Jill Abramson
Goldman Sachs Group
Rapid Realty
10 Donohoe says extra €200m required to fund National Broadband Plan
Search executive
jobs on irishtimes.com


text:
Bluebulb Projects presents:
Step 1: What kind of measurement do you want to compare?
Click an icon above to choose a measurement type for comparison. This space will display an explanation as you move your mouse over the icons.
Enter a measurement to see comparisons
Equivalents in other units Click here to hide this
milimeters
barleycorns
fathoms
leas
ells
parsecs
smoots
spans
cubits
Rollover a unit to see the conversion
How long is 4.20 shaftments?
Closest first | Highest first | Lowest first
It's about one-two-hundred-fiftieth as tall as The Washington Monument.
In other words, 4.20 shaftments is 0.003781 times the height of The Washington Monument, and the height of The Washington Monument is 264.480 times that amount.
(Washington, D.C.)
The Washington Monument measures 1,110.80 shaftments tall, with some discrepancy due to the fact that the Monument's base is slightly below the surrounding ground. Interrupted in its construction by the American Civil War, it was almost 36 years between groundbreaking and the completion of construction.
Measurement source | Link to this result | How do I report a mistake on this? | How do I cite this?
It's about one-two-hundred-fiftieth as tall as St. Paul's Cathedral.
In other words, 4.20 shaftments is 0.00368 times the height of St. Paul's Cathedral, and the height of St. Paul's Cathedral is 272 times that amount.
(London, England, United Kingdom)
St. Paul's Cathedral measures 1,140 shaftments to its peak. The southwest tower of the Cathedral contains the bell known as "Great Paul," which is the largest bell in Great Britain at 15,000 kg (16.5 tons), outweighing the more iconic Big Ben bell by about 3,000 kg (3 tons).
It's about one-three-hundredth as tall as The Space Needle.
In other words, 4.20 shaftments is 0.00348 times the height of The Space Needle, and the height of The Space Needle is 287 times that amount.
(Seattle, Washington) (to aircraft warning beacon at peak)
Built for a 1962 World's Fair, the Space Needle stands 1,210 shaftments tall. With a track-and-wheel design inspired by railroad mechanics and a precisely-configured balance, the restaurant near the top of the space needle requires just a 1.5 hp motor to rotate at speeds of about 0.053 kph (0.033 mph).
It's about one-three-hundred-fiftieth as tall as The Golden Gate Bridge.
In other words, 4.20 shaftments is 0.00282 times the height of The Golden Gate Bridge, and the height of The Golden Gate Bridge is 355 times that amount.
(San Francisco, California and Marin County, California) (height above water)
The height of each tower of Golden Gate Bridge is 1,490 shaftments above the surface of the San Francisco Bay. One of the key designers of the bridge, Charles Ellis, had no engineering degree when he began working on the project, but would later go on to write what became a standard textbook on structural engineering, and would ultimately be forced to complete his calculations on the bridge by working without pay for five months.
It's about 400 times as long as a Strand of Spaghetti (thickness).
In other words, 4.20 shaftments is 380 times the length of a Strand of Spaghetti (thickness), and the length of a Strand of Spaghetti (thickness) is 0.0026 times that amount.
(average; restaurant and supermarket applications) (based on FMA Omcan Italian Made TR50 Counter Top Pasta Machine Extruder 13317)
An average strand of restaurant-grade spaghetti measures 0.011 shaftments in thickness. In 2010, a California Buca di Beppo set a world record by preparing a 13,780-lb bowl of spaghetti, served in a swimming pool.
It's about one-four-hundred-fiftieth as long as The QE2.
In other words, 4.20 shaftments is 0.00218 times the length of The QE2, and the length of The QE2 is 459 times that amount.
(a.k.a. RMS Queen Elizabeth 2) The QE2 has a total length of 1,930 shaftments. During its voyaging lifetime from 1969 through 2008, it travelled more than 63,000,000,000 shaftments, the furthest cumulative distance by any ship in modern history.
It's about one-five-hundredth as tall as The Eiffel Tower.
In other words, 4.20 shaftments is 0.00198 times the height of The Eiffel Tower, and the height of The Eiffel Tower is 505 times that amount.
(a.k.a. La Tour Eiffel) (Paris, France) (to flagpole peak)
The Eiffel Tower stands 2,130 shaftments tall, including its flagpole. The Tower is the largest structure in Paris as most other buildings are governed by a zoning restriction limiting them to a height of 243 shaftments or less.
Results Pages:
< 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 >
Use The Measure of Things Tool | FAQ | About Us | The Measure of Things API | Contact | Privacy Policy | Use The Count of Things Tool
Design and Text Copyright © 2020. All rights reserved.


text:
Jake Arnott
Jake Arnott was born in 1961, and lives in London. He is the author of THE LONG FIRM, published by Sceptre in 1999 and subsequently made into an acclaimed BBC TV series. His second novel, HE KILLS COPPERS, was also made into a series by Channel 4. He has since published the novels TRUECRIME, JOHNNY COME HOME, THE DEVIL'S PAINTBRUSH and THE HOUSE OF RUMOUR.
The Long Firm Trilogy
'Whenever Jake Arnott's got a new book out, I drop everything knowing that the next couple of hours are going to be pure gangland bliss.'…
The Fatal Tree
'A work of dazzling imagination and linguistic inventiveness' Observer Newgate Gaol, 1726. An anonymous writer sets down the words of Edgworth Bess as she confides…
The House of Rumour
Larry Zagorski spins wild tales of fantasy worlds for pulp magazines. But as the Second World War hangs in the balance, the lines between imagination…
The Long Firm
London. The 1960s. The capital is swinging, but underneath the boomtown there's a dark underbelly. Meet Harry Starks: club owner, racketeer, porn king, sociology graduate…
He Kills Coppers
August 1966, the long hot summer of World Cup euphoria is suddenly shattered by a brutal crime that shocks a nation seemingly at ease with…
It's thirty years since Harry Starks and his gang kept the underworld of Soho under control but the consequences of their brutal reign are still…
The Devil's Paintbrush
'A consummate performance...virtuoso' Guardian A fascinating, unusual and seductive historical novel by the bestselling author of The Long Firm. In a Parisian restaurant, Aleister Crowley,…
Johnny Come Home
'Hypnotic, feverish and altogether wonderful' (Guardian) - Jake Arnott's acclaimed successor to the bestselling LONG FIRM trilogy It's 1972 and as the dreams of the…
Ranging from the Swinging Sixties to the Raving Nineties and with a cast that includes the machiavellian gangster Harry Starks, politicians, bent coppers, actresses and…


Look trendy and stay warm with wide range of Gildan sweatshirts available at ApparalnBags.com. Gildan manufactures sweatshirts in different style like Gildan hooded sweatshirts, Gildan crewneck sweatshirts and Gildan regular style sweatshirts. These numerous sweatshirts styles enable you to mix and match it with your different clothing line. Rather you need a sweatshirt for casual or sport wear; Gildan sweatshirts are design to meet both purposes. At ApparelnBags.com we promise to offer you the competitive prices on all Gildan sweatshirts variety with fastest delivery in USA and other different regions of world. In addition to this, ApparelnBags.com also offers a massive discount prices on bulk buying. For more information, please feel free to contact us.


text:
(function(tinymce) {
	// Shorten these names
	var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend,
		each = tinymce.each, isGecko = tinymce.isGecko,
		isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, is = tinymce.is,
		ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager,
		explode = tinymce.explode;

	/**
	 * This class contains the core logic for a TinyMCE editor.
	 *
	 * @class tinymce.Editor
	 * @example
	 * // Add a class to all paragraphs in the editor.
	 * tinyMCE.activeEditor.dom.addClass(tinyMCE.activeEditor.dom.select('p'), 'someclass');
	 *
	 * // Gets the current editors selection as text
	 * tinyMCE.activeEditor.selection.getContent({format : 'text'});
	 *
	 * // Creates a new editor instance
	 * var ed = new tinymce.Editor('textareaid', {
	 *     some_setting : 1
	 * });
	 *
	 * // Select each item the user clicks on
	 * ed.onClick.add(function(ed, e) {
	 *     ed.selection.select(e.target);
	 * });
	 *
	 * ed.render();
	 */
	tinymce.create('tinymce.Editor', {
		/**
		 * Constructs a editor instance by id.
		 *
		 * @constructor
		 * @method Editor
		 * @param {String} id Unique id for the editor.
		 * @param {Object} settings Optional settings string for the editor.
		 * @author Moxiecode
		 */
		Editor : function(id, settings) {
			var self = this, TRUE = true;

			/**
			 * Name/value collection with editor settings.
			 *
			 * @property settings
			 * @type Object
			 * @example
			 * // Get the value of the theme setting
			 * tinyMCE.activeEditor.windowManager.alert("You are using the " + tinyMCE.activeEditor.settings.theme + " theme");
			 */
			self.settings = settings = extend({
				id : id,
				language : 'en',
				theme : 'advanced',
				skin : 'default',
				delta_width : 0,
				delta_height : 0,
				popup_css : '',
				plugins : '',
				document_base_url : tinymce.documentBaseURL,
				add_form_submit_trigger : TRUE,
				submit_patch : TRUE,
				add_unload_trigger : TRUE,
				convert_urls : TRUE,
				relative_urls : TRUE,
				remove_script_host : TRUE,
				table_inline_editing : false,
				object_resizing : TRUE,
				accessibility_focus : TRUE,
				doctype : tinymce.isIE6 ? '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">' : '<!DOCTYPE>', // Use old doctype on IE 6 to avoid horizontal scroll
				visual : TRUE,
				font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
				font_size_legacy_values : 'xx-small,small,medium,large,x-large,xx-large,300%', // See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size
				apply_source_formatting : TRUE,
				directionality : 'ltr',
				forced_root_block : 'p',
				hidden_input : TRUE,
				padd_empty_editor : TRUE,
				render_ui : TRUE,
				indentation : '30px',
				fix_table_elements : TRUE,
				inline_styles : TRUE,
				convert_fonts_to_spans : TRUE,
				indent : 'simple',
				indent_before : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist',
				indent_after : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist',
				validate : TRUE,
				entity_encoding : 'named',
				url_converter : self.convertURL,
				url_converter_scope : self,
				ie7_compat : TRUE
			}, settings);

			/**
			 * Editor instance id, normally the same as the div/textarea that was replaced.
			 *
			 * @property id
			 * @type String
			 */
			self.id = self.editorId = id;

			/**
			 * State to force the editor to return false on a isDirty call.
			 *
			 * @property isNotDirty
			 * @type Boolean
			 * @example
			 * function ajaxSave() {
			 *     var ed = tinyMCE.get('elm1');
			 *
			 *     // Save contents using some XHR call
			 *     alert(ed.getContent());
			 *
			 *     ed.isNotDirty = 1; // Force not dirty state
			 * }
			 */
			self.isNotDirty = false;

			/**
			 * Name/Value object containting plugin instances.
			 *
			 * @property plugins
			 * @type Object
			 * @example
			 * // Execute a method inside a plugin directly
			 * tinyMCE.activeEditor.plugins.someplugin.someMethod();
			 */
			self.plugins = {};

			/**
			 * URI object to document configured for the TinyMCE instance.
			 *
			 * @property documentBaseURI
			 * @type tinymce.util.URI
			 * @example
			 * // Get relative URL from the location of document_base_url
			 * tinyMCE.activeEditor.documentBaseURI.toRelative('/somedir/somefile.htm');
			 *
			 * // Get absolute URL from the location of document_base_url
			 * tinyMCE.activeEditor.documentBaseURI.toAbsolute('somefile.htm');
			 */
			self.documentBaseURI = new tinymce.util.URI(settings.document_base_url || tinymce.documentBaseURL, {
				base_uri : tinyMCE.baseURI
			});

			/**
			 * URI object to current document that holds the TinyMCE editor instance.
			 *
			 * @property baseURI
			 * @type tinymce.util.URI
			 * @example
			 * // Get relative URL from the location of the API
			 * tinyMCE.activeEditor.baseURI.toRelative('/somedir/somefile.htm');
			 *
			 * // Get absolute URL from the location of the API
			 * tinyMCE.activeEditor.baseURI.toAbsolute('somefile.htm');
			 */
			self.baseURI = tinymce.baseURI;

			/**
			 * Array with CSS files to load into the iframe.
			 *
			 * @property contentCSS
			 * @type Array
			 */
			self.contentCSS = [];

			/**
			 * Array of CSS styles to add to head of document when the editor loads.
			 *
			 * @property contentStyles
			 * @type Array
			 */
			self.contentStyles = [];

			// Creates all events like onClick, onSetContent etc see Editor.Events.js for the actual logic
			self.setupEvents();

			// Internal command handler objects
			self.execCommands = {};
			self.queryStateCommands = {};
			self.queryValueCommands = {};

			// Call setup
			self.execCallback('setup', self);
		},

		/**
		 * Renderes the editor/adds it to the page.
		 *
		 * @method render
		 */
		render : function(nst) {
			var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;

			// Page is not loaded yet, wait for it
			if (!Event.domLoaded) {
				Event.add(window, 'ready', function() {
					t.render();
				});
				return;
			}

			tinyMCE.settings = s;

			// Element not found, then skip initialization
			if (!t.getElement())
				return;

			// Is a iPad/iPhone and not on iOS5, then skip initialization. We need to sniff
			// here since the browser says it has contentEditable support but there is no visible caret.
			if (tinymce.isIDevice && !tinymce.isIOS5)
				return;

			// Add hidden input for non input elements inside form elements
			if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))
				DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);

			// Hide target element early to prevent content flashing
			if (!s.content_editable) {
				t.orgVisibility = t.getElement().style.visibility;
				t.getElement().style.visibility = 'hidden';
			}

			/**
			 * Window manager reference, use this to open new windows and dialogs.
			 *
			 * @property windowManager
			 * @type tinymce.WindowManager
			 * @example
			 * // Shows an alert message
			 * tinyMCE.activeEditor.windowManager.alert('Hello world!');
			 *
			 * // Opens a new dialog with the file.htm file and the size 320x240
			 * // It also adds a custom parameter this can be retrieved by using tinyMCEPopup.getWindowArg inside the dialog.
			 * tinyMCE.activeEditor.windowManager.open({
			 *    url : 'file.htm',
			 *    width : 320,
			 *    height : 240
			 * }, {
			 *    custom_param : 1
			 * });
			 */
			if (tinymce.WindowManager)
				t.windowManager = new tinymce.WindowManager(t);

			if (s.encoding == 'xml') {
				t.onGetContent.add(function(ed, o) {
					if (o.save)
						o.content = DOM.encode(o.content);
				});
			}

			if (s.add_form_submit_trigger) {
				t.onSubmit.addToTop(function() {
					if (t.initialized) {
						t.save();
						t.isNotDirty = 1;
					}
				});
			}

			if (s.add_unload_trigger) {
				t._beforeUnload = tinyMCE.onBeforeUnload.add(function() {
					if (t.initialized && !t.destroyed && !t.isHidden())
						t.save({format : 'raw', no_events : true});
				});
			}

			tinymce.addUnload(t.destroy, t);

			if (s.submit_patch) {
				t.onBeforeRenderUI.add(function() {
					var n = t.getElement().form;

					if (!n)
						return;

					// Already patched
					if (n._mceOldSubmit)
						return;

					// Check page uses id="submit" or name="submit" for it's submit button
					if (!n.submit.nodeType && !n.submit.length) {
						t.formElement = n;
						n._mceOldSubmit = n.submit;
						n.submit = function() {
							// Save all instances
							tinymce.triggerSave();
							t.isNotDirty = 1;

							return t.formElement._mceOldSubmit(t.formElement);
						};
					}

					n = null;
				});
			}

			// Load scripts
			function loadScripts() {
				if (s.language && s.language_load !== false)
					sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');

				if (s.theme && typeof s.theme != "function" && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])
					ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');

				each(explode(s.plugins), function(p) {
					if (p &&!PluginManager.urls[p]) {
						if (p.charAt(0) == '-') {
							p = p.substr(1, p.length);
							var dependencies = PluginManager.dependencies(p);
							each(dependencies, function(dep) {
								var defaultSettings = {prefix:'plugins/', resource: dep, suffix:'/editor_plugin' + tinymce.suffix + '.js'};
								dep = PluginManager.createUrl(defaultSettings, dep);
								PluginManager.load(dep.resource, dep);
							});
						} else {
							// Skip safari plugin, since it is removed as of 3.3b1
							if (p == 'safari') {
								return;
							}
							PluginManager.load(p, {prefix:'plugins/', resource: p, suffix:'/editor_plugin' + tinymce.suffix + '.js'});
						}
					}
				});

				// Init when que is loaded
				sl.loadQueue(function() {
					if (!t.removed)
						t.init();
				});
			};

			loadScripts();
		},

		/**
		 * Initializes the editor this will be called automatically when
		 * all plugins/themes and language packs are loaded by the rendered method.
		 * This method will setup the iframe and create the theme and plugin instances.
		 *
		 * @method init
		 */
		init : function() {
			var n, t = this, s = t.settings, w, h, mh, e = t.getElement(), o, ti, u, bi, bc, re, i, initializedPlugins = [];

			tinymce.add(t);

			s.aria_label = s.aria_label || DOM.getAttrib(e, 'aria-label', t.getLang('aria.rich_text_area'));

			/**
			 * Reference to the theme instance that was used to generate the UI.
			 *
			 * @property theme
			 * @type tinymce.Theme
			 * @example
			 * // Executes a method on the theme directly
			 * tinyMCE.activeEditor.theme.someMethod();
			 */
			if (s.theme) {
				if (typeof s.theme != "function") {
					s.theme = s.theme.replace(/-/, '');
					o = ThemeManager.get(s.theme);
					t.theme = new o();

					if (t.theme.init)
						t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));
				} else {
					t.theme = s.theme;
				}
			}

			function initPlugin(p) {
				var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/$/, ''), po;
				if (c && tinymce.inArray(initializedPlugins,p) === -1) {
					each(PluginManager.dependencies(p), function(dep){
						initPlugin(dep);
					});
					po = new c(t, u);

					t.plugins[p] = po;

					if (po.init) {
						po.init(t, u);
						initializedPlugins.push(p);
					}
				}
			}

			// Create all plugins
			each(explode(s.plugins.replace(/\-/g, '')), initPlugin);

			// Setup popup CSS path(s)
			if (s.popup_css !== false) {
				if (s.popup_css)
					s.popup_css = t.documentBaseURI.toAbsolute(s.popup_css);
				else
					s.popup_css = t.baseURI.toAbsolute("themes/" + s.theme + "/skins/" + s.skin + "/dialog.css");
			}

			if (s.popup_css_add)
				s.popup_css += ',' + t.documentBaseURI.toAbsolute(s.popup_css_add);

			/**
			 * Control manager instance for the editor. Will enables you to create new UI elements and change their states etc.
			 *
			 * @property controlManager
			 * @type tinymce.ControlManager
			 * @example
			 * // Disables the bold button
			 * tinyMCE.activeEditor.controlManager.setDisabled('bold', true);
			 */
			t.controlManager = new tinymce.ControlManager(t);

			// Enables users to override the control factory
			t.onBeforeRenderUI.dispatch(t, t.controlManager);

			// Measure box
			if (s.render_ui && t.theme) {
				t.orgDisplay = e.style.display;

				if (typeof s.theme != "function") {
					w = s.width || e.style.width || e.offsetWidth;
					h = s.height || e.style.height || e.offsetHeight;
					mh = s.min_height || 100;
					re = /^[0-9\.]+(|px)$/i;

					if (re.test('' + w))
						w = Math.max(parseInt(w, 10) + (o.deltaWidth || 0), 100);

					if (re.test('' + h))
						h = Math.max(parseInt(h, 10) + (o.deltaHeight || 0), mh);

					// Render UI
					o = t.theme.renderUI({
						targetNode : e,
						width : w,
						height : h,
						deltaWidth : s.delta_width,
						deltaHeight : s.delta_height
					});

					// Resize editor
					DOM.setStyles(o.sizeContainer || o.editorContainer, {
						width : w,
						height : h
					});

					h = (o.iframeHeight || h) + (typeof(h) == 'number' ? (o.deltaHeight || 0) : '');
					if (h < mh)
						h = mh;
				} else {
					o = s.theme(t, e);

					// Convert element type to id:s
					if (o.editorContainer.nodeType) {
						o.editorContainer = o.editorContainer.id = o.editorContainer.id || t.id + "_parent";
					}

					// Convert element type to id:s
					if (o.iframeContainer.nodeType) {
						o.iframeContainer = o.iframeContainer.id = o.iframeContainer.id || t.id + "_iframecontainer";
					}

					// Use specified iframe height or the targets offsetHeight
					h = o.iframeHeight || e.offsetHeight;

					// Store away the selection when it's changed to it can be restored later with a editor.focus() call
					if (isIE) {
						t.onInit.add(function(ed) {
							ed.dom.bind(ed.getBody(), 'beforedeactivate keydown', function() {
								ed.lastIERng = ed.selection.getRng();
							});
						});
					}
				}

				t.editorContainer = o.editorContainer;
			}

			// Load specified content CSS last
			if (s.content_css) {
				each(explode(s.content_css), function(u) {
					t.contentCSS.push(t.documentBaseURI.toAbsolute(u));
				});
			}

			// Load specified content CSS last
			if (s.content_style) {
				t.contentStyles.push(s.content_style);
			}

			// Content editable mode ends here
			if (s.content_editable) {
				e = n = o = null; // Fix IE leak
				return t.initContentBody();
			}

			// User specified a document.domain value
			if (document.domain && location.hostname != document.domain)
				tinymce.relaxedDomain = document.domain;

			t.iframeHTML = s.doctype + '';

			// We only need to override paths if we have to
			// IE has a bug where it remove site absolute urls to relative ones if this is specified
			if (s.document_base_url != tinymce.documentBaseURL)
				t.iframeHTML += '<base href="' + t.documentBaseURI.getURI() + '" />';

			// IE8 doesn't support carets behind images setting ie7_compat would force IE8+ to run in IE7 compat mode.
			if (tinymce.isIE8) {
				if (s.ie7_compat)
					t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=7" />';
				else
					t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=edge" />';
			}

			t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';

			// Load the CSS by injecting them into the HTML this will reduce "flicker"
			for (i = 0; i < t.contentCSS.length; i++) {
				t.iframeHTML += '<link type="text/css" rel="stylesheet" href="' + t.contentCSS[i] + '" />';
			}

			t.contentCSS = [];

			bi = s.body_id || 'tinymce';
			if (bi.indexOf('=') != -1) {
				bi = t.getParam('body_id', '', 'hash');
				bi = bi[t.id] || bi;
			}

			bc = s.body_class || '';
			if (bc.indexOf('=') != -1) {
				bc = t.getParam('body_class', '', 'hash');
				bc = bc[t.id] || '';
			}

			t.iframeHTML += '
';

			// Domain relaxing enabled, then set document domain
			if (tinymce.relaxedDomain && (isIE || (tinymce.isOpera && parseFloat(opera.version()) < 11))) {
				// We need to write the contents here in IE since multiple writes messes up refresh button and back button
				u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinyMCE.get("' + t.id + '");document.write(ed.iframeHTML);document.close();ed.initContentBody();})()';
			}

			// Create iframe
			// TODO: ACC add the appropriate description on this.
			n = DOM.add(o.iframeContainer, 'iframe', {
				id : t.id + "_ifr",
				src : u || 'javascript:""', // Workaround for HTTPS warning in IE6/7
				frameBorder : '0',
				allowTransparency : "true",
				title : s.aria_label,
				style : {
					width : '100%',
					height : h,
					display : 'block' // Important for Gecko to render the iframe correctly
				}
			});

			t.contentAreaContainer = o.iframeContainer;

			if (o.editorContainer) {
				DOM.get(o.editorContainer).style.display = t.orgDisplay;
			}

			// Restore visibility on target element
			e.style.visibility = t.orgVisibility;

			DOM.get(t.id).style.display = 'none';
			DOM.setAttrib(t.id, 'aria-hidden', true);

			if (!tinymce.relaxedDomain || !u)
				t.initContentBody();

			e = n = o = null; // Cleanup
		},

		/**
		 * This method get called by the init method ones the iframe is loaded.
		 * It will fill the iframe with contents, setups DOM and selection objects for the iframe.
		 * This method should not be called directly.
		 *
		 * @method initContentBody
		 */
		initContentBody : function() {
			var self = this, settings = self.settings, targetElm = DOM.get(self.id), doc = self.getDoc(), html, body, contentCssText;

			// Setup iframe body
			if ((!isIE || !tinymce.relaxedDomain) && !settings.content_editable) {
				doc.open();
				doc.write(self.iframeHTML);
				doc.close();

				if (tinymce.relaxedDomain)
					doc.domain = tinymce.relaxedDomain;
			}

			if (settings.content_editable) {
				DOM.addClass(targetElm, 'mceContentBody');
				self.contentDocument = doc = settings.content_document || document;
				self.contentWindow = settings.content_window || window;
				self.bodyElement = targetElm;

				// Prevent leak in IE
				settings.content_document = settings.content_window = null;
			}

			// It will not steal focus while setting contentEditable
			body = self.getBody();
			body.disabled = true;

			if (!settings.readonly)
				body.contentEditable = self.getParam('content_editable_state', true);

			body.disabled = false;

			/**
			 * Schema instance, enables you to validate elements and it's children.
			 *
			 * @property schema
			 * @type tinymce.html.Schema
			 */
			self.schema = new tinymce.html.Schema(settings);

			/**
			 * DOM instance for the editor.
			 *
			 * @property dom
			 * @type tinymce.dom.DOMUtils
			 * @example
			 * // Adds a class to all paragraphs within the editor
			 * tinyMCE.activeEditor.dom.addClass(tinyMCE.activeEditor.dom.select('p'), 'someclass');
			 */
			self.dom = new tinymce.dom.DOMUtils(doc, {
				keep_values : true,
				url_converter : self.convertURL,
				url_converter_scope : self,
				hex_colors : settings.force_hex_style_colors,
				class_filter : settings.class_filter,
				update_styles : true,
				root_element : settings.content_editable ? self.id : null,
				schema : self.schema
			});

			/**
			 * HTML parser will be used when contents is inserted into the editor.
			 *
			 * @property parser
			 * @type tinymce.html.DomParser
			 */
			self.parser = new tinymce.html.DomParser(settings, self.schema);

			// Convert src and href into data-mce-src, data-mce-href and data-mce-style
			self.parser.addAttributeFilter('src,href,style', function(nodes, name) {
				var i = nodes.length, node, dom = self.dom, value, internalName;

				while (i--) {
					node = nodes[i];
					value = node.attr(name);
					internalName = 'data-mce-' + name;

					// Add internal attribute if we need to we don't on a refresh of the document
					if (!node.attributes.map[internalName]) {
						if (name === "style")
							node.attr(internalName, dom.serializeStyle(dom.parseStyle(value), node.name));
						else
							node.attr(internalName, self.convertURL(value, name, node.name));
					}
				}
			});

			// Keep scripts from executing
			self.parser.addNodeFilter('script', function(nodes, name) {
				var i = nodes.length, node;

				while (i--) {
					node = nodes[i];
					node.attr('type', 'mce-' + (node.attr('type') || 'text/javascript'));
				}
			});

			self.parser.addNodeFilter('#cdata', function(nodes, name) {
				var i = nodes.length, node;

				while (i--) {
					node = nodes[i];
					node.type = 8;
					node.name = '#comment';
					node.value = '[CDATA[' + node.value + ']]';
				}
			});

			self.parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function(nodes, name) {
				var i = nodes.length, node, nonEmptyElements = self.schema.getNonEmptyElements();

				while (i--) {
					node = nodes[i];

					if (node.isEmpty(nonEmptyElements))
						node.empty().append(new tinymce.html.Node('br', 1)).shortEnded = true;
				}
			});

			/**
			 * DOM serializer for the editor. Will be used when contents is extracted from the editor.
			 *
			 * @property serializer
			 * @type tinymce.dom.Serializer
			 * @example
			 * // Serializes the first paragraph in the editor into a string
			 * tinyMCE.activeEditor.serializer.serialize(tinyMCE.activeEditor.dom.select('p')[0]);
			 */
			self.serializer = new tinymce.dom.Serializer(settings, self.dom, self.schema);

			/**
			 * Selection instance for the editor.
			 *
			 * @property selection
			 * @type tinymce.dom.Selection
			 * @example
			 * // Sets some contents to the current selection in the editor
			 * tinyMCE.activeEditor.selection.setContent('Some contents');
			 *
			 * // Gets the current selection
			 * alert(tinyMCE.activeEditor.selection.getContent());
			 *
			 * // Selects the first paragraph found
			 * tinyMCE.activeEditor.selection.select(tinyMCE.activeEditor.dom.select('p')[0]);
			 */
			self.selection = new tinymce.dom.Selection(self.dom, self.getWin(), self.serializer, self);

			/**
			 * Formatter instance.
			 *
			 * @property formatter
			 * @type tinymce.Formatter
			 */
			self.formatter = new tinymce.Formatter(self);

			/**
			 * Undo manager instance, responsible for handling undo levels.
			 *
			 * @property undoManager
			 * @type tinymce.UndoManager
			 * @example
			 * // Undoes the last modification to the editor
			 * tinyMCE.activeEditor.undoManager.undo();
			 */
			self.undoManager = new tinymce.UndoManager(self);

			self.forceBlocks = new tinymce.ForceBlocks(self);
			self.enterKey = new tinymce.EnterKey(self);
			self.editorCommands = new tinymce.EditorCommands(self);

			self.onExecCommand.add(function(editor, command) {
				// Don't refresh the select lists until caret move
				if (!/^(FontName|FontSize)$/.test(command))
					self.nodeChanged();
			});

			// Pass through
			self.serializer.onPreProcess.add(function(se, o) {
				return self.onPreProcess.dispatch(self, o, se);
			});

			self.serializer.onPostProcess.add(function(se, o) {
				return self.onPostProcess.dispatch(self, o, se);
			});

			self.onPreInit.dispatch(self);

			if (!settings.browser_spellcheck && !settings.gecko_spellcheck)
				doc.body.spellcheck = false;

			if (!settings.readonly) {
				self.bindNativeEvents();
			}

			self.controlManager.onPostRender.dispatch(self, self.controlManager);
			self.onPostRender.dispatch(self);

			self.quirks = tinymce.util.Quirks(self);

			if (settings.directionality)
				body.dir = settings.directionality;

			if (settings.nowrap)
				body.style.whiteSpace = "nowrap";

			if (settings.protect) {
				self.onBeforeSetContent.add(function(ed, o) {
					each(settings.protect, function(pattern) {
						o.content = o.content.replace(pattern, function(str) {
							return '';
						});
					});
				});
			}

			// Add visual aids when new contents is added
			self.onSetContent.add(function() {
				self.addVisual(self.getBody());
			});

			// Remove empty contents
			if (settings.padd_empty_editor) {
				self.onPostProcess.add(function(ed, o) {
					o.content = o.content.replace(/^(
]*>( | |\s|\u00a0|)<\/p>[\r\n]*|
[\r\n]*)$/, '');
				});
			}

			self.load({initial : true, format : 'html'});
			self.startContent = self.getContent({format : 'raw'});

			/**
			 * Is set to true after the editor instance has been initialized
			 *
			 * @property initialized
			 * @type Boolean
			 * @example
			 * function isEditorInitialized(editor) {
			 *     return editor && editor.initialized;
			 * }
			 */
			self.initialized = true;

			self.onInit.dispatch(self);
			self.execCallback('setupcontent_callback', self.id, body, doc);
			self.execCallback('init_instance_callback', self);
			self.focus(true);
			self.nodeChanged({initial : true});

			// Add editor specific CSS styles
			if (self.contentStyles.length > 0) {
				contentCssText = '';

				each(self.contentStyles, function(style) {
					contentCssText += style + "\r\n";
				});

				self.dom.addStyle(contentCssText);
			}

			// Load specified content CSS last
			each(self.contentCSS, function(url) {
				self.dom.loadCSS(url);
			});

			// Handle auto focus
			if (settings.auto_focus) {
				setTimeout(function () {
					var ed = tinymce.get(settings.auto_focus);

					ed.selection.select(ed.getBody(), 1);
					ed.selection.collapse(1);
					ed.getBody().focus();
					ed.getWin().focus();
				}, 100);
			}

			// Clean up references for IE
			targetElm = doc = body = null;
		},

		/**
		 * Focuses/activates the editor. This will set this editor as the activeEditor in the tinymce collection
		 * it will also place DOM focus inside the editor.
		 *
		 * @method focus
		 * @param {Boolean} skip_focus Skip DOM focus. Just set is as the active editor.
		 */
		focus : function(skip_focus) {
			var oed, self = this, selection = self.selection, contentEditable = self.settings.content_editable, ieRng, controlElm, doc = self.getDoc(), body;

			if (!skip_focus) {
				if (self.lastIERng) {
					selection.setRng(self.lastIERng);
				}

				// Get selected control element
				ieRng = selection.getRng();
				if (ieRng.item) {
					controlElm = ieRng.item(0);
				}

				self._refreshContentEditable();

				// Focus the window iframe
				if (!contentEditable) {
					self.getWin().focus();
				}

				// Focus the body as well since it's contentEditable
				if (tinymce.isGecko || contentEditable) {
					body = self.getBody();

					// Check for setActive since it doesn't scroll to the element
					if (body.setActive) {
						body.setActive();
					} else {
						body.focus();
					}

					if (contentEditable) {
						selection.normalize();
					}
				}

				// Restore selected control element
				// This is needed when for example an image is selected within a
				// layer a call to focus will then remove the control selection
				if (controlElm && controlElm.ownerDocument == doc) {
					ieRng = doc.body.createControlRange();
					ieRng.addElement(controlElm);
					ieRng.select();
				}
			}

			if (tinymce.activeEditor != self) {
				if ((oed = tinymce.activeEditor) != null)
					oed.onDeactivate.dispatch(oed, self);

				self.onActivate.dispatch(self, oed);
			}

			tinymce._setActive(self);
		},

		/**
		 * Executes a legacy callback. This method is useful to call old 2.x option callbacks.
		 * There new event model is a better way to add callback so this method might be removed in the future.
		 *
		 * @method execCallback
		 * @param {String} n Name of the callback to execute.
		 * @return {Object} Return value passed from callback function.
		 */
		execCallback : function(n) {
			var t = this, f = t.settings[n], s;

			if (!f)
				return;

			// Look through lookup
			if (t.callbackLookup && (s = t.callbackLookup[n])) {
				f = s.func;
				s = s.scope;
			}

			if (is(f, 'string')) {
				s = f.replace(/\.\w+$/, '');
				s = s ? tinymce.resolve(s) : 0;
				f = tinymce.resolve(f);
				t.callbackLookup = t.callbackLookup || {};
				t.callbackLookup[n] = {func : f, scope : s};
			}

			return f.apply(s || t, Array.prototype.slice.call(arguments, 1));
		},

		/**
		 * Translates the specified string by replacing variables with language pack items it will also check if there is
		 * a key mathcin the input.
		 *
		 * @method translate
		 * @param {String} s String to translate by the language pack data.
		 * @return {String} Translated string.
		 */
		translate : function(s) {
			var c = this.settings.language || 'en', i18n = tinymce.i18n;

			if (!s)
				return '';

			return i18n[c + '.' + s] || s.replace(/\{\#([^\}]+)\}/g, function(a, b) {
				return i18n[c + '.' + b] || '{#' + b + '}';
			});
		},

		/**
		 * Returns a language pack item by name/key.
		 *
		 * @method getLang
		 * @param {String} n Name/key to get from the language pack.
		 * @param {String} dv Optional default value to retrive.
		 */
		getLang : function(n, dv) {
			return tinymce.i18n[(this.settings.language || 'en') + '.' + n] || (is(dv) ? dv : '{#' + n + '}');
		},

		/**
		 * Returns a configuration parameter by name.
		 *
		 * @method getParam
		 * @param {String} n Configruation parameter to retrive.
		 * @param {String} dv Optional default value to return.
		 * @param {String} ty Optional type parameter.
		 * @return {String} Configuration parameter value or default value.
		 * @example
		 * // Returns a specific config value from the currently active editor
		 * var someval = tinyMCE.activeEditor.getParam('myvalue');
		 *
		 * // Returns a specific config value from a specific editor instance by id
		 * var someval2 = tinyMCE.get('my_editor').getParam('myvalue');
		 */
		getParam : function(n, dv, ty) {
			var tr = tinymce.trim, v = is(this.settings[n]) ? this.settings[n] : dv, o;

			if (ty === 'hash') {
				o = {};

				if (is(v, 'string')) {
					each(v.indexOf('=') > 0 ? v.split(/[;,](?![^=;,]*(?:[;,]|$))/) : v.split(','), function(v) {
						v = v.split('=');

						if (v.length > 1)
							o[tr(v[0])] = tr(v[1]);
						else
							o[tr(v[0])] = tr(v);
					});
				} else
					o = v;

				return o;
			}

			return v;
		},

		/**
		 * Distpaches out a onNodeChange event to all observers. This method should be called when you
		 * need to update the UI states or element path etc.
		 *
		 * @method nodeChanged
		 * @param {Object} o Optional object to pass along for the node changed event.
		 */
		nodeChanged : function(o) {
			var self = this, selection = self.selection, node;

			// Fix for bug #1896577 it seems that this can not be fired while the editor is loading
			if (self.initialized) {
				o = o || {};

				// Get start node
				node = selection.getStart() || self.getBody();
				node = isIE && node.ownerDocument != self.getDoc() ? self.getBody() : node; // Fix for IE initial state

				// Get parents and add them to object
				o.parents = [];
				self.dom.getParent(node, function(node) {
					if (node.nodeName == 'BODY')
						return true;

					o.parents.push(node);
				});

				self.onNodeChange.dispatch(
					self,
					o ? o.controlManager || self.controlManager : self.controlManager,
					node,
					selection.isCollapsed(),
					o
				);
			}
		},

		/**
		 * Adds a button that later gets created by the ControlManager. This is a shorter and easier method
		 * of adding buttons without the need to deal with the ControlManager directly. But it's also less
		 * powerfull if you need more control use the ControlManagers factory methods instead.
		 *
		 * @method addButton
		 * @param {String} name Button name to add.
		 * @param {Object} settings Settings object with title, cmd etc.
		 * @example
		 * // Adds a custom button to the editor and when a user clicks the button it will open
		 * // an alert box with the selected contents as plain text.
		 * tinyMCE.init({
		 *    ...
		 *
		 *    theme_advanced_buttons1 : 'example,..'
		 *
		 *    setup : function(ed) {
		 *       // Register example button
		 *       ed.addButton('example', {
		 *          title : 'example.desc',
		 *          image : '../jscripts/tiny_mce/plugins/example/img/example.gif',
		 *          onclick : function() {
		 *             ed.windowManager.alert('Hello world!! Selection: ' + ed.selection.getContent({format : 'text'}));
		 *          }
		 *       });
		 *    }
		 * });
		 */
		addButton : function(name, settings) {
			var self = this;

			self.buttons = self.buttons || {};
			self.buttons[name] = settings;
		},

		/**
		 * Adds a custom command to the editor, you can also override existing commands with this method.
		 * The command that you add can be executed with execCommand.
		 *
		 * @method addCommand
		 * @param {String} name Command name to add/override.
		 * @param {addCommandCallback} callback Function to execute when the command occurs.
		 * @param {Object} scope Optional scope to execute the function in.
		 * @example
		 * // Adds a custom command that later can be executed using execCommand
		 * tinyMCE.init({
		 *    ...
		 *
		 *    setup : function(ed) {
		 *       // Register example command
		 *       ed.addCommand('mycommand', function(ui, v) {
		 *          ed.windowManager.alert('Hello world!! Selection: ' + ed.selection.getContent({format : 'text'}));
		 *       });
		 *    }
		 * });
		 */
		addCommand : function(name, callback, scope) {
			/**
			 * Callback function that gets called when a command is executed.
			 *
			 * @callback addCommandCallback
			 * @param {Boolean} ui Display UI state true/false.
			 * @param {Object} value Optional value for command.
			 * @return {Boolean} True/false state if the command was handled or not.
			 */
			this.execCommands[name] = {func : callback, scope : scope || this};
		},

		/**
		 * Adds a custom query state command to the editor, you can also override existing commands with this method.
		 * The command that you add can be executed with queryCommandState function.
		 *
		 * @method addQueryStateHandler
		 * @param {String} name Command name to add/override.
		 * @param {addQueryStateHandlerCallback} callback Function to execute when the command state retrival occurs.
		 * @param {Object} scope Optional scope to execute the function in.
		 */
		addQueryStateHandler : function(name, callback, scope) {
			/**
			 * Callback function that gets called when a queryCommandState is executed.
			 *
			 * @callback addQueryStateHandlerCallback
			 * @return {Boolean} True/false state if the command is enabled or not like is it bold.
			 */
			this.queryStateCommands[name] = {func : callback, scope : scope || this};
		},

		/**
		 * Adds a custom query value command to the editor, you can also override existing commands with this method.
		 * The command that you add can be executed with queryCommandValue function.
		 *
		 * @method addQueryValueHandler
		 * @param {String} name Command name to add/override.
		 * @param {addQueryValueHandlerCallback} callback Function to execute when the command value retrival occurs.
		 * @param {Object} scope Optional scope to execute the function in.
		 */
		addQueryValueHandler : function(name, callback, scope) {
			/**
			 * Callback function that gets called when a queryCommandValue is executed.
			 *
			 * @callback addQueryValueHandlerCallback
			 * @return {Object} Value of the command or undefined.
			 */
			this.queryValueCommands[name] = {func : callback, scope : scope || this};
		},

		/**
		 * Adds a keyboard shortcut for some command or function.
		 *
		 * @method addShortcut
		 * @param {String} pa Shortcut pattern. Like for example: ctrl+alt+o.
		 * @param {String} desc Text description for the command.
		 * @param {String/Function} cmd_func Command name string or function to execute when the key is pressed.
		 * @param {Object} sc Optional scope to execute the function in.
		 * @return {Boolean} true/false state if the shortcut was added or not.
		 */
		addShortcut : function(pa, desc, cmd_func, sc) {
			var t = this, c;

			if (t.settings.custom_shortcuts === false)
				return false;

			t.shortcuts = t.shortcuts || {};

			if (is(cmd_func, 'string')) {
				c = cmd_func;

				cmd_func = function() {
					t.execCommand(c, false, null);
				};
			}

			if (is(cmd_func, 'object')) {
				c = cmd_func;

				cmd_func = function() {
					t.execCommand(c[0], c[1], c[2]);
				};
			}

			each(explode(pa), function(pa) {
				var o = {
					func : cmd_func,
					scope : sc || this,
					desc : t.translate(desc),
					alt : false,
					ctrl : false,
					shift : false
				};

				each(explode(pa, '+'), function(v) {
					switch (v) {
						case 'alt':
						case 'ctrl':
						case 'shift':
							o[v] = true;
							break;

						default:
							o.charCode = v.charCodeAt(0);
							o.keyCode = v.toUpperCase().charCodeAt(0);
					}
				});

				t.shortcuts[(o.ctrl ? 'ctrl' : '') + ',' + (o.alt ? 'alt' : '') + ',' + (o.shift ? 'shift' : '') + ',' + o.keyCode] = o;
			});

			return true;
		},

		/**
		 * Executes a command on the current instance. These commands can be TinyMCE internal commands prefixed with "mce" or
		 * they can be build in browser commands such as "Bold". A compleate list of browser commands is available on MSDN or Mozilla.org.
		 * This function will dispatch the execCommand function on each plugin, theme or the execcommand_callback option if none of these
		 * return true it will handle the command as a internal browser command.
		 *
		 * @method execCommand
		 * @param {String} cmd Command name to execute, for example mceLink or Bold.
		 * @param {Boolean} ui True/false state if a UI (dialog) should be presented or not.
		 * @param {mixed} val Optional command value, this can be anything.
		 * @param {Object} a Optional arguments object.
		 * @return {Boolean} True/false if the command was executed or not.
		 */
		execCommand : function(cmd, ui, val, a) {
			var t = this, s = 0, o, st;

			if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(cmd) && (!a || !a.skip_focus))
				t.focus();

			a = extend({}, a);
			t.onBeforeExecCommand.dispatch(t, cmd, ui, val, a);
			if (a.terminate)
				return false;

			// Command callback
			if (t.execCallback('execcommand_callback', t.id, t.selection.getNode(), cmd, ui, val)) {
				t.onExecCommand.dispatch(t, cmd, ui, val, a);
				return true;
			}

			// Registred commands
			if (o = t.execCommands[cmd]) {
				st = o.func.call(o.scope, ui, val);

				// Fall through on true
				if (st !== true) {
					t.onExecCommand.dispatch(t, cmd, ui, val, a);
					return st;
				}
			}

			// Plugin commands
			each(t.plugins, function(p) {
				if (p.execCommand && p.execCommand(cmd, ui, val)) {
					t.onExecCommand.dispatch(t, cmd, ui, val, a);
					s = 1;
					return false;
				}
			});

			if (s)
				return true;

			// Theme commands
			if (t.theme && t.theme.execCommand && t.theme.execCommand(cmd, ui, val)) {
				t.onExecCommand.dispatch(t, cmd, ui, val, a);
				return true;
			}

			// Editor commands
			if (t.editorCommands.execCommand(cmd, ui, val)) {
				t.onExecCommand.dispatch(t, cmd, ui, val, a);
				return true;
			}

			// Browser commands
			t.getDoc().execCommand(cmd, ui, val);
			t.onExecCommand.dispatch(t, cmd, ui, val, a);
		},

		/**
		 * Returns a command specific state, for example if bold is enabled or not.
		 *
		 * @method queryCommandState
		 * @param {string} cmd Command to query state from.
		 * @return {Boolean} Command specific state, for example if bold is enabled or not.
		 */
		queryCommandState : function(cmd) {
			var t = this, o, s;

			// Is hidden then return undefined
			if (t._isHidden())
				return;

			// Registred commands
			if (o = t.queryStateCommands[cmd]) {
				s = o.func.call(o.scope);

				// Fall though on true
				if (s !== true)
					return s;
			}

			// Registred commands
			o = t.editorCommands.queryCommandState(cmd);
			if (o !== -1)
				return o;

			// Browser commands
			try {
				return this.getDoc().queryCommandState(cmd);
			} catch (ex) {
				// Fails sometimes see bug: 1896577
			}
		},

		/**
		 * Returns a command specific value, for example the current font size.
		 *
		 * @method queryCommandValue
		 * @param {string} c Command to query value from.
		 * @return {Object} Command specific value, for example the current font size.
		 */
		queryCommandValue : function(c) {
			var t = this, o, s;

			// Is hidden then return undefined
			if (t._isHidden())
				return;

			// Registred commands
			if (o = t.queryValueCommands[c]) {
				s = o.func.call(o.scope);

				// Fall though on true
				if (s !== true)
					return s;
			}

			// Registred commands
			o = t.editorCommands.queryCommandValue(c);
			if (is(o))
				return o;

			// Browser commands
			try {
				return this.getDoc().queryCommandValue(c);
			} catch (ex) {
				// Fails sometimes see bug: 1896577
			}
		},

		/**
		 * Shows the editor and hides any textarea/div that the editor is supposed to replace.
		 *
		 * @method show
		 */
		show : function() {
			var self = this;

			DOM.show(self.getContainer());
			DOM.hide(self.id);
			self.load();
		},

		/**
		 * Hides the editor and shows any textarea/div that the editor is supposed to replace.
		 *
		 * @method hide
		 */
		hide : function() {
			var self = this, doc = self.getDoc();

			// Fixed bug where IE has a blinking cursor left from the editor
			if (isIE && doc)
				doc.execCommand('SelectAll');

			// We must save before we hide so Safari doesn't crash
			self.save();

			// defer the call to hide to prevent an IE9 crash #4921
			DOM.hide(self.getContainer());
			DOM.setStyle(self.id, 'display', self.orgDisplay);
		},

		/**
		 * Returns true/false if the editor is hidden or not.
		 *
		 * @method isHidden
		 * @return {Boolean} True/false if the editor is hidden or not.
		 */
		isHidden : function() {
			return !DOM.isHidden(this.id);
		},

		/**
		 * Sets the progress state, this will display a throbber/progess for the editor.
		 * This is ideal for asycronous operations like an AJAX save call.
		 *
		 * @method setProgressState
		 * @param {Boolean} b Boolean state if the progress should be shown or hidden.
		 * @param {Number} ti Optional time to wait before the progress gets shown.
		 * @param {Object} o Optional object to pass to the progress observers.
		 * @return {Boolean} Same as the input state.
		 * @example
		 * // Show progress for the active editor
		 * tinyMCE.activeEditor.setProgressState(true);
		 *
		 * // Hide progress for the active editor
		 * tinyMCE.activeEditor.setProgressState(false);
		 *
		 * // Show progress after 3 seconds
		 * tinyMCE.activeEditor.setProgressState(true, 3000);
		 */
		setProgressState : function(b, ti, o) {
			this.onSetProgressState.dispatch(this, b, ti, o);

			return b;
		},

		/**
		 * Loads contents from the textarea or div element that got converted into an editor instance.
		 * This method will move the contents from that textarea or div into the editor by using setContent
		 * so all events etc that method has will get dispatched as well.
		 *
		 * @method load
		 * @param {Object} o Optional content object, this gets passed around through the whole load process.
		 * @return {String} HTML string that got set into the editor.
		 */
		load : function(o) {
			var t = this, e = t.getElement(), h;

			if (e) {
				o = o || {};
				o.load = true;

				// Double encode existing entities in the value
				h = t.setContent(is(e.value) ? e.value : e.innerHTML, o);
				o.element = e;

				if (!o.no_events)
					t.onLoadContent.dispatch(t, o);

				o.element = e = null;

				return h;
			}
		},

		/**
		 * Saves the contents from a editor out to the textarea or div element that got converted into an editor instance.
		 * This method will move the HTML contents from the editor into that textarea or div by getContent
		 * so all events etc that method has will get dispatched as well.
		 *
		 * @method save
		 * @param {Object} o Optional content object, this gets passed around through the whole save process.
		 * @return {String} HTML string that got set into the textarea/div.
		 */
		save : function(o) {
			var t = this, e = t.getElement(), h, f;

			if (!e || !t.initialized)
				return;

			o = o || {};
			o.save = true;

			o.element = e;
			h = o.content = t.getContent(o);

			if (!o.no_events)
				t.onSaveContent.dispatch(t, o);

			h = o.content;

			if (!/TEXTAREA|INPUT/i.test(e.nodeName)) {
				e.innerHTML = h;

				// Update hidden form element
				if (f = DOM.getParent(t.id, 'form')) {
					each(f.elements, function(e) {
						if (e.name == t.id) {
							e.value = h;
							return false;
						}
					});
				}
			} else
				e.value = h;

			o.element = e = null;

			return h;
		},

		/**
		 * Sets the specified content to the editor instance, this will cleanup the content before it gets set using
		 * the different cleanup rules options.
		 *
		 * @method setContent
		 * @param {String} content Content to set to editor, normally HTML contents but can be other formats as well.
		 * @param {Object} args Optional content object, this gets passed around through the whole set process.
		 * @return {String} HTML string that got set into the editor.
		 * @example
		 * // Sets the HTML contents of the activeEditor editor
		 * tinyMCE.activeEditor.setContent('some html');
		 *
		 * // Sets the raw contents of the activeEditor editor
		 * tinyMCE.activeEditor.setContent('some html', {format : 'raw'});
		 *
		 * // Sets the content of a specific editor (my_editor in this example)
		 * tinyMCE.get('my_editor').setContent(data);
		 *
		 * // Sets the bbcode contents of the activeEditor editor if the bbcode plugin was added
		 * tinyMCE.activeEditor.setContent('[b]some[/b] html', {format : 'bbcode'});
		 */
		setContent : function(content, args) {
			var self = this, rootNode, body = self.getBody(), forcedRootBlockName;

			// Setup args object
			args = args || {};
			args.format = args.format || 'html';
			args.set = true;
			args.content = content;

			// Do preprocessing
			if (!args.no_events)
				self.onBeforeSetContent.dispatch(self, args);

			content = args.content;

			// Padd empty content in Gecko and Safari. Commands will otherwise fail on the content
			// It will also be impossible to place the caret in the editor unless there is a BR element present
			if (!tinymce.isIE && (content.length === 0 || /^\s+$/.test(content))) {
				forcedRootBlockName = self.settings.forced_root_block;
				if (forcedRootBlockName)
					content = '<' + forcedRootBlockName + '>
</' + forcedRootBlockName + '>';
				else
					content = '
';

				body.innerHTML = content;
				self.selection.select(body, true);
				self.selection.collapse(true);
				return;
			}

			// Parse and serialize the html
			if (args.format !== 'raw') {
				content = new tinymce.html.Serializer({}, self.schema).serialize(
					self.parser.parse(content)
				);
			}

			// Set the new cleaned contents to the editor
			args.content = tinymce.trim(content);
			self.dom.setHTML(body, args.content);

			// Do post processing
			if (!args.no_events)
				self.onSetContent.dispatch(self, args);

			// Don't normalize selection if the focused element isn't the body in content editable mode since it will steal focus otherwise
			if (!self.settings.content_editable || document.activeElement === self.getBody()) {
				self.selection.normalize();
			}

			return args.content;
		},

		/**
		 * Gets the content from the editor instance, this will cleanup the content before it gets returned using
		 * the different cleanup rules options.
		 *
		 * @method getContent
		 * @param {Object} args Optional content object, this gets passed around through the whole get process.
		 * @return {String} Cleaned content string, normally HTML contents.
		 * @example
		 * // Get the HTML contents of the currently active editor
		 * console.debug(tinyMCE.activeEditor.getContent());
		 *
		 * // Get the raw contents of the currently active editor
		 * tinyMCE.activeEditor.getContent({format : 'raw'});
		 *
		 * // Get content of a specific editor:
		 * tinyMCE.get('content id').getContent()
		 */
		getContent : function(args) {
			var self = this, content, body = self.getBody();

			// Setup args object
			args = args || {};
			args.format = args.format || 'html';
			args.get = true;
			args.getInner = true;

			// Do preprocessing
			if (!args.no_events)
				self.onBeforeGetContent.dispatch(self, args);

			// Get raw contents or by default the cleaned contents
			if (args.format == 'raw')
				content = body.innerHTML;
			else if (args.format == 'text')
				content = body.innerText || body.textContent;
			else
				content = self.serializer.serialize(body, args);

			// Trim whitespace in beginning/end of HTML
			if (args.format != 'text') {
				args.content = tinymce.trim(content);
			} else {
				args.content = content;
			}

			// Do post processing
			if (!args.no_events)
				self.onGetContent.dispatch(self, args);

			return args.content;
		},

		/**
		 * Returns true/false if the editor is dirty or not. It will get dirty if the user has made modifications to the contents.
		 *
		 * @method isDirty
		 * @return {Boolean} True/false if the editor is dirty or not. It will get dirty if the user has made modifications to the contents.
		 * @example
		 * if (tinyMCE.activeEditor.isDirty())
		 *     alert("You must save your contents.");
		 */
		isDirty : function() {
			var self = this;

			return tinymce.trim(self.startContent) != tinymce.trim(self.getContent({format : 'raw', no_events : 1})) && !self.isNotDirty;
		},

		/**
		 * Returns the editors container element. The container element wrappes in
		 * all the elements added to the page for the editor. Such as UI, iframe etc.
		 *
		 * @method getContainer
		 * @return {Element} HTML DOM element for the editor container.
		 */
		getContainer : function() {
			var self = this;

			if (!self.container)
				self.container = DOM.get(self.editorContainer || self.id + '_parent');

			return self.container;
		},

		/**
		 * Returns the editors content area container element. The this element is the one who
		 * holds the iframe or the editable element.
		 *
		 * @method getContentAreaContainer
		 * @return {Element} HTML DOM element for the editor area container.
		 */
		getContentAreaContainer : function() {
			return this.contentAreaContainer;
		},

		/**
		 * Returns the target element/textarea that got replaced with a TinyMCE editor instance.
		 *
		 * @method getElement
		 * @return {Element} HTML DOM element for the replaced element.
		 */
		getElement : function() {
			return DOM.get(this.settings.content_element || this.id);
		},

		/**
		 * Returns the iframes window object.
		 *
		 * @method getWin
		 * @return {Window} Iframe DOM window object.
		 */
		getWin : function() {
			var self = this, elm;

			if (!self.contentWindow) {
				elm = DOM.get(self.id + "_ifr");

				if (elm)
					self.contentWindow = elm.contentWindow;
			}

			return self.contentWindow;
		},

		/**
		 * Returns the iframes document object.
		 *
		 * @method getDoc
		 * @return {Document} Iframe DOM document object.
		 */
		getDoc : function() {
			var self = this, win;

			if (!self.contentDocument) {
				win = self.getWin();

				if (win)
					self.contentDocument = win.document;
			}

			return self.contentDocument;
		},

		/**
		 * Returns the iframes body element.
		 *
		 * @method getBody
		 * @return {Element} Iframe body element.
		 */
		getBody : function() {
			return this.bodyElement || this.getDoc().body;
		},

		/**
		 * URL converter function this gets executed each time a user adds an img, a or
		 * any other element that has a URL in it. This will be called both by the DOM and HTML
		 * manipulation functions.
		 *
		 * @method convertURL
		 * @param {string} url URL to convert.
		 * @param {string} name Attribute name src, href etc.
		 * @param {string/HTMLElement} elm Tag name or HTML DOM element depending on HTML or DOM insert.
		 * @return {string} Converted URL string.
		 */
		convertURL : function(url, name, elm) {
			var self = this, settings = self.settings;

			// Use callback instead
			if (settings.urlconverter_callback)
				return self.execCallback('urlconverter_callback', url, elm, true, name);

			// Don't convert link href since thats the CSS files that gets loaded into the editor also skip local file URLs
			if (!settings.convert_urls || (elm && elm.nodeName == 'LINK') || url.indexOf('file:') === 0)
				return url;

			// Convert to relative
			if (settings.relative_urls)
				return self.documentBaseURI.toRelative(url);

			// Convert to absolute
			url = self.documentBaseURI.toAbsolute(url, settings.remove_script_host);

			return url;
		},

		/**
		 * Adds visual aid for tables, anchors etc so they can be more easily edited inside the editor.
		 *
		 * @method addVisual
		 * @param {Element} elm Optional root element to loop though to find tables etc that needs the visual aid.
		 */
		addVisual : function(elm) {
			var self = this, settings = self.settings, dom = self.dom, cls;

			elm = elm || self.getBody();

			if (!is(self.hasVisual))
				self.hasVisual = settings.visual;

			each(dom.select('table,a', elm), function(elm) {
				var value;

				switch (elm.nodeName) {
					case 'TABLE':
						cls = settings.visual_table_class || 'mceItemTable';
						value = dom.getAttrib(elm, 'border');

						if (!value || value == '0') {
							if (self.hasVisual)
								dom.addClass(elm, cls);
							else
								dom.removeClass(elm, cls);
						}

						return;

					case 'A':
						if (!dom.getAttrib(elm, 'href', false)) {
							value = dom.getAttrib(elm, 'name') || elm.id;
							cls = 'mceItemAnchor';

							if (value) {
								if (self.hasVisual)
									dom.addClass(elm, cls);
								else
									dom.removeClass(elm, cls);
							}
						}

						return;
				}
			});

			self.onVisualAid.dispatch(self, elm, self.hasVisual);
		},

		/**
		 * Removes the editor from the dom and tinymce collection.
		 *
		 * @method remove
		 */
		remove : function() {
			var self = this, elm = self.getContainer(), doc = self.getDoc();

			if (!self.removed) {
				self.removed = 1; // Cancels post remove event execution

				// Fixed bug where IE has a blinking cursor left from the editor
				if (isIE && doc)
					doc.execCommand('SelectAll');

				// We must save before we hide so Safari doesn't crash
				self.save();

				DOM.setStyle(self.id, 'display', self.orgDisplay);

				// Don't clear the window or document if content editable
				// is enabled since other instances might still be present
				if (!self.settings.content_editable) {
					Event.unbind(self.getWin());
					Event.unbind(self.getDoc());
				}

				Event.unbind(self.getBody());
				Event.clear(elm);

				self.execCallback('remove_instance_callback', self);
				self.onRemove.dispatch(self);

				// Clear all execCommand listeners this is required to avoid errors if the editor was removed inside another command
				self.onExecCommand.listeners = [];

				tinymce.remove(self);
				DOM.remove(elm);
			}
		},

		/**
		 * Destroys the editor instance by removing all events, element references or other resources
		 * that could leak memory. This method will be called automatically when the page is unloaded
		 * but you can also call it directly if you know what you are doing.
		 *
		 * @method destroy
		 * @param {Boolean} s Optional state if the destroy is an automatic destroy or user called one.
		 */
		destroy : function(s) {
			var t = this;

			// One time is enough
			if (t.destroyed)
				return;

			// We must unbind on Gecko since it would otherwise produce the pesky "attempt to run compile-and-go script on a cleared scope" message
			if (isGecko) {
				Event.unbind(t.getDoc());
				Event.unbind(t.getWin());
				Event.unbind(t.getBody());
			}

			if (!s) {
				tinymce.removeUnload(t.destroy);
				tinyMCE.onBeforeUnload.remove(t._beforeUnload);

				// Manual destroy
				if (t.theme && t.theme.destroy)
					t.theme.destroy();

				// Destroy controls, selection and dom
				t.controlManager.destroy();
				t.selection.destroy();
				t.dom.destroy();
			}

			if (t.formElement) {
				t.formElement.submit = t.formElement._mceOldSubmit;
				t.formElement._mceOldSubmit = null;
			}

			t.contentAreaContainer = t.formElement = t.container = t.settings.content_element = t.bodyElement = t.contentDocument = t.contentWindow = null;

			if (t.selection)
				t.selection = t.selection.win = t.selection.dom = t.selection.dom.doc = null;

			t.destroyed = 1;
		},

		// Internal functions

		_refreshContentEditable : function() {
			var self = this, body, parent;

			// Check if the editor was hidden and the re-initalize contentEditable mode by removing and adding the body again
			if (self._isHidden()) {
				body = self.getBody();
				parent = body.parentNode;

				parent.removeChild(body);
				parent.appendChild(body);

				body.focus();
			}
		},

		_isHidden : function() {
			var s;

			if (!isGecko)
				return 0;

			// Weird, wheres that cursor selection?
			s = this.selection.getSel();
			return (!s || !s.rangeCount || s.rangeCount === 0);
		}
	});
})(tinymce);