<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="ko"><title type="text">Firejune</title><link rel="alternate" type="text/html" href="http://firejune.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/firejune" /><subtitle type="html">이 사이트는 IT, 웹개발, 자바스크립트, 웹 프로그래밍, 웹2.0, 웹 애플리케이션 등에 대한 내용을 다룹니다.</subtitle><logo>http://firejune.com/attach/image/272778.jpeg</logo><updated>1970-01-01T00:00:00+00:00</updated><generator>Tatter Tools Hybrid</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/firejune" /><feedburner:info uri="firejune" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry><title type="text">3D 드로잉 펜 - 3Doodler</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/aLZiiMj_LAM/1786" /><category term="정보" /><category term="3Doodler" /><category term="3D 드로잉 펜" /><author><name>파이어준</name></author><updated>2013-02-21T03:09:57-08:00</updated><id>http://firejune.com/1786</id><content type="html">&lt;p&gt; &lt;iframe width="664" height="374" style="border:1px solid #aaa" src="http://www.youtube.com/embed/DQWyhezIze4?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.the3doodler.com/"&gt;3Doodler&lt;/a&gt;는 세계 최초이자 유일한 공기중에 입체로 그림을 그릴 수 있는 펜입니다. 전원에 연결하고 몇 분 정도 기다리면 바로 사용할 수 있으며, 소프트웨어나 컴퓨터를 필요로 하지 않습니다. 심은  ABS 플라스틱(3D 프린터에서 흔히 사용되는 재료)를 이용한다고 합니다.&lt;/p&gt;
&lt;p&gt;3Doodler는 어린이용 장난감으로는 부적합하며, 가격은 50달러군요.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1786#p1786"&gt;Comments(2)&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1786"&gt;Hits(55814)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/aLZiiMj_LAM" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1786</feedburner:origLink></entry><entry><title type="text">스타크래프트2 - 군단의 심장 시네마틱</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/j5lnFzJSwis/1784" /><category term="게임/오락" /><category term="문화" /><category term="스타크래프트2" /><category term="시네마틱" /><category term="동영상" /><category term="퀄리티 쩔어" /><author><name>파이어준</name></author><updated>2013-01-22T06:50:46-08:00</updated><id>http://firejune.com/1784</id><content type="html">&lt;p&gt; &lt;iframe id="sc2" width="666" height="375" src="http://www.youtube.com/embed/MVbeoSPqRs4" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;퀄리티 쩌네요. &lt;a href="http://www.youtube.com/embed/TroQ7fKj7hE" onclick="Event.stop(event); $('sc2').src = this.href"&gt;여기를 클릭&lt;/a&gt;하면 한글 더빙판으로 토글합니다.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1784#p1784"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1784"&gt;Hits(68354)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/j5lnFzJSwis" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1784</feedburner:origLink></entry><entry><title type="text">웹 분석도구 Piwik 한국어 현지화 완료!</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/weLNbgcc_IM/1783" /><category term="뻘짓" /><category term="일상" /><category term="Piwik" /><category term="웹 분석도구" /><category term="오픈 소스" /><category term="Analytics" /><category term="번역" /><category term="PHP" /><category term="리소스" /><category term="한국어" /><category term="현지화" /><author><name>파이어준</name></author><updated>2013-01-21T08:39:27-08:00</updated><id>http://firejune.com/1783</id><content type="html">&lt;div class="image-align center"&gt;&lt;a href="http://piwik.org/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0122/130122004029865641/220348.png" border="1" width="666" height="355" alt="Piwik.org.png" class="reflect hasborder"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://piwik.org/"&gt;Piwik&lt;/a&gt;은 오픈 소스 기반의 웹사이트 분석도구입니다. 구글 Analytics의 대안으로 손꼽히고 있으며, 비교적 트래픽이 많은 사이트도 소화할 수 있다고 합니다. 최신 버전인 1.10.1의 한국어 현지화를 방금 마무리했어요. 작업을 시작할 무렵 김종인님이 36% 진행해 놓은 것에 바톤을 이어받아 100% 까지 총 2,153개의 리소스 번역을 한 주에 걸쳐 완료했습니다. 다음 버전 릴리즈 때 반영되겠지만 먼저 적용해 보실 분들은 &lt;a href="http://firejune.com/download/457004.phps"&gt;여기에서 다운로드&lt;/a&gt; 할 수 있습니다.(확장자를 php로 바꾸고 piwik/lang/ 디렉토리에 덮어쓰세요)&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0122/130122004029865641/779823.png" border="1" width="666" height="382" alt="piwik translations.png" class="reflect hasborder"/&gt;
&lt;p class="cap1" style="margin:4px 0 3px 0;"&gt;뿌..., 뿌듯함!&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;직접 사용해 보면서 문맥이 이상한 부분들은 최대한 수정하고 있지만 미처 발견하지 못한 오역이나 이상한 부분이 있다면 알려주세요. 즉시 수정해서 반영하도록 하겠습니다. 그런데 이걸 왜했냐고요? 가끔은 자기 자신을 무작정 괴롭혀 보는 것도 기분전환에 큰 도움이 되더군요….&lt;/p&gt;
&lt;p&gt;덧. Piwik을 설치하고 알아낸 유용한 것들을 정리해 보았습니다. &lt;/p&gt;
&lt;ul class="square"&gt;
&lt;li&gt;&lt;a href="http://piwik.org/mobile/"&gt;Piwik 모바일&lt;/a&gt;을 사용한다면, 보고서의 그래프에 문자가 깨집니다. &lt;a href="http://piwik.org/wp-content/uploads/unifont.ttf.zip"&gt;unifont.ttf&lt;/a&gt;를 다운로드하고, 압축을 풉니다. piwik/plugins/ImageGraph/fonts 디렉토리로 업로하면 문자가 깨지는 것을 바로잡을 수 있습니다.&lt;/li&gt;
&lt;li&gt;Maxmind에서 유료로 제공하는 데이터베이스를 misc 디렉토리에 업로드하면, ISP 공급자와 업체를 추적할 수 있습니다.&lt;/li&gt;
&lt;li&gt;20개 이상의 다양한 &lt;a href="http://dev.piwik.org/trac/query?status=new&amp;amp;status=assigned&amp;status=reopened&amp;milestone=Third+Party+Piwik+Plugins&amp;order=priority"&gt;플러그인&lt;/a&gt;을 사용할 수 있습니다. 압축을 푼 후 plugins 디렉토리에 업로드하기만 하면 플러그인 목록에서 활성/비활성 할 수있습니다.&lt;/li&gt;
&lt;li&gt;검색어 보고서에서 네이버의 한글 검색어가 깨져 보이는 문제는 core/DataFiles/SearchEngines.php 파일에서 &lt;code&gt;'search.naver.com'&lt;/code&gt; 문자열을 찾고 정의되는 배열 마지막에 &lt;code&gt;, 'EUC-KR'&lt;/code&gt;을 제거하여 해결할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;덧. 2013-01-25 업데이트: 추가적인 문맥 수정&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1783#p1783"&gt;Comments(1)&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1783"&gt;Hits(71520)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/weLNbgcc_IM" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1783</feedburner:origLink></entry><entry><title type="text">실시간 모바일 앱 분석 도구 - Countly</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/vrGKaRFTpq4/1782" /><category term="웹개발" /><category term="자료" /><category term="Countly" /><category term="앱" /><category term="Node.js" /><category term="자바스크립트" /><category term="Express.js" /><category term="오픈 소스" /><category term="MongoDB" /><category term="NginX" /><category term="Python" /><category term="Supervisor" /><category term="Cafe24" /><category term="Analytics" /><category term="프로젝트" /><category term="모바일" /><author><name>파이어준</name></author><updated>2013-01-16T09:01:32-08:00</updated><id>http://firejune.com/1782</id><content type="html">&lt;p&gt; &lt;a href="http://count.ly/"&gt;Countly&lt;/a&gt;는 4인으로 구성된 터키출신의 착한 젊은 친구들에 의해 만들어진 실시간 모바일 앱 분석 도구입니다. 모바일 앱 엔드-유저의 행동 자료를 수집하고 분석하여 시각화해 줍니다. 구글 Analytics와 같은 웹 분석 도구를 모바일 앱에 최적화한 것으로 이해할 수 있겠네요. &lt;a href="https://github.com/Countly"&gt;오픈 소스&lt;/a&gt;이며 데이터 수집 및  관리할 수 있는 서버와 안드로이드, 윈도폰, iOS, 블랙베리(WebWorks)용 SDK를 동시에 제공합니다. (서드-파티에서 만든 유니티, 앱셀러레이터 타이타니움, 맥OSX용 SDK도 있습니다.) 재미있는 것은 SDK에서 제공하는 사용자 이벤트 API를 이용하면 앱 안에서의 사용자 패턴도 분석할 수 있습니다. (예를 들면, 게임 내 어떤 무기가 빈번하게 사용되는지 라던가...)&lt;br&gt;

  &lt;div id="gallery4146" class="g_container" style="width:px;height:px;"&gt;
    &lt;img src="http://firejune.cdn2.cafe24.com/attach/0117/130117000119993498/070369.png" width="" height="" id="g_img4146_0" alt="attachment"/&gt;
  &lt;/div&gt;
  &lt;div class="cap1" id="scap4146"&gt;&lt;/div&gt;
  
&lt;/p&gt;
&lt;p&gt;그들이 제공하는 &lt;a href="http://count.ly/login"&gt;데모&lt;/a&gt;를 실행해 보고 가지고 싶다는 생각이 들더군요. 나중에 서비스할지는 모르겠습니다만, 앱을 유료로 등록하고 사용할 수 있게 하는 기능은 없습니다. 그래서 Countly를 지금 사용해 보기 위해서는 운영 가능한 웹서버에 설치를 해야 하는 상황인 거죠. 서버는 Node.js와 MongoDB로 구축되었고 NginX와 Supervisor, Python 등의 패키지 설치를 요구하며, 리눅스 머신(우분투 권장)에 설치할 수 있습니다. 자체적으로 제공하는 설치 스크립트를 이용하면 Node.js를 비롯한 서버 실행 환경을 자동으로 구성해 줍니다. (비추천) 서버는 API와 Frontend로 양분되었으며, API 서버는 데이터의 입/출력을 담당하고, Express.js기반의 Frontend 서버는 데이터의 섹시한 비주얼라이제이션과 사용자 관리 기능을 포함합니다. 이 두 서버는 supervisord으로 관리되며, NginX에서 라우팅 룰에의해 서로 다른 포트를 가진 서버 프로세스로 프락시 패스하도록 구성되어 있었습니다. Cafe24에 놀리고 있는 &lt;a href="http://firejune.io"&gt;가상서버&lt;/a&gt;에 설치하기 위해, 반나잘 삽질하고 &lt;a href="http://kerberosj.tistory.com/"&gt;윤진군&lt;/a&gt;의 도움으로 &lt;a href="http://countly.firejune.io"&gt;성공적으로 실행&lt;/a&gt;했습니다. 그런데 아쉽게도 등록할 만한 앱이 없네요. 혹시 관심 있는 분은 무료로 앱을 등록해 드릴께요. 요청에 한해서 등록한 앱 단위로 데이터베이스까지 덤프해서 드릴 생각입니다.&lt;/p&gt;
&lt;p&gt;아쉽게도 한글 지원이 없어서 직접 &lt;a href="https://www.transifex.com/projects/p/countly/"&gt;한글화 작업을 완료&lt;/a&gt;하고 적용해 줄 것을 요청한 상태입니다. 그리고 각종 데이터를 PDF 문서로 생성해 주는 기능과 모바일에서 액세스할 수 있는 네이티브 앱을 개발 중이며 곧 선보일 예정이라고 하네요. 아주 멋집니다!&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1782#p1782"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1782"&gt;Hits(23292)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/vrGKaRFTpq4" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1782</feedburner:origLink></entry><entry><title type="text">요센 게임도 참 쉽게 만드네 - 유니티</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/URISlsU-xcQ/1781" /><category term="게임/오락" /><category term="문화" /><category term="유니티" /><category term="자바스크립트" /><category term="게임" /><category term="유니티 테크놀로지스 코리아" /><category term="메카님" /><category term="다이렉트X 11" /><category term="게임 엔진" /><category term="크로스 플랫폼" /><category term="모바일" /><category term="인디 게임" /><category term="프로젝트" /><category term="쩌... 쩐다." /><author><name>파이어준</name></author><updated>2013-01-03T04:24:24-08:00</updated><id>http://firejune.com/1781</id><content type="html">&lt;p&gt; 회사 분위기가 싱숭생숭하여 생존 본능이 발동했습니다. 웹은 좀 지겨우니까 이제 다른 쪽 기술들도 살펴볼겸 해서 어깨너어로 슬쩍슬쩍 넘겨보던 와중에 게임회사 다니는 쫑맹형이 "너 자바스크립트 하지?"라고는 질문을 던졌고, "유니티라는거 알아? 그거 죽이니까 살펴봐"라는 정보를 줬습니다. &lt;a href="http://unity3d.com/"&gt;유니티 홈페이지&lt;/a&gt;에 들러 대략 훓어보니 이거 완전 물건이더군요. 게임제작에 필요한 시작부터 끝을 보장하며, &lt;a href="http://korea.unity3d.com/content/content.php?cont=multiplatform"&gt;멀티 플랫폼&lt;/a&gt;이고, 2011년도에 &lt;a href="http://korea.unity3d.com/"&gt;한국 지사&lt;/a&gt;가 설립되어 개발 지원이 풍부하며, 언리얼이나 기타 게임엔진에 비해 저렴한 등 장점을 모두 나열하자면 입이 아플 지경입니다.&lt;/p&gt;
&lt;div class="image-align left"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0103/130103195117322335/470164.jpg" width="320" height="235" alt="unity_editor.jpg" class=" hasborder"/&gt;&lt;/div&gt;
&lt;p&gt;최근 런칭한 &lt;a href="http://korea.unity3d.com/content/content.php?cont=download_unity4_0"&gt;유니티 4.0&lt;/a&gt;은 다이렉트X 11을 공식적으로 지원하고, GUI를 완전히 재작성하여 낮은 성능의 개발환경에서의 효율성을 높였으며, 강력한 애니메이션 시스템(&lt;a href="http://korea.unity3d.com/content/content.php?cont=mecanim"&gt;메카님&lt;/a&gt;)을 제공하여 모션 캡처한 애니메이션을 마치 동영상 편집하듯이 손쉽게 다룰 수 있고, 리눅스 플랫폼을 추가로 지원하며, 그래픽 기능에 엄청난 향상이 있고, 곡선과 기울기 중심의 모듈 파티클 시스템 도구를 강화해 폭발, 충돌, 태풍 등을 보다 적은 예산으로 구현하는 등 많은 발전이 있었다고 합니다. 30일간 사용해 볼 수 있는 트라이얼 버전을 설치하고 이런저런 스크린캐스트를 보면서 따라 하는 중인데, 감탄을 금치 못하고 있습니다. 개발과정에 필요한 모든 라이브러리가 모듈화 되었고 개발도구와 잘 결합하여 조금만 집중하면 간단한 게임 정도는 뚝딱 만들겠다는 생각이 들더군요. 유니티로 만들어진 게임들을 살펴보면 iOS 2012 최고의 게임으로 선정된 &lt;a href="http://unity3d.com/gallery/made-with-unity/profiles/profile#fireproof-theroom"&gt;Room&lt;/a&gt;, 앵그리 버드로 유명한 Rovio사의 &lt;a href="http://unity3d.com/gallery/made-with-unity/profiles/profile#rovio-badpiggies"&gt;Bad Piggies&lt;/a&gt;, &lt;a href="http://unity3d.com/gallery/made-with-unity/profiles/profile#crescent-ravensword"&gt;Ravensword&lt;/a&gt; 이름만 들어도 알 수 있을만한 히트작들이 꽤 있었습니다.&lt;/p&gt;
&lt;p&gt;그리고 홈페이지는 물론 모든 &lt;a href="http://korea.unity3d.com/content/content.php?cont=document_list"&gt;메뉴얼과 레퍼런스 문서&lt;/a&gt;를 완벽한 한글로 제공해 주어 힘들게 구한 외국 문서를 번역해가면서 삽질할 필요가 없다는 것이죠. 그리고 한국만을 위한 &lt;a href="http://korea.unity3d.com/content/content.php?cont=community_main"&gt;개발자 커뮤니티&lt;/a&gt;도 자체적으로 활성화를 도모하는 아름다운 자세를 엿볼 수 있었습니다. 너무 칭찬 일색이네요. 마지막으로 가장 마음에 드는 부분은 자바스크립트를 이용한 스크립트 작성을 지원하는 것입니다. C#(Mono 기반) 또는 Boo로도 스크립트를 작성할 수 있습니다. "아~ 이걸 왜 지금에 와서야 안 거지?"라는 아쉬움이 들 정도입니다. 취미로 삼아 가지고 놀다가 뭔가 재미있는 아이디어가 떠오르면 본격적으로 시작해 봐야겠습니다. 2013년은 왠지 뭔가 터질 것만 같은 이래저래 흥분되는 해가 될 것 같습니다.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1781#p1781"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1781"&gt;Hits(16385)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/URISlsU-xcQ" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1781</feedburner:origLink></entry><entry><title type="text">다트와 타입스크립트 뭘 해야하나?</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/d8Q43Baq-1I/1779" /><category term="웹개발" /><category term="자료" /><category term="Dart" /><category term="TypeScript" /><category term="자바스크립트" /><category term="ECMA" /><category term="VM" /><category term="프로그래밍" /><category term="전 다트 할겁니다." /><author><name>파이어준</name></author><updated>2013-01-02T02:06:51-08:00</updated><id>http://firejune.com/1779</id><content type="html">&lt;p&gt; 1년 전 구글은 자바스크립트를 대체할만한 새로운 언어인 &lt;a href="http://www.dartlang.org/"&gt;다트(Dart)&lt;/a&gt; 만들겠다고 발표했고 1년이 지난 지금 &lt;a href="http://news.dartlang.org/2012/12/dart-milestone-2-has-been-announced.html"&gt;M2 버전&lt;/a&gt;을 발표하면서 쓸만한 수준으로까지 만들어 놓은 것 같습니다. 이에 질세라 MS도 비슷한 시기에 &lt;a href="http://www.typescriptlang.org/"&gt;타입스크립트(TypeScript)&lt;/a&gt;라는 새로운 자바스크립트 프로그래밍 대안을 제시했습니다. 이 둘의 공통적인 지향점은 자바스크립트를 대체하기 보다는 부족한 점을 보완하고 편리성, 확장성, 생산성 향상을 도모해 애플리케이션 규모의 개발을 이롭게 하자는 것입니다. 이러한 측면에서 개발자에게 애플리케이션을 개발하는 새로운 방법을 제시하는 것 그 이상도 그 이하도 아니라는 점은 분명합니다. 일부 시각에서 대체라는 둥 한계라는 둥, 신경 거슬리는 말을 자주 사용하는데 전혀 동요할 필요가 없겠습니다. 그래도 이 새로운 언어들이 계속해서 눈에 밟힐 것 같아 차이점 정도는 집고 넘어야겠다 싶어 알아보았습니다.&lt;/p&gt;
&lt;p&gt;타입스크립트는 ECMA 표준에 근거한 다음 버전의 자바스크립트 규격에 기반을 뒸습니다. 이것은 앞으로 표준이 될 가능성을 염두에 둔 자바스크립트 슈퍼셋입니다.(예: C++은 C의 슈퍼셋) 타입을 검사할 수 있고, 기존 라이브러리를 그대로 사용하며 크로스 플랫폼으로 작성할 수 있는 장점이 있다고 합니다. 기존 자바스크립트와의 호환성을 위해 타입스크립트로 작성된 코드를 자바스크립트로 컴파일 할 수 있으며, 그 완성도가 매우 뛰어납니다. 타입스크립트는 &lt;a href="http://nodejs.org/"&gt;Node.js&lt;/a&gt;에서도 사용할 수 있도록 모듈을 배포하고 있네요. 타입스크립트의 개발은 비주얼 스튜디오 2012에서 이루어지며 플러그인 형태로 설치할 수 있습니다. 혹자는 액션스크립트 3으로 자바스크립트를 짜는 거네... 차라리 &lt;a href="http://coffeescript.org/"&gt;CoffeeScript&lt;/a&gt;를 쓰겠어, 성능은?, 네이티브로 작동하기 위한 계획이나 확산 계획이 불분명하다는 부정적인 반응도 보입니다. 아래는 타입스크립트가 자바스크립트로 컴파일된 예입니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;// typescript
class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

// javascript
var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;다트는 전통적인 클래스기반 객제지향언어입니다. C#, Java를 다뤄본 경험이 있다면 다트의 문법이 친숙하게 느껴질 것입니다. 자바스크립트와 마찬가지로 싱글 스레드로 작동하지만 자체적으로 제공하는 다트 VM(가상 머신)에 탑재된 Isolate를 이용하여 멀티 스레드를 구현할 수 있습니다. VM이 있다는 것은 곧 Node.js와 같은 서버-사이드 프로그래밍도 가능하다는 말입니다. 서버와 클라이언트간 코드가 동일하다는 점에서 비롯되는 이점은 의외로 많습니다. 예를 들면, 시스템 사양이 좋은 테스크탑에서는 클라이언트의 리소스를 활용하고 그렇지 않은 모바일에서는 서버의 리소스를 활용하는 로직을 하나로 코드로 관리할 수 있게 되는 것이죠. 그러나 이것은 모든 환경에 VM이 탑재되었을때 비로소 가능한 것입니다. VM이 보편화하기 전까지는 다트로 작성된 코드가 자바스크립트로 컴파일되도록 하자는 전략입니다. 이클립스기반의 &lt;a href="http://www.dartlang.org/docs/editor/"&gt;다트 에디터&lt;/a&gt;에서 통합 개발환경을 제공하고 다트 VM이 탑재된 크롬 브라우저인 &lt;a href="http://www.dartlang.org/dartium/"&gt;Dartium&lt;/a&gt;에서 다트 코드를 테스트할 수 있습니다. 그리고 자바스크립트 컴파일러, VM, 패키지 매니저로 구성된 &lt;a href="http://www.dartlang.org/docs/sdk/"&gt;SDK&lt;/a&gt;를 제공합니다. 다음은 다트의 예문입니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;import 'dart:html';

main() {
  var msg = query('#msg');
  var btn = new ButtonElement();
  btn.text = 'Click me!';
  btn.on.click.add((e) =&amp;gt; msg.text = 'Dart!');
  document.body.nodes.add(btn);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;덧. 실제로 다트나 타입스크립트를 직접 경험하지 못한 상황에서 바라본 시각으로 작성했다는 점 참고해주세요. 두 언어 모두 근사한 기능을 말하고 있지만 현시점에서 실무에 적용하려면 컴파일러를 통해 자바스크립트로 변환하여 적용하는 일이 고작인듯합니다. 그렇다고 아직 개발 중인 녀석들에게 왈가왈부할 수도 없는 상황이네요. 저는 올해부터 다트를 공부하기로 마음먹었습니다. 다트가 자체적인 런타임을 가지고 있다는 부분이 정말 매력적으로 느껴지더군요. 웹의 범주를 넘어서는 가능성을 열어두었다는 생각이 듭니다. VM위에서는 어느 정도의 성능이 나올지 벌써부터 기대되는군요.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1779#p1779"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1779"&gt;Hits(14969)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/d8Q43Baq-1I" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1779</feedburner:origLink></entry><entry><title type="text">Schema.org 이용하여 HTML 데이터 구조화하기</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/5scidnL4kn4/1778" /><category term="웹개발" /><category term="자료" /><category term="HTML5" /><category term="데이터 구조화" /><category term="마이크로포맷" /><category term="RDFa" /><category term="마이크로데이터" /><category term="data-vocabulary.org" /><category term="Schema.org" /><category term="SEO" /><category term="밀린 포스트 갑자기 마무리하기" /><category term="리치 스니펫" /><author><name>파이어준</name></author><updated>2012-12-31T05:18:41-08:00</updated><id>http://firejune.com/1778</id><content type="html">&lt;p&gt; 개발자들이 정의한 각종 데이터를 최종 결과물인 HTML 문서를 통해서 출력하지만 이를 다시 데이터형으로 돌리기에는 많은 어려움이 있기 때문에 HTML 문서에서 데이터를 구분해 낼 수 있는 방법으로 &lt;a href="http://en.wikipedia.org/wiki/Microdata_(HTML)"&gt;마이크로데이터&lt;/a&gt;이나 &lt;a href="http://microformats.org/wiki/html5"&gt;마이크로포맷&lt;/a&gt; 또는 &lt;a href="http://en.wikipedia.org/wiki/RDFa"&gt;RDFa&lt;/a&gt;를 이용할 수 있습니다. RDFa는 XHTML에나 잘 어울릴 법한 모양새이고 사용법이 다소 까다롭다는 점에서 개인적으로는 마이크로포맷이나 마이크로데이터를 선호합니다. 마이크로포맷은 별도의 네임스페이스 선언을 필요로하지 않고 class와 rel 속성만을 이용하여 구조화된 데이터를 표현할 수 있지만, 단계가 있거나 관계가 있는 데이터를 구조화하기에는 부족한 면이 있습니다. 마이크로데이터는 RDFa와 마이크로포맷의 중간쯤으로 볼 수 있습니다. 자세한 사용 방법은 구글이 문서(&lt;a href="https://support.google.com/webmasters/bin/answer.py?answer=176035"&gt;microdata&lt;/a&gt;, &lt;a href="https://support.google.com/webmasters/bin/answer.py?answer=146897"&gt;microformats&lt;/a&gt;, &lt;a href="https://support.google.com/webmasters/bin/answer.py?answer=146898"&gt;RDFa&lt;/a&gt;)를 잘 만들어 뒀습니다.&lt;/p&gt;
&lt;p&gt;이 얘기는 수년 전부터 거론되었지만 웹사이트 소유주에게 돌아가는 이렇다 할 가치가 없었기 때문에 지들끼리 말만 많았던 HTML5 스팩이죠. 최근 구글은 이 구조화된 데이터를 이용하여 저자나 인물을 표시하거나 제품이나 장소 등의 평점 및 리뷰, 앨범의 트랙 정보 이벤트 등을 검색결과에 노출하고 있으며, 이것을 &lt;a href="https://support.google.com/webmasters/bin/answer.py?hl=ko&amp;amp;answer=99170"&gt;리치 스니펫&lt;/a&gt;이라 부르고 있습니다. 구글은 리치 스니펫을 제공하는 방법으로는 마이크로데이터를 권장하고 있으며 이는 데이터가 어떤 종류인지를 정의하는 스키마를 필요로합니다. 대표적으로 &lt;a href="http://data-vocabulary.org"&gt;data-vocabulary.org&lt;/a&gt;또는 &lt;a href="http://schema.org"&gt;schema.org&lt;/a&gt;에서 제공하는 데이터 스키마를 선언하는데 이를 잘 이용하면 관계형 데이터 구조화가 가능해 집니다.&lt;/p&gt;
&lt;p&gt;구글은 웹마스터 도구를 통해 &lt;a href="http://www.google.com/webmasters/tools/richsnippets"&gt;구조화된 데이터 테스팅 도구&lt;/a&gt;를 제공합니다. 다음은 schema.org의 데이터 스키마를 기반으로 이 블로그의 데이터를 구조화하고 테스팅 도구를 통해 얻은 &lt;a href="http://www.google.com/webmasters/tools/richsnippets?url=http%3A%2F%2Ffirejune.com%2F1776%2FNode.JS%25EC%259A%25A9%2BScribd%2B%25EB%25AA%25A8%25EB%2593%2588%2B%25EB%25B0%25B0%25ED%258F%25AC&amp;amp;html="&gt;결과&lt;/a&gt;입니다. 제법 쓸만한 데이터가 만들어 지더라고요. 조금 더 발전하면 ATOM이나 RSS를 별도로 제공하는게 무의미해질지도 모르겠네요.&lt;/p&gt;

&lt;h4&gt;Item&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;type:&lt;/strong&gt; &lt;a href="http://schema.org/blog"&gt;http://schema.org/blog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;property:&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;url: &lt;a href="http://firejune.com/"&gt;Firejune&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;name: &lt;a href="http://firejune.com/"&gt;Firejune&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;description: The Web is still changing.&lt;/li&gt;
      &lt;li&gt;version: 2.19&lt;/li&gt;
      &lt;li&gt;blogpost: &lt;strong&gt;Item 1&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;author: &lt;strong&gt;Item 2&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Item 1&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;type:&lt;/strong&gt; &lt;a href="http://schema.org/article"&gt;http://schema.org/article&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;property:&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;datepublished: 2012-12-19&lt;/li&gt;
      &lt;li&gt;name: &lt;a href="http://firejune.com/1776/Node.JS%EC%9A%A9+Scribd+%EB%AA%A8%EB%93%88+%EB%B0%B0%ED%8F%AC"&gt;Node.JS용 Scribd 모듈 배포&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;url: &lt;a href="http://firejune.com/1776/Node.JS%EC%9A%A9+Scribd+%EB%AA%A8%EB%93%88+%EB%B0%B0%ED%8F%AC"&gt;Node.JS용 Scribd 모듈 배포&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;author: &lt;a href="http://firejune.com/1776/Node.JS%EC%9A%A9+Scribd+%EB%AA%A8%EB%93%88+%EB%B0%B0%ED%8F%AC#author"&gt;파이어준&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;interactioncount: &lt;a href="http://firejune.com/1776/Node.JS%EC%9A%A9+Scribd+%EB%AA%A8%EB%93%88+%EB%B0%B0%ED%8F%AC#comments-1776"&gt;Reactions4&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;articlebody: 역시나, 기업 요구사항은 파일 교환보다는 문서 관리 쪽으로 많이 치우쳐져 있더군요. 그래서 문서관련 기능을 강화하기 위해 매시업할 수 있는...&lt;/li&gt;
      &lt;li&gt;keywords: &lt;a href="http://firejune.com/entries/8-42"&gt;자료 - 웹개발&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;keywords: &lt;a href="http://firejune.com/tag/Node.JS"&gt;Node.JS&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;keywords: &lt;a href="http://firejune.com/tag/Scribd"&gt;Scribd&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;keywords: &lt;a href="http://firejune.com/tag/HTML5"&gt;HTML5&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;keywords: &lt;a href="http://firejune.com/tag/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8"&gt;자바스크립트&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;keywords: &lt;a href="http://firejune.com/tag/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8"&gt;프로젝트&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;keywords: &lt;a href="http://firejune.com/tag/GitHub"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;keywords: &lt;a href="http://firejune.com/tag/NPM"&gt;NPM&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;keywords: &lt;a href="http://firejune.com/tag/%EB%A7%A4%EC%8B%9C%EC%97%85"&gt;매시업&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;comment: &lt;strong&gt;Item 3&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;comment: &lt;strong&gt;Item 4&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;comment: &lt;strong&gt;Item 5&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;comment: &lt;strong&gt;Item 6&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Item 3&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;type:&lt;/strong&gt; &lt;a href="http://schema.org/comment"&gt;http://schema.org/comment&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;property:&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;datecreated: 2012-12-20T08:55:50+09:00&lt;/li&gt;
      &lt;li&gt;image: &lt;a href="http://a0.twimg.com/profile_images/2399594250/8dp14wildkk8xbt8ownl_normal.png"&gt;http://a0.twimg.com/profile_images/2399594250/8dp14wildkk8xbt8ownl_normal.png&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;url: &lt;a href="http://twitter.com/beyonditblog"&gt;beyonditblog&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;name: &lt;a href="http://twitter.com/beyonditblog"&gt;beyonditblog&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;text: Node.JS용 Scribd 모듈 배포: 역시나, 기업 요구사항은 파일 교환 보다는 문서 관리쪽으로 많이 치우쳐져 있더군요. 그래서 문서관련 기능을 강화하기...&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Item 4&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;type:&lt;/strong&gt; &lt;a href="http://schema.org/comment"&gt;http://schema.org/comment&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;property:&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;datecreated: 2012-12-20T09:24:06+09:00&lt;/li&gt;
      &lt;li&gt;image: &lt;a href="http://a0.twimg.com/profile_images/1123405595/IT_NEWS_normal.jpg"&gt;http://a0.twimg.com/profile_images/1123405595/IT_NEWS_normal.jpg&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;url: &lt;a href="http://twitter.com/All_IT_News"&gt;All_IT_News&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;name: &lt;a href="http://twitter.com/All_IT_News"&gt;All_IT_News&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;text: 
text:	[경준호] Node.JS용 Scribd 모듈 배포: 역시나, 기업 요구사항은 파일 교환 보다는 문서 관리쪽으로 많이 치우쳐져 있더군요. 그래서 문서관련 기능을...&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Item 5&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;type:&lt;/strong&gt; &lt;a href="http://schema.org/comment"&gt;http://schema.org/comment&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;property:&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;datecreated: 2012-12-22T00:50:28+09:00&lt;/li&gt;
      &lt;li&gt;image: &lt;a href="http://a0.twimg.com/profile_images/2514809179/stcr8k585g4tkcch9pgw_normal.jpeg"&gt;http://a0.twimg.com/profile_images/2514809179/stcr8k585g4tkcch9pgw_normal.jpeg&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;url: &lt;a href="http://twitter.com/nanhapark"&gt;nanhapark&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;name: &lt;a href="http://twitter.com/nanhapark"&gt;nanhapark&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;text: Node.JS용 Scribd 모듈 배포 &lt;a href="http://t.co/qpzDlro0"&gt;http://t.co/qpzDlro0&lt;/a&gt; #nodeqa&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Item 6&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;type:&lt;/strong&gt; &lt;a href="http://schema.org/comment"&gt;http://schema.org/comment&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;property:&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;datecreated: 2012-12-22T01:20:16+09:00&lt;/li&gt;
      &lt;li&gt;image: &lt;a href="http://a0.twimg.com/profile_images/1032276925/imazine_normal.jpg"&gt;http://a0.twimg.com/profile_images/1032276925/imazine_normal.jpg&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;url: &lt;a href="http://twitter.com/iMaZiNe80"&gt;iMaZiNe80&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;name: &lt;a href="http://twitter.com/iMaZiNe80"&gt;iMaZiNe80&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;text: RT @nanhapark: Node.JS용 Scribd 모듈 배포 &lt;a href="http://t.co/qpzDlro0"&gt;http://t.co/qpzDlro0&lt;/a&gt; #nodeqa&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Item 2&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;type:&lt;/strong&gt; &lt;a href="http://schema.org/person"&gt;http://schema.org/person&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;property:&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;image: &lt;a href="http://firejune.com/attach/image/272778.jpeg"&gt;http://firejune.com/attach/image/272778.jpeg&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;name: Joon Kyoung&lt;/li&gt;
      &lt;li&gt;jobtitle: web front-end development&lt;/li&gt;
      &lt;li&gt;worksfor: Spark &amp; Associates Corp&lt;/li&gt;
      &lt;li&gt;url: &lt;a href="http://twitter.com/firejune"&gt;@firejune&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;url: &lt;a href="http://firejune.com/"&gt;Blog&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;url: &lt;a href="http://firejune.com/author"&gt;More information&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;


 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1778#p1778"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1778"&gt;Hits(11697)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/5scidnL4kn4" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1778</feedburner:origLink></entry><entry><title type="text">구글봇이 깨진 링크를 한 달 만에 60만 건 가져가</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/pBjBCQyrU_o/1777" /><category term="블로그" /><category term="자료" /><category term="깨진링크" /><category term="Integrity" /><category term="SEO" /><category term="구글 웹마스터 도구" /><category term="구글봇" /><category term="301 리디렉션" /><category term="새해 복 많이 받으세요." /><author><name>파이어준</name></author><updated>2012-12-31T02:18:46-08:00</updated><id>http://firejune.com/1777</id><content type="html">&lt;p&gt; 구글봇의 크롤 정보가 갱신되는 시간인 오후 한 시가 되면 어김없이 &lt;a href="https://www.google.com/webmasters/tools/home?hl=ko"&gt;구글 웹마스터 도구&lt;/a&gt;에 들어갑니다. 최근 블로그를 리뉴얼 하면서 주소형식이 변경되는 일이 있었습니다. 그래서 이전의 주소로 접근했을 때 올바른 주소로 301 리디렉션하도록 했어요. 그런데 만드는 과정에서의 실수로 잘못된 주소가 대량 방출되었다는 사실을 뒤늦게 알았습니다. 한 달 만에, 무려 60만 건에 달하는 크롤 오류가 감지되었더군요. &lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/1231/121231175010769023/231468.png" width="662" height="402" alt="404.png" class="reflect hasborder"/&gt;&lt;/div&gt;
&lt;p&gt;웹마스터 도구에서 보고한 오류 정보를 토대로 수정 작업을 완료하고 Googlebot에게 이제 다시 크롤해도 좋다고 알려줄 수 있습니다. 그런데 이는 오류 종류(500, 404, 401, 410 등)별로 하루 최대 1,000개이므로 60만 건을 모두 처리하려면 600일이 소요됩니다.(물론, 놔두면 구글봇이 알아서 처리한다고 합니다.) 그런데, 이게 은근 중독성인 게, 마치 롤플레잉 게임에서 몹을 때려잡는 듯한 감칠맛까지 나더라고요.&lt;/p&gt;
&lt;p&gt;구글이 개밥 주듯이 조금씩 내주는 정보에 만족할 수 없어서 사이트 전체의 깨진 링크를 검사해 주는 도구인 &lt;a href="http://peacockmedia.co.uk/integrity/"&gt;Integrity&lt;/a&gt;(맥용)를 이용해서 내부적으로 잘못된 주소가 생성되는지 확인했습니다. 공짜치고는 꽤 쓸만한 도구였어요. 전체 5만 여건의 내부링크가 검색되었는데 그중에서 잘못된 링크를 모두 찾아 고치고 수개월째 경과를 지켜보고 있습니다.&lt;/p&gt;
&lt;p&gt;구글봇이 가져간 크롤오류가 바로잡히는 데에는 생각보다 오랜 시간이 걸렸습니다. 약 3개월에 걸쳐 조금씩 줄어들어 지금은 22만여 건으로 많이 줄어든 상태에요. 기존에 서비스되고 있는 라우트를 건드릴 때에는 정말 조심스럽게 작업에 임해야겠습니다.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1777#p1777"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1777"&gt;Hits(5635)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/pBjBCQyrU_o" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1777</feedburner:origLink></entry><entry><title type="text">Node.JS용 Scribd 모듈 배포</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/DSeIStfW50Q/1776" /><category term="웹개발" /><category term="자료" /><category term="Node.JS" /><category term="Scribd" /><category term="HTML5" /><category term="자바스크립트" /><category term="프로젝트" /><category term="GitHub" /><category term="NPM" /><category term="플래시" /><category term="매시업" /><category term="모듈" /><category term="내가 돈있으면 투자하고 싶은 회사" /><author><name>파이어준</name></author><updated>2012-12-19T06:54:49-08:00</updated><id>http://firejune.com/1776</id><content type="html">&lt;p&gt; 역시나, 기업 요구사항은 파일 교환보다는 문서 관리 쪽으로 많이 치우쳐져 있더군요. 그래서 문서관련 기능을 강화하기 위해 매시업할 수 있는 서비스들을 찾아보던 중 &lt;a href="http://www.scribd.com/"&gt;Scribd&lt;/a&gt;라는 서비스를 알게 되었습니다. 이 서비스는 업로드한 문서를 HTML5(또는 플래시)에서 출력할 수 있도록 컨버전해주는 서비스였습니다. 변환된 문서는 원본 문서와 다른 점을 찾아보기 어려울 정도로 품질이 좋더군요. 그리고 자신들이 가진 기술을 공유에 목적을 두고 마음껏 사용해 주기를 바라는 착한 회사였습니다. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.scribd.com/developers"&gt;Scribd의 API&lt;/a&gt;는 문서를 웹페이지에 임베드하기 위한 &lt;a href="http://www.scribd.com/developers/javascript_api"&gt;자바스크립트 API&lt;/a&gt;와 문서를 등록하거나 메타데이터를 조회하거나 검색 등을 할 수 있는 &lt;a href="http://www.scribd.com/developers/platform"&gt;플랫폼 API&lt;/a&gt;로 나뉩니다. 플랫폼 API에는 Ruby, Java, PHP, Python 등의 라이브러리가 있었지만 아쉽게도 &lt;a href="http://nodejs.org/"&gt;Node.JS&lt;/a&gt;용 라이브러리만 쏙 빠져있어서 래핑 모듈을 만들고 배포합니다. 아래는 &lt;a href="https://github.com/firejune/scribd"&gt;GitHub에 공개&lt;/a&gt;한 scribd 모듈의 API 문서입니다.&lt;/p&gt;
&lt;h3&gt;Scribd Platform API binding for Node.JS&lt;/h3&gt;
&lt;p&gt;Installing:
&lt;pre class="command"&gt;&lt;code class="command"&gt;$ npm install scribd&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Usage:
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;var Scribd = require('scribd');

var key = "ENTER-YOUR-API-KEY-HERE"
  , secret = "ENTER-YOUR-API-SECRET-HERE"; 

var scribd = new Scribd(key, secret);

// or (&amp;gt;= 0.1.5)

var scribd = new Scribd({
    apikey: key
  , secret: secret
});


/**
 * docs.upload
 */

scribd.upload(function(err, res) {
  console.log("\n scribd.upload", err, res);
}, "./my.docx", "doc", "private");

// or (&amp;gt;= 0.1.5)

scribd.upload({
    file: "./my.docx"
  , docType: "doc"
  , access: "private"
}, function(err, res) {
  console.log("\n scribd.upload", err, res);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Methods:
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;/**
 * Docs Method
 */

// docs.upload (callback, file, [docType], [access], [revId])
scribd.upload(function(err, res) {
  console.log('\n scribd.upload', err, res);
}, './document.path');

// docs.uploadFromUrl (callback, url, [docType], [access], [revId])
scribd.uploadFromUrl(function(err, res) {
  console.log('\n scribd.uploadFromUrl', err, res);
}, 'url');

// docs.getList (callback)
scribd.getList(function(err, res) {
  console.log('\n scribd.getList', err, res);
});

// docs.getConversionStatus (callback, docId)
scribd.getConversionStatus(function(err, res) {
  console.log('\n scribd.getConversionStatus', err, res);
}, 'docId');

// docs.getSettings (callback, docId)
scribd.getSettings(function(err, res) {
  console.log('\n scribd.getSettings', err, res);
}, 'docId');

// docs.changeSettings (callback, docId, [title], [description], [access], [license], [showAds], [tags])
scribd.changeSettings(function(err, res) {
  console.log('\n scribd.changeSettings', err, res);
}, 'docId', 'title');

// docs.getDownloadUrl (callback, docId)
scribd.getDownloadUrl(function(err, res) {
  console.log('\n scribd.getDownloadUrl', err, res);
}, 'docId');

// docs.getStats (callback, docId)
scribd.getStats(function(err, res) {
  console.log('\n scribd.getStats', err, res);
}, 'docId');

// docs.delete (callback, docId)
scribd.delete(function(err, res) {
  console.log('\n scribd.remove', err, res);
}, 'docId');

// docs.search (callback, query, [numResults], [numStart], [scope])
scribd.search(function(err, res) {
  console.log('\n scribd.search', err, res);
}, 'Node.JS', 1);

// docs.getCategories (callback, docId)
scribd.getCategories(function(err, res) {
  console.log('\n scribd.getCategories', err, res);
}, 'docId');

// docs.featured (callback, [limit], [offset], [scope])
scribd.featured(function(err, res) {
  console.log('\n scribd.featured', err, res);
});

// docs.browse (callback, [limit], [offset], [categoryId], [sort])
scribd.browse(function(err, res) {
  console.log('\n scribd.browse', err, res);
});

// docs.uploadThumb (callback, file, docId)
scribd.uploadThumb(function(err, res) {
  console.log('\n scribd.uploadThumb', err, res);
}, 'thumbnail.path', 'docId');


/**
 * Thumbnail Method
 */

// thumbnail.get (callback, docId, [width], [height])
scribd.getThumbnail(function(err, res) {
  console.log('\n scribd.getThumbnail', err, res);
}, 'docId', 256);


/**
 * User Method
 */

// user.login (callback, username, password)
scribd.login(function(err, res) {
  console.log('\n scribd.login', err, res);
}, 'username', 'password');

// user.signup (callback, username, password, email, [name])
scribd.signup(function(err, res) {
  console.log('\n scribd.signup', err, res);
}, 'username', 'password', 'email', 'name');

// user.getAutoSigninUrl (callback, [nextUrl])
scribd.getAutoSigninUrl(function(err, res) {
  console.log('\n scribd.getAutoSigninUrl', err, res);
}, '/');&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
&lt;h3&gt;License&lt;/h3&gt;
&lt;p&gt;MIT &amp;lt;3&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1776#p1776"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1776"&gt;Hits(11999)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/DSeIStfW50Q" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1776</feedburner:origLink></entry><entry><title type="text">CodeMirror 3으로 업그레이드하기</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/QXi8MKYtjWQ/1775" /><category term="웹개발" /><category term="자료" /><category term="CodeMirror" /><category term="자바스크립트" /><category term="편집기" /><category term="에디터" /><category term="JSBin" /><category term="CSS" /><author><name>파이어준</name></author><updated>2012-12-11T10:54:36-08:00</updated><id>http://firejune.com/1775</id><content type="html">&lt;p&gt; &lt;a href="http://codemirror.net/"&gt;CodeMirror&lt;/a&gt;는 웹 브라우저에서 코드 편집 기능을 제공할 수 있게 하는 자바스크립트 컴포넌트입니다. 자바스크립트, CSS, HTML은 물론 C, Java, PHP, Python, Ruby 등 50여 종의 언어 모드(Mode)를 지원하며, 문법 강조, 단축키, 자동포맷, 코드 폴딩, 테마, 검색 및 바꾸기 등의 유틸리티를 제공합니다. &lt;a href="http://jsbin.com/"&gt;JSBin&lt;/a&gt;, &lt;a href="https://script.google.com/"&gt;Google Apps Script&lt;/a&gt;, &lt;a href="http://media.chikuyonok.ru/codemirror2/"&gt;Zen Coding&lt;/a&gt;등의 사이트에서 CodeMirror를 이용하여 코드 편집 기능을 제공하고 있습니다. JSBin을 포크 해서 고쳐 사용 중인 &lt;a href="http://jsbin.firejune.com"&gt;FireJSBin&lt;/a&gt;(코드네임)의 라이브러리를 업데이트하려다가 CodeMirror 3의 정식 버전이 최근에 릴리즈되었다는 사실을 알게 되었습니다. 그래서 버전 2.x에 비해 어떤 점들이 달라지고 어떻게 업그레이드하는지 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;CodeMirror 버전 3은 2.x의 API에서 크게 벗어나지 않았습니다. 단순한 방법으로 CodeMirror를 이용한 사이트는 별다른 문제 없이 업그레이드할 수 있습니다. 애석하게도 버전 3부터는 인터넷 익스플로러 7을 완전히 지원하는 것을 포기합니다. IE7을 지원하는 코드들이 효율성을 떨어트리기 때문일까요? 아무튼, 그렇습니다.&lt;/p&gt;
&lt;h3&gt;DOM structure&lt;/h3&gt;
&lt;p&gt;편집기 내부에 사용되는 새로운 스크롤링 모델을 구현하기 위해 꽤 많은 DOM 구조가 변경되었습니다. 그래서 codemirror.css를 변경해서 사용하는 경우에는 문제를 일으킬 가능성이 큽니다. 편집기의 높이를 처리하는 요소가 스크롤러 요소(CSS class &lt;code&gt;CodeMirror-scroll&lt;/code&gt;)에서 래퍼(Wrapper) 요소(CSS class &lt;code&gt;CodeMirror&lt;/code&gt;)로 변경되었습니다. 그 외 다른 요소들이 이동되거나 제거되었고 추가되었습니다. 만약 편집기 내부의 DOM 요소를 제어하는 코드를 작성했다면 버전 3에서는 그 코드들을 다시 테스트해야 할 것입니다. CodeMirror 메뉴얼의 &lt;a href="http://codemirror.net/doc/manual.html#styling"&gt;스타일링 섹션&lt;/a&gt;에서 더 많은 정보를 얻을 수 있습니다.&lt;/p&gt;
&lt;h3&gt;Gutter model&lt;/h3&gt;
&lt;p&gt;CodeMirror 2.x에서는 싱글 거터(Gutter, 라인 넘버가 출력되는 영역)만 제공되어 라인을 마킹하거나 할 때 좁은 공간에 줄 번호를 비롯한 추가적인 정보가 공존해야 했었지만, 버전 3부터는 거터를 클래스네임의 배열로 지정함으로써 복수로 사용할 수 있게 되었습니다. &lt;code&gt;setGutterMarker&lt;/code&gt;, &lt;code&gt;clearGutter&lt;/code&gt; 등의 추가적인 메서드를 이용하여 거터단위 마커를 추가 및 제거할 수 있고, HTML 스니펫이 아닌 DOM 노드로 지정됩니다.&lt;/p&gt;
&lt;p&gt;수평으로 스크롤할 때 거터가 들쭉날쭉하는 문제가 사라졌으며, &lt;code&gt;fixedGutter&lt;/code&gt; 옵션은 삭제되었습니다.&lt;/p&gt;
&lt;pre class="htlm"&gt;&lt;code class="htlm"&gt;&amp;lt;style&amp;gt;
  /* Define a gutter style */
  .note-gutter { width: 3em; background: cyan; }
&amp;lt;/style&amp;gt;
&amp;lt;script&amp;gt;
  // Create an instance with two gutters -- line numbers and notes
  var cm = new CodeMirror(document.body, {
    gutters: ["note-gutter", "CodeMirror-linenumbers"],
    lineNumbers: true
  });
  // Add a note to line 0
  cm.setGutterMarker(0, "note-gutter", document.createTextNode("hi"));
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Event handling&lt;/h3&gt;
&lt;p&gt;onXYZ 옵션이 대부분 삭제되었습니다. 같은 효과로 이벤트 유형을 식별하는 문자열에서 입수할 수 있습니다. 여러 개의 핸들러를 하나의 이벤트에 할당합니다. 이러한 방식으로 라인 핸들러는 더 쉽게 이벤트를 받습니다. &lt;code&gt;onKeyEvent&lt;/code&gt;와 &lt;code&gt;onDragEvent&lt;/code&gt; 옵션은 이벤트 핸들러를 후크하는 방식으로 작동하며 이전과 마찬가지로 사용할 수 있습니다.
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;cm.on("change", function(cm, change) {
  console.log("something changed! (" + change.origin + ")");
});&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;markText method arguments&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://codemirror.net/doc/manual.html#markText"&gt;&lt;code&gt;markText&lt;/code&gt;&lt;/a&gt; 메서드는 이제 CSS 클래스명을 인자로 받지 않습니다. 이것은 선택 옵션이며, 옵션 개체를 통하여 전달할 수 있습니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;// Style first ten lines, and forbid the cursor from entering them
cm.markText({line: 0, ch: 0}, {line: 10, ch: 0}, {
  className: "magic-text",
  inclusiveLeft: true,
  atomic: true
});&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Line folding&lt;/h3&gt;
&lt;p&gt;라인을 숨기는 인터페이스가 제거되었습니다. &lt;code&gt;markText&lt;/code&gt;를 이용하여 지금보다 더 유연하고 강력한 방법으로 동일한 작업을 수행하는 데 사용할 수 있습니다. 폴딩 스크립트는 새로운 인터페이스를 사용되도록 견고하게 업데이트되었습니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;// Fold a range, replacing it with the text "??"
var range = cm.markText({line: 4, ch: 2}, {line: 8, ch: 1}, {
  replacedWith: document.createTextNode("??"),
  // Auto-unfold when cursor moves into the range
  clearOnEnter: true
});
// Get notified when auto-unfolding
CodeMirror.on(range, "clear", function() {
  console.log("boom");
});&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Line CSS classes&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;setLineClass&lt;/code&gt; 메서드는 &lt;code&gt;addLineClass&lt;/code&gt;과 &lt;code&gt;removeLineClass&lt;/code&gt;으로 대체되었습니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;var marked = cm.addLineClass(10, "background", "highlighted-line");
setTimeout(function() {
  cm.removeLineClass(marked, "background", "highlighted-line");
});&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Position Properties&lt;/h3&gt;
&lt;p&gt;모든 포지션 메서드는 화면에 표시하는 위치 개체를 반환합니다. &lt;code&gt;{left, top, bottom, right}&lt;/code&gt; 속성을 항상 사용할 수 있으며, 버전 2.x에서 사용하던 &lt;code&gt;{x, y, yBot}&lt;/code&gt; 속성을 사용하고 있다면 수정해야 합니다. 포지션 속성을 반환하는 메서드는 &lt;a href="http://codemirror.net/doc/manual.html#cursorCoords"&gt;&lt;code&gt;cursorCoords&lt;/code&gt;&lt;/a&gt;, &lt;a href="http://codemirror.net/doc/manual.html#charCoords"&gt;&lt;code&gt;charCoords&lt;/code&gt;&lt;/a&gt;, &lt;a href="http://codemirror.net/doc/manual.html#coordsChar"&gt;&lt;code&gt;coordsChar&lt;/code&gt;&lt;/a&gt; 그리고 &lt;a href="http://codemirror.net/doc/manual.html#getScrollInfo"&gt;&lt;code&gt;getScrollInfo&lt;/code&gt;&lt;/a&gt; 입니다.&lt;/p&gt;
&lt;h3&gt;Bracket matching no longer in core&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://codemirror.net/doc/manual.html#util_matchbrackets"&gt;&lt;code&gt;matchBrackets&lt;/code&gt;&lt;/a&gt; 옵션은 이제 코어 에디터에 정의되지 않으며 &lt;code&gt;lib/util/matchbrackets.js&lt;/code&gt;를 로드합니다.&lt;/p&gt;
&lt;h3&gt;Mode management&lt;/h3&gt;
&lt;p&gt; 정의된 모드(Mode)의 목록을 반환하던 &lt;code&gt;CodeMirror.listModes&lt;/code&gt;와 &lt;code&gt;CodeMirror.listMIMEs&lt;/code&gt; 함수는 이제 없어졌습니다. 대신 &lt;code&gt;CodeMirror.modes&lt;/code&gt;와 &lt;code&gt;CodeMirror.mimeModes&lt;/code&gt;로 간단하게 확인할 수 있습니다.&lt;/p&gt;
&lt;h3&gt;New features&lt;/h3&gt;
&lt;p&gt;버전 3으로 업그레이드하면 다음과 같은 이점이 있습니다.&lt;/p&gt;
&lt;ul class="square"&gt;
&lt;li&gt;양 방향(Bi-directional) 텍스트 지원, 아랍어 또는 히브리어 텍스트를 편집할 수 있습니다.&lt;/li&gt;
&lt;li&gt;임의의 행 높이 처리, 에디터 내부에서 높이가 서로다른 글꼴이 사용되는 경우 이제 우아하게 처리합니다.&lt;/li&gt;
&lt;li&gt;인라인-위젯 지원, 이 &lt;a href="http://codemirror.net/demo/widget.html"&gt;데모&lt;/a&gt;와 &lt;a href="http://codemirror.net/doc/manual.html#addLineWidget"&gt;문서&lt;/a&gt;를 참고하세요.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CodeMirror.defineOption&lt;/code&gt;으로 사용자 정의 옵션을 지정할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이상으로 CodeMirror 버전 3으로의 업그래이드 방법에 대하여 알아보았습니다. 스크롤이 수평으로 이동할때 거터가 들락날락하는 현상이 수정된 거 빼고는 그리 업그레이드의 필요성을 못느끼겠네요. 아랍어를 다룰것도 아니고; 이 기존 2.x 버전은 버그를 수정하는 수준으로 업데이트가 이루어 진다고 하니, 너무 성급하게 3으로 갈아탈 필요는 없어 보입니다.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1775#p1775"&gt;Comments(1)&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1775"&gt;Hits(11302)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/QXi8MKYtjWQ" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1775</feedburner:origLink></entry><entry><title type="text">Analytics 자바스크립트 페이지 트래킹</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/HC9MvD3zDlA/1774" /><category term="웹개발" /><category term="자료" /><category term="Analytics" /><category term="자바스크립트" /><category term="페이지" /><category term="타이틀" /><category term="트래킹" /><category term="SEO" /><author><name>파이어준</name></author><updated>2012-12-09T08:21:34-08:00</updated><id>http://firejune.com/1774</id><content type="html">&lt;p&gt; &lt;a href="https://www.google.com/analytics"&gt;Google Analytics&lt;/a&gt;에서 제공하는 기본 트래킹 코드는 정적인 페이지에서 사용하기 적합하며 Ajax나 &lt;a href="https://developer.mozilla.org/en-US/docs/DOM/window.onpopstate"&gt;history. pushState&lt;/a&gt;를 이용하여 컨텐츠를 갱신하는 동적인 사이트는 필요한 경우 추가적인 작업을 해야 합니다. Analytics는 페이지의 이동 경로와 이벤트 등을 추적할 수 있는 자바스크립트로 작성된 &lt;a href="https://developers.google.com/analytics/devguides/collection/gajs/"&gt;오픈 API&lt;/a&gt;를 제공합니다. API를 이용하는 방법은 크게 두 가지로 구분할 수 있는데 &lt;code&gt;_gaq.push&lt;/code&gt;로 호출할 메서드와 값을 전달하는 방법과 &lt;code&gt;_gat._getTracker&lt;/code&gt;에서 반환하는 인스턴트의 &lt;code&gt;_trackPageview&lt;/code&gt; 메서드를 호출하는 방법입니다. 이 API를 Ajax에 응용한 예제는 다음과 같습니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;// _gaq.push
$.ajax({
  url: "/some.html",
  context: document.body,
  success: function(){
    _gaq.push(['_trackPageview', '/some.html']);
  }
});

// or

// _gat._getTracker
var pageTracker = _gat._getTracker('UA-XXXXX-X');
$.ajax({
  url: "/some.html",
  context: document.body,
  success: function(){
    pageTracker._trackPageview('/some.html');
  }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;두 방법 모두 같은 결과를 보입니다. 자바스크립트를 이용하여 트래킹하는 경우에 주의해야 할 점 역시 두가지 입니다. &lt;code&gt;_trackPageview&lt;/code&gt;는 자동으로 호스트 네임을 걸러주지 않기 때문에 인자로 입력되는 주소는 호스트 정보가 빠진 경로만을 입력해야 합니다. 그리고 페이지 타이틀을 갱신해야 합니다. 그렇지 않으면 Analytics의 페이지 제목 분석기능을 제대로 활용할 수 없게 됩니다. 예를 들어 첫 페이지의 타이틀이 'firejune.com'이면 비동기로 갱신되어 Analytics에 기록된 페이지들이 모두 'firejune.com'이란 타이틀을 가지게 되기 때문이죠. &lt;code&gt;'_trackPageview'&lt;/code&gt; 함수는 단순히 &lt;code&gt;document.title&lt;/code&gt;의 값을 기록하죠. 다음은 간단한 실용 예를 작성한 것입니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;var pageTracker = _gat._getTracker('UA-XXXXX-X');
function trackPageview(url, title) {
    url = url.replace(location.protocol + '//' + location.host, '');
    document.title = document.title.split(' : ')[0] + (title &amp;amp;&amp;amp; ' : ' + title || '');
    pageTracker._trackPageview(url);
}

function updatePage(el) {
  $.ajax({
    url: el.href,
    context: document.body,
    success: function(){
      trackPageview(el.href, el.innerHTML);
    }
  });
  return false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="html"&gt;&lt;code class="html"&gt;&amp;lt;a href="/some.html" onclick="return updatePage(this);"&amp;gt;Some HTML&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;최근 작업 중인 &lt;a href="http://firejune.com/1771/The+Velox+%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8+%EA%B3%B5%EA%B0%9C+%EA%B7%B8%EB%A6%AC%EA%B3%A0+%ED%81%B4%EB%A1%9C%EC%A6%88+%EB%B2%A0%ED%83%80"&gt;벨록스 프로젝트&lt;/a&gt;는 애플리케이션 레이아웃이어서 패널과 다이얼로그를 이용하여 컨텐츠를 갱신하기 때문에 다른 방식으로 사용자의 행동을 추적해야 할 필요가 있었습니다. 그래서 속성 편집 패널을 열면, 기존 &lt;code&gt;document.title&lt;/code&gt;에 추가로 컨트롤러/액션(&lt;code&gt;' : /files/edit'&lt;/code&gt;) 이름을 더하여 Analytics에 기록한 후 원래대로 돌리는 방식으로 데이터를 쌓음으로써 사용자의 이동 경로를 조금 더 세밀하게 파악할 수 있었습니다.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1774#p1774"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1774"&gt;Hits(11907)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/HC9MvD3zDlA" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1774</feedburner:origLink></entry><entry><title type="text">MongoDB용 ObjectID의 길이 줄이기</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/9hceRBvGWyo/1773" /><category term="웹개발" /><category term="자료" /><category term="MongoDB" /><category term="ObjectID" /><category term="자바스크립트" /><category term="NodeJS" /><category term="Shorten" /><category term="BSON" /><category term="ExpressJS" /><category term="HEX" /><category term="RaailwayJS" /><category term="Base64" /><category term="인코딩" /><category term="디코딩" /><category term="Base64ID" /><author><name>파이어준</name></author><updated>2012-12-01T20:41:24-08:00</updated><id>http://firejune.com/1773</id><content type="html">&lt;p&gt; &lt;a href="http://www.mongodb.org/display/DOCS/Object+IDs"&gt;MongoDB의 ObjectID&lt;/a&gt;는 12바이트짜리 BSON타입 UUID를 사용합니다. 4-byte timestamp, 3-byte machine identifier, 2-byte process id, 그리고 3-byte counter로 구성되어 합이 12바이트인 것입니다. 데이터를 쓰기도 전에 ID를 생성하며 ID만으로 타임스탬프를를 뽑아낼 수도 있지요. 그런데 이 ID를 문자로 반환하면 무려 24자 길이의 HEX 스트링이 &lt;code&gt;"50812452a46e98744d000003"&lt;/code&gt; 요렇게 튀어나옵니다. 이 ID를 각종 파라메터나 URL에 사용하고 있는데 너무 길어서 좀 예쁘게 줄일 방법이 없나 싶어 찾아봤더니 &lt;a href="http://ko.wikipedia.org/wiki/%EB%B2%A0%EC%9D%B4%EC%8A%A464"&gt;Base64&lt;/a&gt; 인코딩을 이용하여 &lt;code&gt;"UIjDaeXm18RLAAAD"&lt;/code&gt; 처럼 반 토막으로 &lt;a href="http://sebastian.formzoo.com/2012/04/12/mongodb-shorten-the-objectid/"&gt;축소할 수 있는 방법&lt;/a&gt;이 있어 소개합니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;module.exports = {
  _encodeBase64ID: function(id) {
    return
      id &amp;amp;&amp;amp; new Buffer(id.toString(), 'hex')
        .toString('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_') || id;
  },
  _decodeBase64ID: function(id) {
    return
      id &amp;amp;&amp;amp; new Buffer(id
        .replace(/-/g, '+')
        .replace(/_/g, '/')
        , 'base64').toString('hex') || id;
  },
  ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://expressjs.com/"&gt;ExpressJS&lt;/a&gt;에서 위 두 함수를 이용하여 ObjectID를 Base64ID로 인코딩/디코딩 할 수 있습니다. 일단은 Helper 모듈로 만들어 가시적으로 노출되는 라우트와 컨트롤러에서만 호출하는 식으로 사용하고 있는데 포스트를 작성하면서 곰곰이 생각해 보니, 익스프레스용 미들웨어로 작성하기에 아주 적합하다는 생각이 드는군요. 라우팅 정보에서 &lt;code&gt;req.params&lt;/code&gt; 키를 추출하여 값을 치환해 주면 되는 간단한 일이잖아요. 말이 나온 김에 지금 작성해 보겠습니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;/*!
 * Middleware - ObjectID parsor:
 * Joon Kyoung(@firejune)
 * Copyright(c) 2012 Spark &amp;amp; Associates Inc.
 * MIT Licensed
 */

exports.objectIDParser = function() {
  var parse = require('url').parse;

  /**
   * Attempt to match the given params to one of the routes.
   */
  function match(req, routes) {
    var params = {}
      , method = req.method
      , captures
      , i = 0;
  
    if ('HEAD' == method) method = 'GET';
    if (routes = routes[method.toLowerCase()]) {
      var pathname = parse(req.url).pathname;
      for (var len = routes.length; i &amp;lt; len; ++i) {
        var route = routes[i]
          , keys = route.keys
          , path = route.regexp
          , params = [];

        if (captures = path.exec(pathname)) {
          for (var j = 1, len = captures.length; j &amp;lt; len; ++j) {
            var key = keys[j - 1]
              , val = typeof captures[j] === 'string'
                ? decodeURIComponent(captures[j])
                : captures[j];

            if (key) {
              params[key.name] = val;
            } else {
              params.push(val);
            }
          }
          return params;
        }
      }
    }
    return params;
  }

  /**
   *  Parse Base64ID to ObjectID in request params,
   *  providing the parsed object as `params.uuid`.
   */
  return function objectIDParser(req, res, next) {
    if (req._body) return next();

    var routes = req.app.routes.routes
      , params = match(req, routes);

    // uuid in params
    if (!params.uuid) return next();      

    // flag as parsed
    req._body = true;

    // current uuid
    if (24 &amp;lt;= params.uuid.length) {
      console.warn('Deprecated parameter type ObjectID is now using base64ID');
    } else {
      // decode to hex
      params.uuid = new Buffer(params.uuid.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('hex');
      Object.defineProperty(req, "params", {value: params, writable: false});
    }

    next();
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;생각처럼 쉬운 일이 아니었습니다. 몇 시간을 삽질했어요. &lt;code&gt;req.url&lt;/code&gt; 파싱해서 라우트 룰을 모두 뒤져 찾아내고 거기서 찾은 정규식을 또다시 &lt;code&gt;req.url&lt;/code&gt;에 대입하여 &lt;code&gt;req.params&lt;/code&gt; 값을 뽑아내야 했어요. &lt;code&gt;req.app.routes&lt;/code&gt;에는 이미 &lt;code&gt;req.params&lt;/code&gt; 값들이 할당되어 있었지만 업데이트되는 시점은 &lt;code&gt;app.route&lt;/code&gt;가 호출되는 가장 마지막이기 때문에 미들웨어에서 찾을 수 있는 정보는 이전 라우트에서 사용했던 거였죠. 또 다른 문제는 &lt;code&gt;req.params&lt;/code&gt; 값도 전달이 안 된다는 거에요. 익스프레스가 &lt;code&gt;app.route&lt;/code&gt;를 처리되면서 리플레이스해 버립니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;app.configure('development', function() {
  app.use(express.static(process.cwd() + '/public', {maxAge: 86400000}));
  app.use(middleware.objectIDParser());
  app.use(middleware.octetStream({tempDir: process.cwd() + '/temp/'}));
  app.use(express.bodyParser());
  app.use(express.cookieParser('fire*une'));
  app.use(express.session({secret: 'fire*une'}));
  app.use(express.methodOverride());
  app.use(app.router);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;일단, 익스프레스에서 라우트를 비교하는 로직을 가져올 필요가 있어서 소스코드를 몽창 뒤져 &lt;code&gt;match&lt;/code&gt;라는 함수를 발견하고 땡겨와 약간 수정했습니다. 그리고 아까 배운 &lt;code&gt;Object.defineProperty&lt;/code&gt;로 속성을 변경할 수 없게 만들어버렸더니 잘 전달 되더라고요! 단, 주의할 점은 익스프레스가 &lt;code&gt;req.params&lt;/code&gt; 속성을 변경 할 수 없는 상태가 돼 버리므로 이 단계에서 완성해야 합니다. 자~ 이제 라우팅 룰에 &lt;code&gt;":uuid"&lt;/code&gt;로 키만 설정하면 미들웨어에 의해 올바른 ObjectID로 자동 치환되어 컨트롤러에 전달됩니다. 아, 왠지 뿌듯하네요! &lt;a href="https://thevelox.com"&gt;thevelox.com&lt;/a&gt;에 바로 적용했습니다.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1773#p1773"&gt;Comments(1)&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1773"&gt;Hits(11645)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/9hceRBvGWyo" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1773</feedburner:origLink></entry><entry><title type="text">자바스크립트 1.8.5(ES5)의 새 기능</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/v5CghXOPsuo/1772" /><category term="웹개발" /><category term="자료" /><category term="자바스크립트" /><category term="ES5" /><category term="JavaScript 1.8.x" /><category term="ES5-Shim" /><category term="ECMAScript" /><category term="Polyfill" /><category term="Shim" /><author><name>파이어준</name></author><updated>2012-12-01T09:51:51-08:00</updated><id>http://firejune.com/1772</id><content type="html">&lt;p&gt; 신경 안 쓰는 사이에 &lt;a href="http://kangax.github.com/es5-compat-table/"&gt;거의 모든 브라우저가 ECMAScript 5를 지원&lt;/a&gt;하게 되는 황금기를 맞는군요. &lt;a href="http://www.nodejs.org/"&gt;NodeJS&lt;/a&gt;에서 다른 사람이 짠 코드를 참고할 때 종종 보이던 ES5의 새 기능을 눈여겨 두었다가 드문드문 써먹곤 했었는데 이제 정말로 깨우치고 사용해야 할 시기라는 생각이 듭니다. 다음은 &lt;a href="https://developer.mozilla.org/ko/"&gt;MDN&lt;/a&gt;에서 퍼온 자바스크립트 1.8에서 추가된 기능과 설명입니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;/* Object */
Object.create // Creates a new object with the specified prototype object and properties.
Object.defineProperty // Adds the named property described by a given descriptor to an object.
Object.defineProperties // Adds the named properties described by the given descriptors to an object.
Object.getPrototypeOf // Returns a property descriptor for a named property on an object. 
Object.keys // Returns an array of all enumerable properties on an object.
Object.preventExtensions // Prevents any extensions of an object.
Object.seal // Prevents other code from deleting properties of an object.
Object.isSealed // Determine if an object is sealed.
Object.freeze // Freezes an object: other code can't delete or change any properties.
Object.isFrozen // Determine if an object was frozen. 
Object.isExtensible // Determine if extending of an object is allowed.
Object.getOwnPropertyDescriptor //Returns a property descriptor for an own property of a given object.
Object.getOwnPropertyNames // Returns an array of all enumerable and non-enumerable properties on an object.

/* Array */
Array.isArray // Checks if a variable is an array. 
Array.prototype.indexOf // Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found.
Array.prototype.lastIndexOf // Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found.
Array.prototype.every // Returns true if every element in this array satisfies the provided testing function.
Array.prototype.some // Returns true if at least one element in this array satisfies the provided testing function.
Array.prototype.forEach // Calls a function for each element in the array.
Array.prototype.map // Creates a new array with the results of calling a provided function on every element in this array.
Array.prototype.filter // Creates a new array with all of the elements of this array for which the provided filtering function returns true.
Array.prototype.reduce // Apply a function simultaneously against two values of the array (from left-to-right) as to reduce it to a single value.
Array.prototype.reduceRight // Apply a function simultaneously against two values of the array (from right-to-left) as to reduce it to a single value.

/* More */
Function.prototype.bind // Creates a new function that, when called, itself calls this function in the context provided 
String.prototype.trim // Removes whitespace from both ends of the string.
Date.prototype.toJSON // Returns a string encapsulating the Date object in JSON format.
Date.prototype.toISOString // JavaScript provides a direct way to convert a date object into a string in ISO format.
Date.now // Returns the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.
"use strict" // strict mode support&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Object&lt;/code&gt;와 &lt;code&gt;Array.prototype&lt;/code&gt;에 새로운 기능들이 대거 추가되었습니다. 특히, &lt;code&gt;Object.keys&lt;/code&gt;는 정말 유용하게 사용될 거 같습니다. 인자로 받은 options을 default options과 머지할 때 아주 유용하겠네요. 자바스크립트는 배열과 관련된 메서드들이 정말 부실했었는데, &lt;code&gt;indexOf&lt;/code&gt;, &lt;code&gt;forEach&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, &lt;code&gt;some&lt;/code&gt; 등 전부 요긴하게 사용할 수 있는 녀석들이 뭉탱이로 들어와 있습니다. 또한 &lt;code&gt; Function.prototype.bind&lt;/code&gt;이 추가되어 별다른 트릭없이 선호하는 문법을 구사할 수 있게 되었습니다. 아무리 생각해도 &lt;code&gt;var self = this&lt;/code&gt;와 같은 문장은 언어적 결함으로밖에 보이지 않거든요. 다음은 자주 사용될 것 같은 코드 스니펫들입니다.&lt;/p&gt;
&lt;pre class="javascript"&gt;&lt;code class="javascript"&gt;/* Basic Class */
var book={ title: 'default',  author: 'default' };
var techBook=Object.create(book, {category: {value: 'technology'}});
techBook.category; //=&amp;gt; technology
Object.defineProperty(techBook, "category", {value: 'javascript'});
techBook.category; //=&amp;gt; javascript

/* Mixin Class */ 
function MyClass() {
    SuperClass.call(this);
    OtherSuperClass.call(this);
}

MyClass.prototype = Object.create(SuperClass.prototype); //inherit
mixin(MyClass.prototype, OtherSuperClass.prototype); //mixin

MyClass.prototype.myMethod = function() {
    // do a thing
};

/* Object extend */
Object.keys(options).forEach(function(key){
    form[key] = options[key];
});

/* Getter/Setter */
var myObject = {};
Object.defineProperty( myObject, '_myProp', {
    value:          'myDefault',
    writable:       false,
    enumberable:    false,
    configurable:   true
});

Object.defineProperty( myObject, 'myProp', {
    enumberable: true,
    configurable: true,
    set: function( v ) {
        Object.defineProperty( this, '_myProp', { writable:true } );
        this._myProp = v;
        Object.defineProperty( this, '_myProp', { writable:false } );
    },
    get: function() {
        return this._myProp;
    }
});
 
alert( myObject.myProp );
myObject.myProp = 'myValue';
alert( myObject.myProp );
myObject._myProp = 'teehee, not writable';
alert( myObject._myProp );

/* non-writable */
var o = {}; // Creates a new object
Object.defineProperty(o, "a", { value : 37, writable : false });
o.a = 25; // No error thrown (it would throw in strict mode)
o.a //=&amp;gt; 37

/* Fu*k self */
function LateBloomer() {
    this.petalCount = Math.ceil( Math.random() * 12 ) + 1;
}

// declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
    window.setTimeout( this.declare.bind( this ), 1000 );
};

LateBloomer.prototype.declare = function() {
    console.log('I am a beautiful flower with ' + this.petalCount + ' petals!');
};

/* ISODateString */
new Date().toISOString() //=&amp;gt; "2012-12-01T20:24:27.681Z"

/* Real trim */
"   _firejune   ".trim() //=&amp;gt; "_firejune"
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;하위 호환을 위한 폴리필(Polyfill) 라이브러리로는 &lt;a href="https://github.com/kriskowal/es5-shim/"&gt;ES5-Shim&lt;/a&gt;이 대세인 듯 합니다.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1772#p1772"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1772"&gt;Hits(8931)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/v5CghXOPsuo" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1772</feedburner:origLink></entry><entry><title type="text">The Velox 프로젝트 공개 그리고 클로즈 베타</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/f37Rx0cv4to/1771" /><category term="웹개발" /><category term="자료" /><category term="클라우드" /><category term="드랍박스" /><category term="벨록스" /><category term="프로젝트" /><category term="자바스크립트" /><category term="NodeJS" /><category term="MongoDB" /><category term="Redis" /><category term="RailwayJS" /><category term="SocketIO" /><category term="HTML5" /><category term="CSS3" /><category term="iOS" /><category term="Cluster" /><category term="Swift" /><category term="L10n" /><category term="태그필터" /><category term="ExpressJS" /><category term="NginX" /><category term="WebSocket" /><category term="Splunk" /><category term="Velox" /><category term="thevelox.com" /><category term="GitHub" /><category term="Keystone" /><category term="File API" /><category term="MongooseJS" /><category term="서비스" /><author><name>파이어준</name></author><updated>2012-11-26T08:12:03-08:00</updated><id>http://firejune.com/1771</id><content type="html">&lt;p&gt; 입사 후 처음으로 수행한 웹 프로젝트가 1년만에 슬슬 마무리 단계에 접어들고 있습니다. 개발자라고는 저 혼자인 상황에서 막연하게 시작했던 프로젝트입니다. 백-엔드 개발자 뽑느라고 4개월 허송세월 보내고, 중간에 다른 프로젝트 한다고 서너달 접어두기도 했었습니다. 이제 그 모습을 여기에 공개해 보겠습니다.&lt;/p&gt;
&lt;p&gt;프로젝트 코드명은 벨록스(Velox)입니다. 도메인이 준비되는 바람에 제품명으로 굳혀지고 있는 듯한 모습입니다. 벨록스는 &lt;a href="https://www.dropbox.com/"&gt;드랍박스&lt;/a&gt;, &lt;a href="https://drive.google.com/"&gt;구글 드라이브&lt;/a&gt;와 유사한 온라인 파일 관리 도구이며 기업에 사용하기에 적당한 구조를 가진 솔루션으로 개발되었습니다. 본격적으로 개발에 착수 할 때 즈음 몇몇 중견 기업의 파일 관리 실태를 사전조사 했었는데, 내부인과 외부인이 보안성 파일을 교환하는데 문제가 가장 심각한 것으로 드러났습니다. 그리고 우리에게 매우 친숙한 폴더 하이어라키 파일 시스템은 사실, 사람보다는 기계에 더 친숙한 것입니다. 나중에 파일들이 많아지게 되면 자신의 파일이 어디에 쳐박혀 있는지도 모르고, 이력도 없고, 심지어 복사본인지 원본인지도 모르는 경우가 상당수여서 뭔가 다른 관리 방법이 필요하다는 생각이 들었습니다. 뭐, 기본적인 보안이야 당연한 거니까 생략할께요.&lt;/p&gt;
&lt;p&gt;
  &lt;div id="gallery17562" class="g_container" style="width:px;height:px;"&gt;
    &lt;img src="http://firejune.cdn2.cafe24.com/attach/1126/121126200035496502/927317.png" width="" height="" id="g_img17562_0" alt="attachment"/&gt;
  &lt;/div&gt;
  &lt;div class="cap1" id="scap17562"&gt;공유 탭과 계정 헤더, 영역별 도구바, 태그 사이드바 그리고 파일 브라우저 영역으로 구분된 레이아웃&lt;/div&gt;
  
&lt;br&gt;
벨록스의 주요기능이 담긴 스크린샷과 설명입니다. 기능을 줄줄이 읇자면 너무 지루해지므로 요지만 간략하게 말씀드리겠습니다. 폴더를 대체하기 위해 강력한 태그 필터링 기능을 넣자고 박박 우겨서 허락도 안 받고 만들어버렸습니다. 벨록스의 태그 필터는 시스템이 스스로 분석하여 자동으로 할당해 주는 자동 태그와 사용자들이 입력한 사용자 태그로 구분됩니다. 한 폴더에 파일의 종류에 상관없이 몽창 때려넣고 태그 필터와 검색 필터를 AND 연산으로 데이터 출력 범위를 좁히는 것이지요. &lt;a href="http://www.apple.com/kr/ilife/iphoto/"&gt;아이포토 &lt;/a&gt;처럼요. 휴지통 태그는 조금 특수한 것으로 삭제된 파일들에 입혀집니다. 이 태그가 활성화되면, 지워진 녀석들만 나타나게 되고, 도구는 복구, 완전 삭제, 전체 삭제로 변경됩니다. 기존에 할당했던 태그들과 조합할 수도 있습니다. 일반적인 OS의 있는 휴지통을 구현한 것으로 이해하면 되겠습니다. 사용자 태그는 블로그나 SNS에서처럼 태그를 엉뚱하게 사용하는 일이 없도록 신중하게 입력하여 간결하게 유지할 것을 강요합니다. 한일/할일 목록을 작성하는 느낌의 인터페이스를 만들고 싶었지만 잘 안된거 같습니다. 추가적으로, 사용자의 불필요한 행동을 차단하기 위해 수신된 데이터에서 더이상 범위를 좁힐수 있는 태그가 발견되지 않으면 태그 필터 버튼이 비활성됩니다. 여러 사람을 대상으로 시연을 하는동안 다수의 분이 불편할 것 같다고 토로 했는데 일단 사용해 보실것을 권장한 뒤로 별다른 크레임은 없는 상태이긴 합니다만, 어이가 없어서 그런건지... 도무지 알길이 없네요. 이 부분에 대한 사용성은 개인적으로도 가장 검증하고 싶은 부분입니다. 만약 테스트에 참여하신다면 의견 꼭 부탁드릴께요. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://socket.io/"&gt;SocketIO&lt;/a&gt;를 이용한 알림을 지원합니다. 파일이 추가되거나 갱신되는 경우 파란색 카운터가 아이콘 대신 나타나며, 노트와 같은 소통성 데이터가 추가되거나 갱신되는 경우 주황색 카운터가 나타납니다. 다른 사람에게 초대된 경우 느닷없이 새로운 탭이 추가되며, 현재 접속중인 공유 탭의 사용자 수를 하단에 표시합니다. 이번 주 중에 다른 사람이 포커스 중인 아이템을 비주얼라이즈하는 기능이 추가될 거 같습니다. SocketIO는 이미 여러 번 다뤄봤기 때문에 처음부터 신중하게 적용했는데, 크로스-도메인 제약이 없기 때문에 SocketIO를 완전히 독립된 서버로 운영하고 이 서버가 죽거나 브라우저가 WebSocket을 지원하지 않아도 기능상에는 아무런 지장이 없게 하는 것에 원칙을 두었습니다.&lt;/p&gt;
&lt;p&gt;오래 머물러 봐야 채 10분 내외인 사이트에 채팅 기능은 굳이 필요 없다고 판단했습니다. 그래도 명세기 웹 서비스인데 커뮤니케이션 피처는 있어야겠다 싶어서 노트 페이퍼(Note Paper)라 명명한 종이쪽지를 통해 필요한 소통만 이루어지도록 했습니다. 마치 포스트-잇을 작성하는 느낌으로 메모를 덕지덕지 화면에 붙여 놓는 것이죠. 이 쪽지는 파일들과 상호작용하도록 설계되었습니다. 파일과의 연결 없이는 작성할 수 없으며, 우측 상단의 링크 아이콘을 클릭하면 이미 화면에 있는 경우 파일 위치로 스크롤하고 포커스, 없는 경우 나타날 때까지 탐색합니다. 이것은 마치 이메일에 파일을 첨부하는 행위로 이해하셔도 무방하겠습니다. 이렇게 작성된 쪽지는 해당 공유 탭에 참여한 모든 사용자에게 나타나게 되며, 닫기 버튼을 눌러야 화면에서 사라져요. 이 행위를 시스템은 사용자가 내용을 확인한 것으로 간주하는 것입니다. 한 번 닫으면 다시 는 열 수 없으니 신중하게 처리해야 합니다. 다시 조회하는 기능이 없는 대신 환경설정에서 쪽지 수신에 대한 이메일 알림으로 대체할 수 있도록 했습니다.&lt;/p&gt;
&lt;p&gt;
  &lt;div id="gallery49874" class="g_container" style="width:px;height:px;"&gt;
    &lt;img src="http://firejune.cdn2.cafe24.com/attach/1126/121126200035496502/779795.png" width="" height="" id="g_img49874_0" alt="attachment"/&gt;
  &lt;/div&gt;
  &lt;div class="cap1" id="scap49874"&gt;초창기 사용자 인터페이스 목업&lt;/div&gt;
  
&lt;br&gt;
UI가 꾀나 불친절하다는 것을 잘 알고 있습니다. 대부분의 기업용 솔루션은 사전 학습을 요구하는 과정이 있기 때문에 레이블들로 떡칠이 되어 난잡해진 레이아웃을 제공하는 것이 그저 마음에 안들었던 거죠. 조금 미안한 마음이 들어서 주요 기능들에는 예쁜 툴팁울 넣어 두었습니다. 모든 상호작용은 멀티플로 작동하고 행동에 따른 패널과 다이얼로그를 통해 이루어집니다. 복수로 타겟팅한 다음 선택 가능한 액션이 활성화 되는 일반적인 애플리케이션 인터랙션과 마찬가지에요.&lt;/p&gt;
&lt;p&gt;모바일 웹도 지원합니다. 모바일용 페이지를 별도로 만들어 제공하는 것은 설계 자체를 잘못한 것이라는 생각이 들어서 스타일 시트와 약간의 조건문만으로 모바일 웹 지원을 해결했습니다. 조금 이상한 것이 모바일에서 올리는 이미지 파일은 이름이 모두 image.jpg로 넘어오기 때문에 업로드전에 파일명을 유니크하게 변경해 주는 작업이 필요했습니다. 그리고 모바일 사파리에는 &lt;del&gt;File API 자체에 버그가 있어서 첫 사진만 중복해서 등록됩니다.&lt;/del&gt;(미친 모바일 사파리는 post도 캐시를 하면서 발생한 문제였습니다. Timestamp로 해결) 로드맵에는 전용 데스크탑 앱과 모바일 앱 개발이 포함되어 있으니 최소한의 수준으로 마무리한 거죠. 아직은 iOS만 지원하고 안드로이드 머신까지는 아니에요. 프론트-엔드 얘기는 이즘에서 접고, 다른 쪽 얘기를 해 볼까요.&lt;/p&gt;
&lt;p&gt;백-엔드는 100% &lt;a href="http://nodejs.org/"&gt;NodeJS&lt;/a&gt;로 구축되었습니다. 협업에 용이하도록 &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt;에 둥지를 틀고 프레임웍으로는 &lt;a href="http://expressjs.com/"&gt;ExpressJS&lt;/a&gt;기반의 &lt;a href="http://railwayjs.com/"&gt;RailwayJS&lt;/a&gt;를 사용했으며, 데이터베이스는 &lt;a href="http://www.mongodb.org/"&gt;Mongo&lt;/a&gt;이고, &lt;a href="http://mongoosejs.com/"&gt;MongooseJS&lt;/a&gt; 모듈을 사용했습니다. 그리고 스토리지는 자주 언급한 바 있는 &lt;a href="http://www.openstack.org/software/openstack-storage/"&gt;OpenStack Object Storage(Swift)&lt;/a&gt;입니다. AD, LDP과의 연동이 용이하도록 &lt;a href="http://docs.openstack.org/developer/glance/authentication.html"&gt;Keystone&lt;/a&gt;인증 체계를 사용했고요.&lt;/p&gt;
&lt;p&gt;원래 .NET하던 친구인 성열군에게 NodeJS가 죽여준다고 꼬드겨서 우여곡절 끝에 우리 화사 공식 백-엔드 개발자로 영입하게 되었습니다. 요즘엔 자바스크립트가 구리다는 소리를 늘 입에 달고 다니면서도, 처리해야 할 일이 생기면 똑부러지게 처리해 주는 멋진 동료입니다. (지금은 분명 속았다는 느낌일 거에요.) 최근 결혼 준비 때문에 바쁜 와중에도 큰 도움을 줘서 얼마나 고마운지 몰라요. 결혼 축하해!&lt;/p&gt;
&lt;p&gt;이 양반과 NodeJS로 삽질하면서 수나잘을 떠들고도 모자랄 정도의 많은 이슈들을 처리했습니다. 특히, File API를 이용한 멀티플 업로드를 구현하는 과정에서 노드로 바이너리(Binary)를 다루는 일은 다시는 하고 싶지 않은 코딩 지옥이었어요. 당시에는 자바스크립트로 만든 웹서버를 구축한다니 어처구니가 없고 너무 못 미더워서 만드는 중간에 다른 플랫폼으로 컨버젼해야 한다는 생각이 끊이질 않았었습니다. 기능 구현에 목말라 예외처리를 너무 등한시 한데서 문제가 발생한 경우가 많기도 했지만, 이미 다뤄 보신 분 들이라면 끝없는 콜백, 지랄 같은 문법, 메모리 릭과 같은 풀리지 않는 문제 등을 경험해 보셨을 것입니다. 지금은 Production 모드에서 &lt;a href="http://www.redis.io/"&gt;Redis&lt;/a&gt;를 이용해 서버가 죽어도 세션(Session)이 살아있게 처리하고, CPU 수만큼 클러스터링해서 돌려놓으니 한결 안정화된 느낌입니다.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://www.splunk.com/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/1126/121126200035496502/018052.png" width="661" height="533" alt="Splunk.png" class="reflect hasborder"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;또한, 우리 &lt;a href="http://kerberosj.tistory.com/160"&gt;윤진군&lt;/a&gt;은 바이너리에 연약한 노드를 강하게 만들어줄 NginX 환경을 재구성하여 외부에서 https로 들어오는 것을 노드에게 http로 프락시 패스해주고, 정적인 파일들을 모두 NginX에서 서빙하여 노드의 성능을 끌어올리는데 크게 한몫했습니다. 10개 프로세스가 각 1024개 스레드로 작동한데요. 그 무거운 서버들을 Cafe2x 데이터 센터까지 들고가서 손수 설치하는 걸 도와주지 못해 미안한 마음도 들었지만... 아무튼, Velox라는 네이밍도 이 친구 아이디어였어요. 별도로 설치해 준 &lt;a href="http://www.splunk.com/"&gt;Splunk&lt;/a&gt;라는 로그 분석도구를 이용해서 위 화면에서 보는 것처럼 노드에서 크래쉬가 발생한 코드를 기간단위로 가시화해서 모니터링하여 분석할 수 있었고 예상치 못한 오류를 대폭 수정할 수 있었습니다. 2012년 11월 24일에 엄청 죽었군요; 간단한 사용팁 하나를 드리자면 위처럼 컬러코드가 로그에 포함되지 않게 하려면 forever를 실행할 때 --plain 옵션을 사용하세요.  노드로 서비스 돌리시는 분들에게 강력추천합니다. 로그 크기 500MB까지 공짜임!&lt;/p&gt;
&lt;p&gt;언제나 그렇듯이 글이 두서가 없네요. 아침 일찍 포항으로 날아가야 하는 관계로 나중에 다시 가다듬도록 하겠습니다. 급하게 마무리하자면, 노드로 밀어 붙인 건 잘한 일이라 생각하고 었어요. 언젠가 꼭 배워야겠다고 생각만 10년 했던 리눅스를 다루는 데에도 조금 익숙해지고, 맥이랑도 친해지고, 서버를 운영하는 기술도 등 넘어 배우고, 노드의 장단점도 확실히 몸으로 깨우쳤으니까요. 무엇보다도 최근 5개월 스팟하는 동안 그리 넉넉한 개발환경이 아님에도 열심히 달려준 동료가 있었기에 가능한 일이었습니다. 재미있는 프로젝트에 참여할 기회를 주신 대표님, 버그 리포팅와 신선한 아이디어를 아낌없이 지원해 주신 팀장님, 내부 테스트에 참여해 주신 사운드파이프코리아 여러분, 그리고 쳐 싸우면서 같이 고생한 성열, 윤진군에게 이 자리를 빌려 고마운 마음을 전합니다.&lt;/p&gt;
&lt;p&gt;아, 참! 이 서비스의 도메인은 &lt;a href="https://thevelox.com"&gt;https://thevelox.com&lt;/a&gt; 입니다. 서버 수용치 만큼만 테스트 회원가입을 받을 예정이니 테스트 의향이 있으신 분들은 서둘러 가입해 주시면 감사하겠습니다. &lt;del&gt;1등에서 3등까지는 이쁜이 사진 3,000여장 공유해 드림!&lt;/del&gt; 테스트 기간은 미정이고, 계정당 100GB씩 할당해 드리며, 다른 사람이 공유한 탭에 가입하면 소비량은 합산되고 파일당 용량 제한은 4GB입니다. 그리고 파일을 외부인과 전송하는 기능은 아직 마무리 되지 않아서 접근제한이 풀려있는 상태이니 착오 없으시길 바라고요. 어디까지나 테스트이니만큼 등록한 파일이 갑자기 사라져도 전 몰라요.(헤헤... 농담입니다.) 그리고 또, 디자인도 아직 가다듬어 지지 않았습니다. 디자인에 대한 의견은 무효입니다. 우리 회사엔 디자이너가 없어요! 다 어디서 퍼온거에요.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;외주로 진행 가능한 실력있는 디자이너님 추천해주세요! - &lt;a href="https://twitter.com/firejune"&gt;@firejune&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1771#p1771"&gt;Comments(16)&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1771"&gt;Hits(13295)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/f37Rx0cv4to" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1771</feedburner:origLink></entry><entry><title type="text">Emily Browning - Sweet Dreams (Sucker Punch OST)</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/QtvjC8kX17c/1769" /><category term="영화/음악" /><category term="문화" /><category term="Sucker Punch" /><category term="Soundtrack" /><category term="내 스타일" /><category term="OST" /><category term="Emily Browning" /><category term="Sweet Dreams" /><author><name>파이어준</name></author><updated>2012-11-08T06:05:08-08:00</updated><id>http://firejune.com/1769</id><content type="html">&lt;p&gt; &lt;iframe width="665" height="371" id="utplayer" src="http://www.youtube.com/embed/u7zxNpGA7wI?list=PLFFE1B4334D222920&amp;amp;hl=ko_KR" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;ul id="playlist" class="square"&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/embed/u7zxNpGA7wI?list=PLFFE1B4334D222920&amp;amp;hl=ko_KR&amp;amp;autoplay=1"&gt;01 - Sweet Dreams - Emily Browning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/embed/Zce1QaicJTs?list=PLFFE1B4334D222920&amp;amp;hl=ko_KR&amp;amp;autoplay=1"&gt;02 - Army of Me [Sucker Punch Remix]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/embed/sMBXcX9mmRc?list=PLFFE1B4334D222920&amp;amp;hl=ko_KR&amp;amp;autoplay=1"&gt;03 - White Rabbit - Emiliana Torrini&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/embed/Q4sZlyOc58k?list=PLFFE1B4334D222920&amp;amp;hl=ko_KR&amp;amp;autoplay=1"&gt;04 - I Want It All / We Will Rock You [Mash-Up]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/embed/CD0ng1BONFM?list=PLFFE1B4334D222920&amp;amp;hl=ko_KR&amp;amp;autoplay=1"&gt;05 - Search and Destroy - Skunk Anansie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/embed/OPsL6dECQ38?list=PLFFE1B4334D222920&amp;amp;hl=ko_KR&amp;amp;autoplay=1"&gt;06 - Tomorrow Never Knows - Carla Azar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/embed/7U9f1Rrhz9w?list=PLFFE1B4334D222920&amp;amp;hl=ko_KR&amp;amp;autoplay=1"&gt;07 - Where Is My Mind - Yoav (feat. Emily Browning)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/embed/17M_pWtRsew?list=PLFFE1B4334D222920&amp;amp;hl=ko_KR&amp;amp;autoplay=1"&gt;08 - Asleep - Emily Browning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/embed/8pO9VeF3QRs?list=PLFFE1B4334D222920&amp;amp;hl=ko_KR&amp;amp;autoplay=1"&gt;09 - Love is the Drug - Oscar Isaac &amp; Carla Gugino&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;

"Sucker Punch OST"는 언제 들어도 좋아요. 꺄~&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1769#p1769"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1769"&gt;Hits(12985)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/QtvjC8kX17c" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1769</feedburner:origLink></entry><entry><title type="text">새로운 스크롤 제스처 아이디어 - 플릭 스크롤</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/1E2NJgkwCd8/1768" /><category term="모바일" /><category term="정보" /><category term="플릭 스크롤" /><category term="아이디어" /><category term="simurai" /><category term="UI" /><category term="터치" /><category term="이벤트" /><category term="스크롤" /><category term="제스처" /><author><name>파이어준</name></author><updated>2012-10-28T06:42:57-07:00</updated><id>http://firejune.com/1768</id><content type="html">&lt;p&gt; &lt;iframe src="http://player.vimeo.com/video/49375288?badge=0" width="666" height="374" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;플릭 스크롤(Flick Scroll)은 아이폰이나 아이패드 또는 안드로이드와 같은 터치 인터페이스에서 추가적인 화면 조작하는데 있어서 &lt;a href="http://simurai.com/post/31460815120/flick-scroll"&gt;새로운 제스처로 스크롤 하는 방법&lt;/a&gt;에 대한 Simon(simurai)씨의 생각입니다. 일반적으로 터치를 이용하여 스크롤 하기 위해서는 터치-시작, 터치-이동 이벤트에 의해 스크롤 기능으로 진입하며, 여기에서 두 가지 동작으로 나누어지는데, 터치-종료 이벤트에 의해 스크롤 동작이 던지기로 판단(행동 시간 대비 이동 범위)되는 경우 미끄러지듯이 스크롤 되며, 그렇지 않으면 마지막 포인팅 위치까지 드래그하는 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://firejune.com/attach/1028/121028201002112791/531814.gif" width="500" height="388" alt="flick-scroll.gif" /&gt;&lt;/p&gt;
&lt;p&gt;여기에 플릭 스크롤 제스처를 더하면 터치-시작 지점을 빠르게 화면의 끝으로 짧게 이동할 수 있는 기능이 추가되는 것입니다. 그리고 앱의 화면 구성 상태에 따라서는 페이지를 업/다운 혹은 다음/이전 페이지 이동으로 작동할 수도 있습니다. 이 제스처는 터치-시작, 터치-이동, 터치-종료를 짧고 빠르게 하는 것으로 발동하게 됩니다. 말로 설명하려니 참(;) 위 그림과 동영상을 참고하면 이해가 빠르겠네요.&lt;/p&gt;
&lt;p&gt;여기 두 데모에 플릭 스크롤을 적용해 보았습니다. &lt;a href="http://archive.simurai.com/lab/flick-scroll/book/"&gt;북(Book) 데모&lt;/a&gt;는 짧은 스크롤 모드이고 &lt;a href="http://archive.simurai.com/lab/flick-scroll/timeline/"&gt;타임라인 데모&lt;/a&gt;는 페이지 업/다운 모드로 작동하는 것입니다.&lt;/p&gt;
&lt;p class="note"&gt;단, 이 새로운 스크롤 제스처를 구현하기 위해서는 기본으로 제공하는 터치 스크롤 기능을 해제 해야 할 필요가 있었기 때문에 기본으로 제공되는 터치-스크롤의 에뮬레이션을 위해  &lt;a href="http://cubiq.org/iscroll-4"&gt;iScroll4&lt;/a&gt; 자바스크립트 라이브러리가 사용되었다는 점과 만약에 플릭 스크롤이 기능이 기본으로 내장된다면 위 데모보다도 훨씬 더 원활하게 작동할 것이라는 점을 기억해 주세요.&lt;/p&gt;
&lt;p&gt;덧. Simon씨는 이 아이디어에 대한 다른 사람들의 의견을 취합하고 있으며, 플릭 스크롤과 유사한 기능으로 더블-탭 한 위치를 중앙으로 이동할 수 있다는 의견에 일반 웹 페이지일 때 확대하는 기능으로 사용되고 있는 등의 이유로 플릭 스크롤과는 차이가 있다고 했으며, 플릭 스크롤 제스처가 짧은 스크롤인지 페이지 업/다운인지의 의사를 자동으로 판단할 수 있다는 등의 의견이 있습니다.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1768#p1768"&gt;Comments(1)&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1768"&gt;Hits(18008)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/1E2NJgkwCd8" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1768</feedburner:origLink></entry><entry><title type="text">Cafe24의 Bingbot 차단문제 해결하기</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/aQXMA2o3wNo/1765" /><category term="웹개발" /><category term="자료" /><category term="Bingbot" /><category term="카페24" /><category term=".htaccess" /><category term="야후" /><category term="Bing" /><category term="Bing 웹마스터 도구" /><category term="크롤링" /><category term="호스팅" /><author><name>파이어준</name></author><updated>2012-10-25T10:27:52-07:00</updated><id>http://firejune.com/1765</id><content type="html">&lt;p&gt; &lt;a href="http://www.searchalliance.com"&gt;야후와 Bing이 검색 제휴&lt;/a&gt;를 맺었다는 소식을 뒤늦게 접하고 &lt;a href="http://www.bing.com/toolbox/webmaster/"&gt;Bing 웹마스터 도구&lt;/a&gt;를 이용하여 firejune.com의 크롤링을 신청하고 약 한 달 정도 지났지만 크롤이 단 한 건도 성공하지 못하여 알아보니 카페24 호스팅에서는 주기적인 서버부하 등의 문제가 발생하여 Bingbot을 전역으로 차단하고 있다는 정보를 찾을 수 있었습니다. 실제로 Bing 웹마스터 도구에서 제공하는 "Bingbot으로 가져오기" 도구를 이용하여 크롤 성공 여부를 확인해 보니, 모든 URL에 대하여 다음과 같은 403 Forbidden이 발생하고 있었습니다. &lt;/p&gt;
&lt;pre class="command"&gt;&lt;code class="command"&gt;HTTP/1.1 403 Forbidden
Connection: keep-alive
Date: Thu, 25 Oct 2012 16:46:02 GMT
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1
Server: apache&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그래서 Cafe24의 문의 게시판에 위와 같은 증상과 해결방법을 보고했더니 FTP홈디렉토리의  .htaccess파일의 제일 하단에 다음과 같은 코드를 삽입하여 해결해 주더군요.&lt;/p&gt;
&lt;pre class="html"&gt;&lt;code class="html"&gt;PHP_FLAG register_globals ON
PHP_VALUE mysql.default_charset UTF8
&amp;lt;IfModule mod_url.c&amp;gt;
   CheckURL  Off
&amp;lt;/IfModule&amp;gt;
SetEnvIfNoCase User-Agent "bingbot" !go_out&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 코드가 적용되고 며칠이 지난 후 정상적으로 크롤링하는 것을 확인할 수 있었습니다.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/1026/121026013225721816/153090.png" width="664" height="316" alt="보고서 및 데이터 - Bing 웹 마스터 도구-022118.png" class="reflect hasborder"/&gt;&lt;/div&gt;
&lt;p&gt;혹시 저와 같은 문제를 겪으신다면 이와 같은 방법으로 해결할 수 있습니다.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1765#p1765"&gt;Comments&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1765"&gt;Hits(16365)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/aQXMA2o3wNo" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1765</feedburner:origLink></entry><entry><title type="text">IOS6 업데이트, 한국에서 지역기반 서비스 대부분 미지원</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/OYqBCIqDD98/1764" /><category term="모바일" /><category term="정보" /><category term="IOS6" /><category term="한국" /><category term="업데이트" /><category term="미지원" /><category term="항목" /><category term="법규가 병맛" /><category term="애플" /><category term="이민가고 싶다" /><author><name>파이어준</name></author><updated>2012-09-19T14:54:24-07:00</updated><id>http://firejune.com/1764</id><content type="html">&lt;p&gt; IOS6 업데이트는 다음을 포함한 200가지 이상의 새로운 기능이 포함되어 있습니다. 하지만, 한국에서 &lt;a href="http://www.apple.com/ios/feature-availability"&gt;사용할 수 없는 일부 기능&lt;/a&gt;을 표시해 보았더니, 지역 기반 관련 기능을 대부분 이용할 수 없군요. 3GS부터 계속 그래 왔는데, 나중에는 해 주겠거니 하고 넘어갔지만, 아예 그럴 생각이 없는 거 같습니다. 그리고 iTunes Store도 그대로네요. 이거 왜 이럴까요? 한국 시장이 작아서 그럴까요? 우리나라가 후진국이라 애플이 생까는 걸까요? 아니면 대한민국 법규가 병맛이라서 그런 건가요?&lt;/p&gt;

&lt;ul class="square"&gt;
  &lt;li&gt;지도&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Apple이 디자인한 벡터 기반 지도&lt;/li&gt;
    &lt;li&gt;성으로 방향을 안내하는 턴 바이 턴(Turn-by-turn) 방식의 내비게이션(iPhone 5, iPhone 4S, 2세대 및
      3세대 iPad Wi-Fi + 셀룰러)&lt;/li&gt;
    &lt;li&gt;실시간 교통 정보 &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;실제 주요 도심 지역과 거의 흡사한 사진 및 대화식 3D 보기를 제공하는 Flyover(iPhone 5, iPhone 4S, 3세대 iPad 및 5세대 iPod touch) &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;Yelp 사진, 선호도, 리뷰 및 검색 가능한 항목이 포함된 지역 검색 결과 &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;Siri가 통합되어 길을 묻거나 경로를 따라 장소를 찾을 수 있음 &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;li&gt;Siri 개선사항&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;스포츠: 야구, 농구, 축구, 미식축구 및 하키 경기의 점수, 선수 정보, 경기 일정, 출전 선수 및 리그 순위 확인 가능&lt;/li&gt;
    &lt;li&gt;영화: 예고편, 상영시간, 리뷰 및 정보 확인 가능 &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;음식점: 예약, 리뷰, 사진 및 정보 제공 &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;트윗 보내기&lt;/li&gt;
    &lt;li&gt;Facebook에 게시물 올리기&lt;/li&gt;
    &lt;li&gt;응용 프로그램 실행&lt;/li&gt;
    &lt;li&gt;지원되는 자동차의 경우 Eyes Free 사용 가능&lt;/li&gt;
    &lt;li&gt;Siri가 지원되는 국가의 경우 지역 검색 가능(출시 초기에는 사용이 제한적일 수 있음) &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;추가 국가 및 언어 지원: 캐나다(영어 및 캐나다 프랑스어), 중국(중국 표준어), 홍콩(광둥어), 이탈리아(이탈리아어), 한국(한국어),
      멕시코(스페인어), 스페인(스페인어), 스위스(이탈리아어, 프랑스어, 독일어), 대만(중국 표준어) 및 미국(스페인어)&lt;/li&gt;
    &lt;li&gt;iPhone 5, iPhone 4S, 3세대 iPad 및 5세대 iPod touch에서 지원&lt;/li&gt;
  &lt;/ul&gt;
  &lt;li&gt;Facebook 통합 ...&lt;/li&gt;
  &lt;li&gt;공유 사진 스트림 ...&lt;/li&gt;
  &lt;li&gt;Passbook ...&lt;/li&gt;
  &lt;li&gt;FaceTime 개선사항 ...&lt;/li&gt;
  &lt;li&gt;전화 개선사항 ...&lt;/li&gt;
  &lt;li&gt;Mail 개선사항 ...&lt;/li&gt;
  &lt;li&gt;Safari 개선사항 ...&lt;/li&gt;
  &lt;li&gt;App Store 및&amp;nbsp;iTunes Store 개선사항 &lt;strong style="color: #b30"&gt;음악, 영화, TV 프로그램 컨텐츠 없음&lt;/strong&gt;&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;스토어 디자인 업데이트 &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;iTunes 미리보기 내역 &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;나의 시즌 완성 &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;나의 앨범 완성 &lt;strong style="color: #b30"&gt;미지원&lt;/strong&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;li&gt;Game Center 개선사항 ...&lt;/li&gt;
  &lt;li&gt;손쉬운 사용 개선사항 ...&lt;/li&gt;
  &lt;li&gt;버그 수정 등&lt;/li&gt;
&lt;/ul&gt;


 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1764#p1764"&gt;Comments(4)&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1764"&gt;Hits(25400)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/OYqBCIqDD98" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1764</feedburner:origLink></entry><entry><title type="text">아이콘 웹 폰트 라운드업</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/U5k6MbKOUuY/1763" /><category term="웹개발" /><category term="자료" /><category term="프로젝트" /><category term="아이콘" /><category term="폰트" /><category term="벡터" /><category term="웹폰트" /><category term="CSS" /><category term="HTML" /><category term="Fico" /><category term="Pixelated" /><category term="Entypo" /><category term="Uicons" /><category term="Iconic" /><category term="Sanscons" /><category term="Heydings" /><category term="JustVector" /><category term="Flexi" /><category term="WriteSocial" /><category term="ikoo" /><category term="InfoBits" /><category term="Pictos" /><category term="FontAwesome" /><category term="CSS3" /><author><name>파이어준</name></author><updated>2012-09-17T13:38:12-07:00</updated><id>http://firejune.com/1763</id><content type="html">&lt;p&gt; 업무가 슬슬  재미있어지고 있습니다. 회사에 그래픽 디자이너가 없다 보니 맘대로 사이트를 작살내고 있는 와중에 하나 둘 드러나기 시작하는 시각적 불만족을 잠재울 아이콘 폰트를 찾고 있던 참이었습니다. 구하면 얻는다더니, &lt;a href="http://www.webdesignerdepot.com/2012/09/a-roundup-of-great-icon-fonts/"&gt;Web Designer Depot에서 솔깃할 만한 포스트&lt;/a&gt;를 최근에 작성했군요. 브라우저 벤더 마다 지원하는 형식이 달라 여러가지 폰트 포맷을 준비해야하는 상황이지만, 그럼에도 아이콘 웹 폰트를 도입했을 때의 이점은 너무나 많습니다. 색상과 크기를 CSS에서 조정할 수 있으며, 그림자와 그라디언트 등의 다양한 CSS3 효과를 적용할 수도 있죠. 벡터이기 때문에 크기에 구애받지 않으면서 자연스럽게 레티나 디스플레이에도 대응합니다. 또한, 글꼴파일이기 때문에 리소스 로딩을 개선할 수 있는 등이 아이콘 웹 폰트를 사용하는 이유입니다. 최근에 인기몰이 중인 아이콘들을 정리해 보겠습니다.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://fico.lensco.be/"&gt;Fico&lt;/a&gt; &lt;em&gt; €19.00&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;프로토타입 개발에 애용하는 아이콘 웹 폰트입니다. &lt;a href="http://jsbin.firejune.com"&gt;jsbin.firejune.com&lt;/a&gt;에서도 요긴하게 이용 중인 녀석이지요. 구매자에게는 더 혜택이 있을 줄 알았는데 다를 게 없더군요(맘만 먹으면 퍼올 수 있어요;). 뭔가 기부한 느낌이 드는 유료 웹 폰트입니다. 총 52개의 아이콘으로 구성되었으며, 요소의 data 속성을 이용하여 마크 업하는 것으로 아이콘을 쉽게 표시할 수 있습니다. &lt;/p&gt;
&lt;pre class="html"&gt;&lt;code class="html"&gt;&amp;lt;a href="#" class="icon" data-icon="p"&amp;gt;&amp;lt;/a&amp;gt;

&amp;lt;style&amp;gt;
  @font-face {
    font-family: fico;
    /* reference font files here */
    }

  .icon:before {
    content: attr(data-icon);
    font-family: fico;
    }
&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://fico.lensco.be/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/872273.png" width="615" height="308" alt="Fico.png" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p class="note"&gt;특수문자(Unicode Icon)를 아이콘으로 매핑하여 폰트가 로드되지 않는 상황에서도 그 의미를 전달할 수 있게 만들어졌으며, 문자의 크기와 기준선(Baseline)과도 잘 맞아떨어집니다. 폰트당 7~15KB로 부담 없는 용량이면서 아이콘의 디테일도 훌륭한 편이긴 합니다만, 아이콘의 가짓수가 그리 많지 않습니다.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://wplifeguard.com/pixelated-icon-set/"&gt;Pixelated&lt;/a&gt; &lt;em&gt;Free&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;10 x 10 사이즈의 픽셀 짜리 투명 gif 이미지들로 구성된 아이콘 셋입니다. 픽셀 수가 작다 보니 전부 합쳐봐야 용량이 고작 60바이트입니다. 총 36가지 아이콘이 어두고 밝은 색상으로 구분되었으며, PSD파일을 함께 제공합니다. 무료이고 상업적으로도 사용 가능합니다.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://wplifeguard.com/pixelated-icon-set/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/305001.png" width="600" height="300" alt="pixelated.png" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p class="note"&gt;이건 웹 폰트가 아닌 이미지 아이콘입니다. 왜 넣은 거지?&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://www.entypo.com/"&gt;Entypo&lt;/a&gt; &lt;em&gt;CC BY-SA 3.0&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;Pixelated와 같이 상업적으로 사용해도 무방한 무료 아이콘 셋입니다(&lt;a href="http://creativecommons.org/licenses/by-sa/3.0/deed.ko"&gt;CC BY-SA 3.0&lt;/a&gt; 요약: 저작자 표시). 총 124개의 벡터 아이콘으로 구성되어 있으며, EPS와 OpenType 폰트 포맷으로 제공됩니다. 용량은 19~29KB이며, SVG 포맷은 63KB입니다. 웹 폰트 서비스는 현재 준비 중이군요.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://www.entypo.com/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/047475.png" width="615" height="307" alt="set-entypo1-e1339466491852.png" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p class="note"&gt;OpenType 폰트는 &lt;a href="http://www.fontsquirrel.com"&gt;Font Squirrel&lt;/a&gt;에서 생성된 것으로 문자에 비해 너무 작은 크기로 할당되어 있어 문자와 동시에 사용하기에는 부적합니다.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://uicons.co/"&gt;Uicons&lt;/a&gt; &lt;em&gt;$20&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;391 아이콘 세트, 소셜 네트워크 아이콘 포함, 상대적으로 저렴한 $20(이후 업데이트 공짜), 벡터 소스제공&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://uicons.co/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/122569.png" width="615" height="307" alt="set-uicons-e1339467899799.png" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;&lt;a href="http://somerandomdude.com/work/iconic/#"&gt;Iconic&lt;/a&gt; &lt;em&gt;Free&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;Iconic은 오픈 소스로 공개된 171가지 아이콘을 취합한 것입니다. 무료이고요. 이 아이콘 폰트는 확장 가능하도록 설계된 것이 특징입니다. 그리고 Github에 공개하여 만인이 원하고 다 같이 만들어가는 것을 목표로 한다는군요. PNG, SVG, SWC, OFT/TTF/EOT 등 모든 형태의 포맷을 얻을 수 있으며, JSX와 Python 스크립트를 이용하여 원하는 아이콘 셋을 빌드할 수 있습니다. 폰트당 용량은 19~46KB이며, SVG 포맷은 81KB입니다.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://somerandomdude.com/work/iconic/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/765748.png" width="615" height="307" alt="Screen-Shot-2012-06-22-at-19.54.19.png" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p class="note"&gt;Unicode 아이콘과 16진수(Hexadecimal) 코드 중 하나를 선택하여 폰트로부터 아이콘을 호출하며, 선(Stroke)과 색이 채워진(Fill) 두가지 스타일로 구분되어 있습니다. 공개된 아이콘들이어서 그런지는 몰라도 쌀티가 물씬 풍깁니다.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://somerandomdude.com/work/sanscons/"&gt;Sanscons&lt;/a&gt; &lt;em&gt;CC BY-SA 3.0&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;이것은 &lt;a href="http://somerandomdude.com/work/bitcons/"&gt;Bitcons&lt;/a&gt;의 CSS에서 사용하기 편한 버전입니다. 120개 아이콘이 10가지 색상과 16×16, 32×32 그리고 64×64 크기로 구성되었으며,  Entypo와 같은 CC BY-SA 3.0 라이센스입니다.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://somerandomdude.com/work/sanscons/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/204720.jpg" width="619" height="307" alt="Sanscons.jpg" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p class="note"&gt;이것 역시 이미지 아이콘...&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://www.heydonworks.com/article/a-free-icon-web-font"&gt;Heydings&lt;/a&gt; &lt;em&gt;Free&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;총 60개의 고품질 아이콘이 담긴 무료 웹 폰트입니다. CSS를 이용하여 표시할 수 있고, 사용자가 더 쉽게 사용할 수 있게 하려고 알파벳에 매핑했으며, 다양한 범위의 핵심 인터페이스를 커버할 수 있도록 설계되었습니다.&lt;/p&gt;
&lt;pre class="css"&gt;&lt;code class="css"&gt;a:before, a:after {
     font-family:'Heydings';
}

a[href*="rss"]:before {
     color:#c03f29;
     content:'R';
}

a[href*="rss"]:after {
     vertical-align:super;
     font-size:16px;
     content:'e';
}&lt;/code&gt;&lt;/pre&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://www.heydonworks.com/article/a-free-icon-web-font"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/036962.png" width="615" height="355" alt="Heydings1.png" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p class="note"&gt;달랑 TTF(TrueType Font) 형식만 제공합니다.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://www.alexpeattie.com/projects/justvector_font/"&gt;Just Vector&lt;/a&gt; &lt;em&gt;?&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;이 아이콘 세트는 다양한 크기의 &lt;code&gt;@font-face&lt;/code&gt;를 제공합니다. 문자를 그대로 아이콘화하기 때문에 별도의 트릭을 필요로 하지 않습니다. 소셜 아이콘 포함 총 62개로 구성되어 있습니다. 애플 로고도 있군요.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://www.alexpeattie.com/projects/justvector_font/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/404209.jpg" width="615" height="240" alt="icon_font_20.jpg" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p class="note"&gt;다양한 크기에서 문자와의 훌륭한 조합을 보이지만, UI 요소에 사용할만한 아이콘이 없습니다.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://www.myfonts.com/fonts/juraj-chrastina/flexi-social-icons/flexi-social-icons/gallery.html"&gt;Flexi Social Icons&lt;/a&gt; &lt;em&gt;$29&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;Flexi는 myfonts.com에서 제공하는 유료 웹 폰트입니다. 총 68개의 소설 아이콘으로 구성되어 있으며 가격은 $29입니다.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://www.myfonts.com/fonts/juraj-chrastina/flexi-social-icons/flexi-social-icons/gallery.html"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/616419.jpg" width="615" height="160" alt="flexi-social2.jpg" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;&lt;a href="http://kdnmedia.com/"&gt;WriteSocial&lt;/a&gt; &lt;em&gt;$10/$15&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;WriteSocial은 18가지 아이콘만으로 구성되어 있지만, 모서리가 둥근 사각형이나 원형에 음각으로 들어간 아이콘들을 옵션으로 제공합니다. $10를 지급하고 글꼴만 구입하거나 $10를 자선 단체에 기부하는 대신에 $15를 지급하도록 선택할 수 있습니다.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://kdnmedia.com/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/001904.jpg" width="615" height="240" alt="WriteSocial1.jpg" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;&lt;a href="http://fontstruct.com/fontstructions/show/352362"&gt;ikoo&lt;/a&gt; &lt;em&gt;Free&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;ikoo는&lt;code&gt;@font-face&lt;/code&gt;를 사용하지 않고 플래시를 이하여 HTML 페이지에 벡터 아이콘을 출력할 수 있도록 개발된 글꼴입니다. 또한, CSS에서 정의한 크기와 색상을 정의할 수 있습니다. 총 65개의 아이콘으로 구성되어 있으며 무료입니다.&lt;/p&gt;
&lt;pre class="html"&gt;&lt;code class="html"&gt;&amp;lt;object id="flash_352362" type="application/x-shockwave-flash" style="width:570px; height:90px;" data="http://fontstruct.com/widget.swf"&amp;gt;
  &amp;lt;param name="movie" value="http://fontstruct.com/widget.swf" /&amp;gt;
  &amp;lt;param name="wmode" value="opaque" /&amp;gt;
  &amp;lt;param name="bgcolor" value="#FFFFFF" /&amp;gt;
  &amp;lt;param name="allowFullScreen" value="true" /&amp;gt;
  &amp;lt;param name="flashvars" value="d=dD0wJmFtcDtwdD0xJmFtcDtpbT0wJmFtcDtsPTEmYW1wO3A9MCZhbXA7cHU9MCZhbXA7Zj0zNTIzNjI=" /&amp;gt;
&amp;lt;/object&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p class="note"&gt;이거로 뭘 어쩌라는 거냐!&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://fontstruct.com/fontstructions/show/352362"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/213053.jpg" width="615" height="272" alt="ikoo.jpg" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;&lt;a href="http://www.fonthead.com/fonts/InfoBits"&gt;InfoBits (Icons &amp; Dingbats)&lt;/a&gt; &lt;em&gt;$19/$29&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;$19에 Things 또는 Symbols 중 하나를 구입하거나 $29에 둘 다 구입할 수 있는 유료 아이콘 글꼴입니다.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://www.fonthead.com/fonts/InfoBits"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/944922.gif" width="615" height="498" alt="infobits_sample2.gif" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;&lt;a href="http://pictos.cc/font/"&gt;Pictos&lt;/a&gt; &lt;em&gt;$49&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;Pictos는 웹 폰트 아이콘뿐만 아니라 다양한 벡터 아이콘을 판매합니다. Pictos 웹 폰트 역시 알파벳과 특수문자를 매핑하고 있으며, 총 94개로 구성되어 있습니다. MS나 EA, Adobe, 3M, Dropbox 등에서 Pictos의 매력적인 아이콘을 이용 중입니다. $49를 내고 웹 폰트 아이콘 셋을 내려받거나 년 $19/$49/$99 의 비용으로 Pictos 폰트 서버를 이용할 수 있습니다. 월 2만 5천 페이지뷰의 무료 플랜도 있으니 실험적으로 적용해 볼 수도 있겠습니다. 웹 폰트의 용량은 21~33KB이며, SVG 포맷은 67KB입니다.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://pictos.cc/font/"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/868994.png" width="615" height="224" alt="Pictos.png" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p class="note"&gt;아이콘의 디테일은 상당히 우수하지만, 문자와 혼용해서 사용할 때 기준선과 일치하지 않고 아이콘 치수가 불규칙하여 들쭉날쭉해 보이는 문제가 있습니다. 무턱대고 구입했으면 큰일 날 뻔 했네요.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://fortawesome.github.com/Font-Awesome/#overview"&gt;Font Awesome&lt;/a&gt; &lt;em&gt;Free&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;이 웹 폰트는 &lt;a href="http://twitter.github.com/bootstrap/"&gt;Bootstrap&lt;/a&gt; 인터페이스에 사용되도록 설계된 무료 아이콘 세트입니다. 총 220개의 깔끔한 아이콘들로 구성되어 있으며, CSS에서 제어할 수 있고, v2.0부터는 IE7까지 지원합니다. 누구나 수정할 수 있도록 벡터 아이콘 소스도 함께 제공하네요. 용량은 41~67KB이며, SVG 포맷은 128KB입니다.&lt;/p&gt;
&lt;div class="image-align center"&gt;&lt;a href="http://fortawesome.github.com/Font-Awesome/#overview"&gt;&lt;img src="http://firejune.cdn2.cafe24.com/attach/0918/120918025637030605/207811.png" width="615" height="340" alt="faicons2.png" class="reflect null"/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p class="note"&gt;UI 요소로 갖추어야 할 아이콘은 모두 갖추었다고 봐도 무방합니다. 아이콘의 디테일이나 문자와의 조합도 훌륭한 편이고요. 하지만 폰트당 용량이 다소 무겁고, 함께 제공되는 CSS를 이용하지 않을 때에는 16진수 코드만으로 아이콘을 호출합니다.&lt;/p&gt;

 &lt;br /&gt;&lt;br /&gt;
 &lt;a href="http://firejune.com/1763#p1763"&gt;Comments(2)&lt;/a&gt; | 
 &lt;a href="http://firejune.com/1763"&gt;Hits(25373)&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/U5k6MbKOUuY" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1763</feedburner:origLink></entry><entry><title type="text">PrismJS 문법 강조 언어 추가하기</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/firejune/~3/ubh9vu-wz04/1762" /><category term="웹개발" /><category term="자료" /><category term="자바스크립트" /><category term="PrismJS" /><category term="문법 강조" /><category term="Syntax" /><category term="Highlighter" /><category term="CSS" /><category term="HTML" /><category term="Bash" /><category term="JAVA" /><category term="Clojure" /><category term="Vim" /><category term="Ruby" /><category term="PHP" /><category term="Generic" /><category term="테마" /><author><name>파이어준</name></author><updated>2012-09-13T13:07:58-07:00</updated><id>http://firejune.com/1762</id><content type="html">&lt;p&gt; &lt;a href="http://firejune.com/1748/%EC%84%B9%EC%8B%9C%ED%95%9C+%EB%AC%B8%EB%B2%95+%EA%B0%95%EC%A1%B0%EA%B8%B0+-+Prism.js"&gt;얼마 전 소개&lt;/a&gt;했던 &lt;a href="http://prismjs.com/"&gt;PrismJS&lt;/a&gt;는 아직 HTML, CSS, JS만을 지원하고 있습니다. 지금 즈음 다른 언어를 지원하지 않을까 해서 살펴보니 역시나 있더군요. 제가 발견한 현재 확장 가능한 언어는 JAVA, PHP, Bash 그리고 모든 C 스타일 언어에 적용할 수 있는 Generic 등이 있습니다. 이 문법 강조 컴포넌트를 확장하려면 PrismJS를 포크한 각 개발자의 저장소에서 직접 가져와야 합니다. 몇몇 컴포넌트에서 사소한 문제를 발견했지만, 신속히 수정되고 있어 해결방법을 어렵지 않게 찾아낼 수 있었어요. 각 언어별 저장소 위치를 아래에 정리했습니다. PrismJS를 사용하는 분들은 참고하세요.&lt;/p&gt;
&lt;p&gt;Bash - &lt;a href="https://github.com/ktmud/prism/tree/gh-pages/components"&gt;https://github.com/ktmud/prism/tree/gh-pages/components&lt;/a&gt;&lt;br&gt;
JAVA - &lt;a href="https://github.com/thomasklemm/prism/tree/gh-pages/components"&gt;https://github.com/thomasklemm/prism/tree/gh-pages/components&lt;/a&gt;&lt;br&gt;
Clojure - &lt;a href="https://github.com/samflores/prism/tree/gh-pages/plugins"&gt;https://github.com/samflores/prism/tree/gh-pages/plugins&lt;/a&gt;&lt;br&gt;
Vim - &lt;a href="https://github.com/samflores/prism/tree/gh-pages/plugins"&gt;https://github.com/samflores/prism/tree/gh-pages/plugins&lt;/a&gt;&lt;br&gt;
Ruby - &lt;a href="https://github.com/samflores/prism/tree/gh-pages/plugins"&gt;https://github.com/samflores/prism/tree/gh-pages/plugins&lt;/a&gt;&lt;br&gt;
PHP - &lt;a href="https://github.com/Aaron3/prism/tree/php/components"&gt;https://github.com/Aaron3/prism/tree/php/components&lt;/a&gt;&lt;br&gt;
Generic - &lt;a href="https://github.com/Aaron3/prism/tree/generic/components"&gt;https://github.com/Aaron3/prism/tree/generic/components&lt;/a&gt;&lt;br&gt;
Okaidia(theme) - &lt;a href="https://github.com/ocodia/prism/tree"&gt;https://github.com/ocodia/prism/tree&lt;/a&gt;&lt;/p&gt;
&lt;p class="note"&gt;언어를 추가하는 방법은 아주 간단합니다. 컴포넌트 또는 플러그인 폴더에 있는 해당언어의 소스를 prism.js에 추가해 주세요.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/firejune/~4/ubh9vu-wz04" height="1" width="1"/&gt;</content><feedburner:origLink>http://firejune.com/1762</feedburner:origLink></entry></feed>
