├── .dockerignore ├── .gitignore ├── .tx └── config ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── app ├── badbrowser.html ├── favicon.ico ├── favicon_unread.ico ├── fonts │ ├── 400.svg │ ├── 400.ttf │ ├── 400.woff │ ├── 400.woff2 │ ├── 400c.woff2 │ ├── 400cn.woff2 │ ├── 400l.woff2 │ ├── 400ln.woff2 │ ├── 600.svg │ ├── 600.ttf │ ├── 600.woff │ ├── 600.woff2 │ ├── 600c.woff2 │ ├── 600cn.woff2 │ ├── 600l.woff2 │ └── 600ln.woff2 ├── img │ ├── Manytabs.png │ ├── Manytabs_2x.png │ ├── Telegram.png │ ├── Telegram.svg │ ├── Telegram72.png │ ├── Telegram72_2x.png │ ├── Telegram_2x.png │ ├── blank.gif │ ├── changelog │ │ └── card_wecandoit.png │ ├── emojisprite_0.png │ ├── emojisprite_1.png │ ├── emojisprite_2.png │ ├── emojisprite_3.png │ ├── emojisprite_4.png │ ├── icons │ │ ├── AboutLogos.png │ │ ├── AboutLogos_2x.png │ │ ├── General.png │ │ ├── General_2x.png │ │ ├── IconsetSmiles.png │ │ ├── IconsetSmiles_2x.png │ │ ├── IconsetW.png │ │ ├── IconsetW_2x.png │ │ ├── Major.png │ │ ├── Major_2x.png │ │ ├── MobileIcons.png │ │ ├── MobileIcons_2x.png │ │ ├── PhotoIcons.png │ │ ├── PhotoIcons_2x.png │ │ ├── ProfileIcons.png │ │ ├── ProfileIcons_2x.png │ │ ├── icon.svg │ │ ├── icon120.png │ │ ├── icon128.png │ │ ├── icon16.png │ │ ├── icon192.png │ │ ├── icon32.png │ │ ├── icon512.png │ │ ├── icon60.png │ │ ├── icon64.png │ │ └── icon90.png │ ├── iphone_home120.png │ ├── iphone_startup.png │ ├── logo_share.png │ ├── placeholders │ │ ├── DialogListAvatarSystem@2x.png │ │ ├── Fave.png │ │ ├── GroupAvatar1@2x.png │ │ ├── GroupAvatar2@2x.png │ │ ├── GroupAvatar3@2x.png │ │ ├── GroupAvatar4@2x.png │ │ ├── PhotoThumbConversation.gif │ │ ├── PhotoThumbModal.gif │ │ ├── UserAvatar1@2x.png │ │ ├── UserAvatar2@2x.png │ │ ├── UserAvatar3@2x.png │ │ ├── UserAvatar4@2x.png │ │ ├── UserAvatar5@2x.png │ │ ├── UserAvatar6@2x.png │ │ ├── UserAvatar7@2x.png │ │ ├── UserAvatar8@2x.png │ │ ├── VideoThumbConversation.gif │ │ └── VideoThumbModal.gif │ ├── screenshot1.png │ ├── screenshot2.png │ ├── screenshot3.png │ └── sound_a.mp3 ├── index.html ├── js │ ├── app.js │ ├── background.js │ ├── controllers.js │ ├── directives.js │ ├── directives_mobile.js │ ├── filters.js │ ├── init.js │ ├── lib │ │ ├── bin_utils.js │ │ ├── config.js │ │ ├── crypto_worker.js │ │ ├── i18n.js │ │ ├── mtproto.js │ │ ├── mtproto_wrapper.js │ │ ├── ng_utils.js │ │ ├── polyfill.js │ │ ├── push_worker.js │ │ ├── schema.tl │ │ ├── tl_utils.js │ │ └── utils.js │ ├── locales │ │ ├── README.md │ │ ├── de-de.json │ │ ├── en-us.json │ │ ├── es-es.json │ │ ├── it-it.json │ │ ├── nl-nl.json │ │ ├── pt-br.json │ │ └── ru-ru.json │ ├── message_composer.js │ ├── messages_manager.js │ ├── offline_manager.js │ └── services.js ├── less │ ├── app.less │ ├── desktop.less │ ├── font.less │ ├── lib │ │ └── mixins.less │ └── mobile.less ├── manifest.json ├── manifest.webapp ├── manifest.webapp.json ├── nacl │ ├── Makefile │ ├── aes.h │ ├── aes_core.c │ ├── aes_ige.c │ ├── aes_locl.h │ ├── aes_misc.c │ ├── mtproto_crypto.bc │ ├── mtproto_crypto.cc │ ├── mtproto_crypto.nmf │ └── mtproto_crypto.pexe ├── partials │ ├── desktop │ │ ├── audio_player.html │ │ ├── changelog_modal.html │ │ ├── channel_edit_modal.html │ │ ├── channel_modal.html │ │ ├── chat_create_modal.html │ │ ├── chat_edit_modal.html │ │ ├── chat_invite_link_modal.html │ │ ├── chat_modal.html │ │ ├── composer_dropdown.html │ │ ├── confirm_modal.html │ │ ├── contacts_modal.html │ │ ├── country_select_modal.html │ │ ├── dialog.html │ │ ├── document_modal.html │ │ ├── edit_contact_modal.html │ │ ├── embed_modal.html │ │ ├── emoji_btn_tooltip.html │ │ ├── error_modal.html │ │ ├── footer.html │ │ ├── forwarded_messages.html │ │ ├── full_document.html │ │ ├── full_gif.html │ │ ├── full_photo.html │ │ ├── full_round.html │ │ ├── full_video.html │ │ ├── game_modal.html │ │ ├── head.html │ │ ├── im.html │ │ ├── import_contact_modal.html │ │ ├── inactive.html │ │ ├── inline_results.html │ │ ├── lang_footer.html │ │ ├── login.html │ │ ├── media_modal_layout.html │ │ ├── megagroup_edit_modal.html │ │ ├── message.html │ │ ├── message_attach_contact.html │ │ ├── message_attach_document.html │ │ ├── message_attach_game.html │ │ ├── message_attach_geo.html │ │ ├── message_attach_pending.html │ │ ├── message_attach_photo.html │ │ ├── message_attach_venue.html │ │ ├── message_attach_webpage.html │ │ ├── message_media.html │ │ ├── message_service.html │ │ ├── password_recovery_modal.html │ │ ├── password_update_modal.html │ │ ├── peer_pinned_message_bar.html │ │ ├── peer_select.html │ │ ├── photo_modal.html │ │ ├── pinned_message.html │ │ ├── profile_edit_modal.html │ │ ├── reply_markup.html │ │ ├── reply_message.html │ │ ├── report_msgs_modal.html │ │ ├── send_form.html │ │ ├── sessions_list_modal.html │ │ ├── settings_modal.html │ │ ├── short_message.html │ │ ├── slider.html │ │ ├── stickerset_modal.html │ │ ├── user_modal.html │ │ ├── username_edit_modal.html │ │ └── video_modal.html │ └── mobile │ │ ├── audio_player.html │ │ ├── changelog_modal.html │ │ ├── channel_modal.html │ │ ├── chat_create_modal.html │ │ ├── chat_edit_modal.html │ │ ├── chat_modal.html │ │ ├── contacts_modal.html │ │ ├── country_select_modal.html │ │ ├── dialog.html │ │ ├── edit_contact_modal.html │ │ ├── full_gif.html │ │ ├── full_photo.html │ │ ├── full_video.html │ │ ├── game_modal.html │ │ ├── head.html │ │ ├── im.html │ │ ├── import_contact_modal.html │ │ ├── login.html │ │ ├── message.html │ │ ├── message_actions_modal.html │ │ ├── message_attach_contact.html │ │ ├── message_attach_document.html │ │ ├── message_attach_geo.html │ │ ├── message_attach_pending.html │ │ ├── message_attach_photo.html │ │ ├── message_attach_venue.html │ │ ├── message_attach_webpage.html │ │ ├── message_service.html │ │ ├── password_recovery_modal.html │ │ ├── password_update_modal.html │ │ ├── peer_select.html │ │ ├── phonebook_modal.html │ │ ├── photo_modal.html │ │ ├── profile_edit_modal.html │ │ ├── send_form.html │ │ ├── sessions_list_modal.html │ │ ├── settings_modal.html │ │ ├── stickerset_modal.html │ │ ├── user_modal.html │ │ ├── username_edit_modal.html │ │ └── video_modal.html ├── service_worker.js ├── vendor │ ├── README.md │ ├── angular-media-player │ │ └── angular-media-player.js │ ├── angular │ │ ├── angular-animate.js │ │ ├── angular-animate.min.js │ │ ├── angular-animate.min.js.map │ │ ├── angular-aria.js │ │ ├── angular-aria.min.js │ │ ├── angular-aria.min.js.map │ │ ├── angular-cookies.js │ │ ├── angular-cookies.min.js │ │ ├── angular-cookies.min.js.map │ │ ├── angular-csp.css │ │ ├── angular-loader.js │ │ ├── angular-loader.min.js │ │ ├── angular-loader.min.js.map │ │ ├── angular-message-format.js │ │ ├── angular-message-format.min.js │ │ ├── angular-message-format.min.js.map │ │ ├── angular-messages.js │ │ ├── angular-messages.min.js │ │ ├── angular-messages.min.js.map │ │ ├── angular-mocks.js │ │ ├── angular-parse-ext.js │ │ ├── angular-parse-ext.min.js │ │ ├── angular-parse-ext.min.js.map │ │ ├── angular-resource.js │ │ ├── angular-resource.min.js │ │ ├── angular-resource.min.js.map │ │ ├── angular-route.js │ │ ├── angular-route.min.js │ │ ├── angular-route.min.js.map │ │ ├── angular-sanitize.js │ │ ├── angular-sanitize.min.js │ │ ├── angular-sanitize.min.js.map │ │ ├── angular-touch.js │ │ ├── angular-touch.min.js │ │ ├── angular-touch.min.js.map │ │ ├── angular.js │ │ ├── angular.min.js │ │ ├── angular.min.js.map │ │ ├── errors.json │ │ ├── i18n │ │ │ ├── angular-locale_af-na.js │ │ │ ├── angular-locale_af-za.js │ │ │ ├── angular-locale_af.js │ │ │ ├── angular-locale_agq-cm.js │ │ │ ├── angular-locale_agq.js │ │ │ ├── angular-locale_ak-gh.js │ │ │ ├── angular-locale_ak.js │ │ │ ├── angular-locale_am-et.js │ │ │ ├── angular-locale_am.js │ │ │ ├── angular-locale_ar-001.js │ │ │ ├── angular-locale_ar-ae.js │ │ │ ├── angular-locale_ar-bh.js │ │ │ ├── angular-locale_ar-dj.js │ │ │ ├── angular-locale_ar-dz.js │ │ │ ├── angular-locale_ar-eg.js │ │ │ ├── angular-locale_ar-eh.js │ │ │ ├── angular-locale_ar-er.js │ │ │ ├── angular-locale_ar-il.js │ │ │ ├── angular-locale_ar-iq.js │ │ │ ├── angular-locale_ar-jo.js │ │ │ ├── angular-locale_ar-km.js │ │ │ ├── angular-locale_ar-kw.js │ │ │ ├── angular-locale_ar-lb.js │ │ │ ├── angular-locale_ar-ly.js │ │ │ ├── angular-locale_ar-ma.js │ │ │ ├── angular-locale_ar-mr.js │ │ │ ├── angular-locale_ar-om.js │ │ │ ├── angular-locale_ar-ps.js │ │ │ ├── angular-locale_ar-qa.js │ │ │ ├── angular-locale_ar-sa.js │ │ │ ├── angular-locale_ar-sd.js │ │ │ ├── angular-locale_ar-so.js │ │ │ ├── angular-locale_ar-ss.js │ │ │ ├── angular-locale_ar-sy.js │ │ │ ├── angular-locale_ar-td.js │ │ │ ├── angular-locale_ar-tn.js │ │ │ ├── angular-locale_ar-xb.js │ │ │ ├── angular-locale_ar-ye.js │ │ │ ├── angular-locale_ar.js │ │ │ ├── angular-locale_as-in.js │ │ │ ├── angular-locale_as.js │ │ │ ├── angular-locale_asa-tz.js │ │ │ ├── angular-locale_asa.js │ │ │ ├── angular-locale_ast-es.js │ │ │ ├── angular-locale_ast.js │ │ │ ├── angular-locale_az-cyrl-az.js │ │ │ ├── angular-locale_az-cyrl.js │ │ │ ├── angular-locale_az-latn-az.js │ │ │ ├── angular-locale_az-latn.js │ │ │ ├── angular-locale_az.js │ │ │ ├── angular-locale_bas-cm.js │ │ │ ├── angular-locale_bas.js │ │ │ ├── angular-locale_be-by.js │ │ │ ├── angular-locale_be.js │ │ │ ├── angular-locale_bem-zm.js │ │ │ ├── angular-locale_bem.js │ │ │ ├── angular-locale_bez-tz.js │ │ │ ├── angular-locale_bez.js │ │ │ ├── angular-locale_bg-bg.js │ │ │ ├── angular-locale_bg.js │ │ │ ├── angular-locale_bm-ml.js │ │ │ ├── angular-locale_bm.js │ │ │ ├── angular-locale_bn-bd.js │ │ │ ├── angular-locale_bn-in.js │ │ │ ├── angular-locale_bn.js │ │ │ ├── angular-locale_bo-cn.js │ │ │ ├── angular-locale_bo-in.js │ │ │ ├── angular-locale_bo.js │ │ │ ├── angular-locale_br-fr.js │ │ │ ├── angular-locale_br.js │ │ │ ├── angular-locale_brx-in.js │ │ │ ├── angular-locale_brx.js │ │ │ ├── angular-locale_bs-cyrl-ba.js │ │ │ ├── angular-locale_bs-cyrl.js │ │ │ ├── angular-locale_bs-latn-ba.js │ │ │ ├── angular-locale_bs-latn.js │ │ │ ├── angular-locale_bs.js │ │ │ ├── angular-locale_ca-ad.js │ │ │ ├── angular-locale_ca-es-valencia.js │ │ │ ├── angular-locale_ca-es.js │ │ │ ├── angular-locale_ca-fr.js │ │ │ ├── angular-locale_ca-it.js │ │ │ ├── angular-locale_ca.js │ │ │ ├── angular-locale_ce-ru.js │ │ │ ├── angular-locale_ce.js │ │ │ ├── angular-locale_cgg-ug.js │ │ │ ├── angular-locale_cgg.js │ │ │ ├── angular-locale_chr-us.js │ │ │ ├── angular-locale_chr.js │ │ │ ├── angular-locale_ckb-arab-iq.js │ │ │ ├── angular-locale_ckb-arab-ir.js │ │ │ ├── angular-locale_ckb-arab.js │ │ │ ├── angular-locale_ckb-iq.js │ │ │ ├── angular-locale_ckb-ir.js │ │ │ ├── angular-locale_ckb-latn-iq.js │ │ │ ├── angular-locale_ckb-latn.js │ │ │ ├── angular-locale_ckb.js │ │ │ ├── angular-locale_cs-cz.js │ │ │ ├── angular-locale_cs.js │ │ │ ├── angular-locale_cu-ru.js │ │ │ ├── angular-locale_cu.js │ │ │ ├── angular-locale_cy-gb.js │ │ │ ├── angular-locale_cy.js │ │ │ ├── angular-locale_da-dk.js │ │ │ ├── angular-locale_da-gl.js │ │ │ ├── angular-locale_da.js │ │ │ ├── angular-locale_dav-ke.js │ │ │ ├── angular-locale_dav.js │ │ │ ├── angular-locale_de-at.js │ │ │ ├── angular-locale_de-be.js │ │ │ ├── angular-locale_de-ch.js │ │ │ ├── angular-locale_de-de.js │ │ │ ├── angular-locale_de-it.js │ │ │ ├── angular-locale_de-li.js │ │ │ ├── angular-locale_de-lu.js │ │ │ ├── angular-locale_de.js │ │ │ ├── angular-locale_dje-ne.js │ │ │ ├── angular-locale_dje.js │ │ │ ├── angular-locale_dsb-de.js │ │ │ ├── angular-locale_dsb.js │ │ │ ├── angular-locale_dua-cm.js │ │ │ ├── angular-locale_dua.js │ │ │ ├── angular-locale_dyo-sn.js │ │ │ ├── angular-locale_dyo.js │ │ │ ├── angular-locale_dz-bt.js │ │ │ ├── angular-locale_dz.js │ │ │ ├── angular-locale_ebu-ke.js │ │ │ ├── angular-locale_ebu.js │ │ │ ├── angular-locale_ee-gh.js │ │ │ ├── angular-locale_ee-tg.js │ │ │ ├── angular-locale_ee.js │ │ │ ├── angular-locale_el-cy.js │ │ │ ├── angular-locale_el-gr.js │ │ │ ├── angular-locale_el.js │ │ │ ├── angular-locale_en-001.js │ │ │ ├── angular-locale_en-150.js │ │ │ ├── angular-locale_en-ag.js │ │ │ ├── angular-locale_en-ai.js │ │ │ ├── angular-locale_en-as.js │ │ │ ├── angular-locale_en-at.js │ │ │ ├── angular-locale_en-au.js │ │ │ ├── angular-locale_en-bb.js │ │ │ ├── angular-locale_en-be.js │ │ │ ├── angular-locale_en-bi.js │ │ │ ├── angular-locale_en-bm.js │ │ │ ├── angular-locale_en-bs.js │ │ │ ├── angular-locale_en-bw.js │ │ │ ├── angular-locale_en-bz.js │ │ │ ├── angular-locale_en-ca.js │ │ │ ├── angular-locale_en-cc.js │ │ │ ├── angular-locale_en-ch.js │ │ │ ├── angular-locale_en-ck.js │ │ │ ├── angular-locale_en-cm.js │ │ │ ├── angular-locale_en-cx.js │ │ │ ├── angular-locale_en-cy.js │ │ │ ├── angular-locale_en-de.js │ │ │ ├── angular-locale_en-dg.js │ │ │ ├── angular-locale_en-dk.js │ │ │ ├── angular-locale_en-dm.js │ │ │ ├── angular-locale_en-er.js │ │ │ ├── angular-locale_en-fi.js │ │ │ ├── angular-locale_en-fj.js │ │ │ ├── angular-locale_en-fk.js │ │ │ ├── angular-locale_en-fm.js │ │ │ ├── angular-locale_en-gb.js │ │ │ ├── angular-locale_en-gd.js │ │ │ ├── angular-locale_en-gg.js │ │ │ ├── angular-locale_en-gh.js │ │ │ ├── angular-locale_en-gi.js │ │ │ ├── angular-locale_en-gm.js │ │ │ ├── angular-locale_en-gu.js │ │ │ ├── angular-locale_en-gy.js │ │ │ ├── angular-locale_en-hk.js │ │ │ ├── angular-locale_en-ie.js │ │ │ ├── angular-locale_en-il.js │ │ │ ├── angular-locale_en-im.js │ │ │ ├── angular-locale_en-in.js │ │ │ ├── angular-locale_en-io.js │ │ │ ├── angular-locale_en-iso.js │ │ │ ├── angular-locale_en-je.js │ │ │ ├── angular-locale_en-jm.js │ │ │ ├── angular-locale_en-ke.js │ │ │ ├── angular-locale_en-ki.js │ │ │ ├── angular-locale_en-kn.js │ │ │ ├── angular-locale_en-ky.js │ │ │ ├── angular-locale_en-lc.js │ │ │ ├── angular-locale_en-lr.js │ │ │ ├── angular-locale_en-ls.js │ │ │ ├── angular-locale_en-mg.js │ │ │ ├── angular-locale_en-mh.js │ │ │ ├── angular-locale_en-mo.js │ │ │ ├── angular-locale_en-mp.js │ │ │ ├── angular-locale_en-ms.js │ │ │ ├── angular-locale_en-mt.js │ │ │ ├── angular-locale_en-mu.js │ │ │ ├── angular-locale_en-mw.js │ │ │ ├── angular-locale_en-my.js │ │ │ ├── angular-locale_en-na.js │ │ │ ├── angular-locale_en-nf.js │ │ │ ├── angular-locale_en-ng.js │ │ │ ├── angular-locale_en-nl.js │ │ │ ├── angular-locale_en-nr.js │ │ │ ├── angular-locale_en-nu.js │ │ │ ├── angular-locale_en-nz.js │ │ │ ├── angular-locale_en-pg.js │ │ │ ├── angular-locale_en-ph.js │ │ │ ├── angular-locale_en-pk.js │ │ │ ├── angular-locale_en-pn.js │ │ │ ├── angular-locale_en-pr.js │ │ │ ├── angular-locale_en-pw.js │ │ │ ├── angular-locale_en-rw.js │ │ │ ├── angular-locale_en-sb.js │ │ │ ├── angular-locale_en-sc.js │ │ │ ├── angular-locale_en-sd.js │ │ │ ├── angular-locale_en-se.js │ │ │ ├── angular-locale_en-sg.js │ │ │ ├── angular-locale_en-sh.js │ │ │ ├── angular-locale_en-si.js │ │ │ ├── angular-locale_en-sl.js │ │ │ ├── angular-locale_en-ss.js │ │ │ ├── angular-locale_en-sx.js │ │ │ ├── angular-locale_en-sz.js │ │ │ ├── angular-locale_en-tc.js │ │ │ ├── angular-locale_en-tk.js │ │ │ ├── angular-locale_en-to.js │ │ │ ├── angular-locale_en-tt.js │ │ │ ├── angular-locale_en-tv.js │ │ │ ├── angular-locale_en-tz.js │ │ │ ├── angular-locale_en-ug.js │ │ │ ├── angular-locale_en-um.js │ │ │ ├── angular-locale_en-us-posix.js │ │ │ ├── angular-locale_en-us.js │ │ │ ├── angular-locale_en-vc.js │ │ │ ├── angular-locale_en-vg.js │ │ │ ├── angular-locale_en-vi.js │ │ │ ├── angular-locale_en-vu.js │ │ │ ├── angular-locale_en-ws.js │ │ │ ├── angular-locale_en-xa.js │ │ │ ├── angular-locale_en-za.js │ │ │ ├── angular-locale_en-zm.js │ │ │ ├── angular-locale_en-zw.js │ │ │ ├── angular-locale_en.js │ │ │ ├── angular-locale_eo-001.js │ │ │ ├── angular-locale_eo.js │ │ │ ├── angular-locale_es-419.js │ │ │ ├── angular-locale_es-ar.js │ │ │ ├── angular-locale_es-bo.js │ │ │ ├── angular-locale_es-br.js │ │ │ ├── angular-locale_es-bz.js │ │ │ ├── angular-locale_es-cl.js │ │ │ ├── angular-locale_es-co.js │ │ │ ├── angular-locale_es-cr.js │ │ │ ├── angular-locale_es-cu.js │ │ │ ├── angular-locale_es-do.js │ │ │ ├── angular-locale_es-ea.js │ │ │ ├── angular-locale_es-ec.js │ │ │ ├── angular-locale_es-es.js │ │ │ ├── angular-locale_es-gq.js │ │ │ ├── angular-locale_es-gt.js │ │ │ ├── angular-locale_es-hn.js │ │ │ ├── angular-locale_es-ic.js │ │ │ ├── angular-locale_es-mx.js │ │ │ ├── angular-locale_es-ni.js │ │ │ ├── angular-locale_es-pa.js │ │ │ ├── angular-locale_es-pe.js │ │ │ ├── angular-locale_es-ph.js │ │ │ ├── angular-locale_es-pr.js │ │ │ ├── angular-locale_es-py.js │ │ │ ├── angular-locale_es-sv.js │ │ │ ├── angular-locale_es-us.js │ │ │ ├── angular-locale_es-uy.js │ │ │ ├── angular-locale_es-ve.js │ │ │ ├── angular-locale_es.js │ │ │ ├── angular-locale_et-ee.js │ │ │ ├── angular-locale_et.js │ │ │ ├── angular-locale_eu-es.js │ │ │ ├── angular-locale_eu.js │ │ │ ├── angular-locale_ewo-cm.js │ │ │ ├── angular-locale_ewo.js │ │ │ ├── angular-locale_fa-af.js │ │ │ ├── angular-locale_fa-ir.js │ │ │ ├── angular-locale_fa.js │ │ │ ├── angular-locale_ff-cm.js │ │ │ ├── angular-locale_ff-gn.js │ │ │ ├── angular-locale_ff-mr.js │ │ │ ├── angular-locale_ff-sn.js │ │ │ ├── angular-locale_ff.js │ │ │ ├── angular-locale_fi-fi.js │ │ │ ├── angular-locale_fi.js │ │ │ ├── angular-locale_fil-ph.js │ │ │ ├── angular-locale_fil.js │ │ │ ├── angular-locale_fo-dk.js │ │ │ ├── angular-locale_fo-fo.js │ │ │ ├── angular-locale_fo.js │ │ │ ├── angular-locale_fr-be.js │ │ │ ├── angular-locale_fr-bf.js │ │ │ ├── angular-locale_fr-bi.js │ │ │ ├── angular-locale_fr-bj.js │ │ │ ├── angular-locale_fr-bl.js │ │ │ ├── angular-locale_fr-ca.js │ │ │ ├── angular-locale_fr-cd.js │ │ │ ├── angular-locale_fr-cf.js │ │ │ ├── angular-locale_fr-cg.js │ │ │ ├── angular-locale_fr-ch.js │ │ │ ├── angular-locale_fr-ci.js │ │ │ ├── angular-locale_fr-cm.js │ │ │ ├── angular-locale_fr-dj.js │ │ │ ├── angular-locale_fr-dz.js │ │ │ ├── angular-locale_fr-fr.js │ │ │ ├── angular-locale_fr-ga.js │ │ │ ├── angular-locale_fr-gf.js │ │ │ ├── angular-locale_fr-gn.js │ │ │ ├── angular-locale_fr-gp.js │ │ │ ├── angular-locale_fr-gq.js │ │ │ ├── angular-locale_fr-ht.js │ │ │ ├── angular-locale_fr-km.js │ │ │ ├── angular-locale_fr-lu.js │ │ │ ├── angular-locale_fr-ma.js │ │ │ ├── angular-locale_fr-mc.js │ │ │ ├── angular-locale_fr-mf.js │ │ │ ├── angular-locale_fr-mg.js │ │ │ ├── angular-locale_fr-ml.js │ │ │ ├── angular-locale_fr-mq.js │ │ │ ├── angular-locale_fr-mr.js │ │ │ ├── angular-locale_fr-mu.js │ │ │ ├── angular-locale_fr-nc.js │ │ │ ├── angular-locale_fr-ne.js │ │ │ ├── angular-locale_fr-pf.js │ │ │ ├── angular-locale_fr-pm.js │ │ │ ├── angular-locale_fr-re.js │ │ │ ├── angular-locale_fr-rw.js │ │ │ ├── angular-locale_fr-sc.js │ │ │ ├── angular-locale_fr-sn.js │ │ │ ├── angular-locale_fr-sy.js │ │ │ ├── angular-locale_fr-td.js │ │ │ ├── angular-locale_fr-tg.js │ │ │ ├── angular-locale_fr-tn.js │ │ │ ├── angular-locale_fr-vu.js │ │ │ ├── angular-locale_fr-wf.js │ │ │ ├── angular-locale_fr-yt.js │ │ │ ├── angular-locale_fr.js │ │ │ ├── angular-locale_fur-it.js │ │ │ ├── angular-locale_fur.js │ │ │ ├── angular-locale_fy-nl.js │ │ │ ├── angular-locale_fy.js │ │ │ ├── angular-locale_ga-ie.js │ │ │ ├── angular-locale_ga.js │ │ │ ├── angular-locale_gd-gb.js │ │ │ ├── angular-locale_gd.js │ │ │ ├── angular-locale_gl-es.js │ │ │ ├── angular-locale_gl.js │ │ │ ├── angular-locale_gsw-ch.js │ │ │ ├── angular-locale_gsw-fr.js │ │ │ ├── angular-locale_gsw-li.js │ │ │ ├── angular-locale_gsw.js │ │ │ ├── angular-locale_gu-in.js │ │ │ ├── angular-locale_gu.js │ │ │ ├── angular-locale_guz-ke.js │ │ │ ├── angular-locale_guz.js │ │ │ ├── angular-locale_gv-im.js │ │ │ ├── angular-locale_gv.js │ │ │ ├── angular-locale_ha-gh.js │ │ │ ├── angular-locale_ha-ne.js │ │ │ ├── angular-locale_ha-ng.js │ │ │ ├── angular-locale_ha.js │ │ │ ├── angular-locale_haw-us.js │ │ │ ├── angular-locale_haw.js │ │ │ ├── angular-locale_he-il.js │ │ │ ├── angular-locale_he.js │ │ │ ├── angular-locale_hi-in.js │ │ │ ├── angular-locale_hi.js │ │ │ ├── angular-locale_hr-ba.js │ │ │ ├── angular-locale_hr-hr.js │ │ │ ├── angular-locale_hr.js │ │ │ ├── angular-locale_hsb-de.js │ │ │ ├── angular-locale_hsb.js │ │ │ ├── angular-locale_hu-hu.js │ │ │ ├── angular-locale_hu.js │ │ │ ├── angular-locale_hy-am.js │ │ │ ├── angular-locale_hy.js │ │ │ ├── angular-locale_id-id.js │ │ │ ├── angular-locale_id.js │ │ │ ├── angular-locale_ig-ng.js │ │ │ ├── angular-locale_ig.js │ │ │ ├── angular-locale_ii-cn.js │ │ │ ├── angular-locale_ii.js │ │ │ ├── angular-locale_in.js │ │ │ ├── angular-locale_is-is.js │ │ │ ├── angular-locale_is.js │ │ │ ├── angular-locale_it-ch.js │ │ │ ├── angular-locale_it-it.js │ │ │ ├── angular-locale_it-sm.js │ │ │ ├── angular-locale_it-va.js │ │ │ ├── angular-locale_it.js │ │ │ ├── angular-locale_iw.js │ │ │ ├── angular-locale_ja-jp.js │ │ │ ├── angular-locale_ja.js │ │ │ ├── angular-locale_jgo-cm.js │ │ │ ├── angular-locale_jgo.js │ │ │ ├── angular-locale_jmc-tz.js │ │ │ ├── angular-locale_jmc.js │ │ │ ├── angular-locale_ka-ge.js │ │ │ ├── angular-locale_ka.js │ │ │ ├── angular-locale_kab-dz.js │ │ │ ├── angular-locale_kab.js │ │ │ ├── angular-locale_kam-ke.js │ │ │ ├── angular-locale_kam.js │ │ │ ├── angular-locale_kde-tz.js │ │ │ ├── angular-locale_kde.js │ │ │ ├── angular-locale_kea-cv.js │ │ │ ├── angular-locale_kea.js │ │ │ ├── angular-locale_khq-ml.js │ │ │ ├── angular-locale_khq.js │ │ │ ├── angular-locale_ki-ke.js │ │ │ ├── angular-locale_ki.js │ │ │ ├── angular-locale_kk-kz.js │ │ │ ├── angular-locale_kk.js │ │ │ ├── angular-locale_kkj-cm.js │ │ │ ├── angular-locale_kkj.js │ │ │ ├── angular-locale_kl-gl.js │ │ │ ├── angular-locale_kl.js │ │ │ ├── angular-locale_kln-ke.js │ │ │ ├── angular-locale_kln.js │ │ │ ├── angular-locale_km-kh.js │ │ │ ├── angular-locale_km.js │ │ │ ├── angular-locale_kn-in.js │ │ │ ├── angular-locale_kn.js │ │ │ ├── angular-locale_ko-kp.js │ │ │ ├── angular-locale_ko-kr.js │ │ │ ├── angular-locale_ko.js │ │ │ ├── angular-locale_kok-in.js │ │ │ ├── angular-locale_kok.js │ │ │ ├── angular-locale_ks-in.js │ │ │ ├── angular-locale_ks.js │ │ │ ├── angular-locale_ksb-tz.js │ │ │ ├── angular-locale_ksb.js │ │ │ ├── angular-locale_ksf-cm.js │ │ │ ├── angular-locale_ksf.js │ │ │ ├── angular-locale_ksh-de.js │ │ │ ├── angular-locale_ksh.js │ │ │ ├── angular-locale_kw-gb.js │ │ │ ├── angular-locale_kw.js │ │ │ ├── angular-locale_ky-kg.js │ │ │ ├── angular-locale_ky.js │ │ │ ├── angular-locale_lag-tz.js │ │ │ ├── angular-locale_lag.js │ │ │ ├── angular-locale_lb-lu.js │ │ │ ├── angular-locale_lb.js │ │ │ ├── angular-locale_lg-ug.js │ │ │ ├── angular-locale_lg.js │ │ │ ├── angular-locale_lkt-us.js │ │ │ ├── angular-locale_lkt.js │ │ │ ├── angular-locale_ln-ao.js │ │ │ ├── angular-locale_ln-cd.js │ │ │ ├── angular-locale_ln-cf.js │ │ │ ├── angular-locale_ln-cg.js │ │ │ ├── angular-locale_ln.js │ │ │ ├── angular-locale_lo-la.js │ │ │ ├── angular-locale_lo.js │ │ │ ├── angular-locale_lrc-iq.js │ │ │ ├── angular-locale_lrc-ir.js │ │ │ ├── angular-locale_lrc.js │ │ │ ├── angular-locale_lt-lt.js │ │ │ ├── angular-locale_lt.js │ │ │ ├── angular-locale_lu-cd.js │ │ │ ├── angular-locale_lu.js │ │ │ ├── angular-locale_luo-ke.js │ │ │ ├── angular-locale_luo.js │ │ │ ├── angular-locale_luy-ke.js │ │ │ ├── angular-locale_luy.js │ │ │ ├── angular-locale_lv-lv.js │ │ │ ├── angular-locale_lv.js │ │ │ ├── angular-locale_mas-ke.js │ │ │ ├── angular-locale_mas-tz.js │ │ │ ├── angular-locale_mas.js │ │ │ ├── angular-locale_mer-ke.js │ │ │ ├── angular-locale_mer.js │ │ │ ├── angular-locale_mfe-mu.js │ │ │ ├── angular-locale_mfe.js │ │ │ ├── angular-locale_mg-mg.js │ │ │ ├── angular-locale_mg.js │ │ │ ├── angular-locale_mgh-mz.js │ │ │ ├── angular-locale_mgh.js │ │ │ ├── angular-locale_mgo-cm.js │ │ │ ├── angular-locale_mgo.js │ │ │ ├── angular-locale_mk-mk.js │ │ │ ├── angular-locale_mk.js │ │ │ ├── angular-locale_ml-in.js │ │ │ ├── angular-locale_ml.js │ │ │ ├── angular-locale_mn-mn.js │ │ │ ├── angular-locale_mn.js │ │ │ ├── angular-locale_mo.js │ │ │ ├── angular-locale_mr-in.js │ │ │ ├── angular-locale_mr.js │ │ │ ├── angular-locale_ms-bn.js │ │ │ ├── angular-locale_ms-my.js │ │ │ ├── angular-locale_ms-sg.js │ │ │ ├── angular-locale_ms.js │ │ │ ├── angular-locale_mt-mt.js │ │ │ ├── angular-locale_mt.js │ │ │ ├── angular-locale_mua-cm.js │ │ │ ├── angular-locale_mua.js │ │ │ ├── angular-locale_my-mm.js │ │ │ ├── angular-locale_my.js │ │ │ ├── angular-locale_mzn-ir.js │ │ │ ├── angular-locale_mzn.js │ │ │ ├── angular-locale_naq-na.js │ │ │ ├── angular-locale_naq.js │ │ │ ├── angular-locale_nb-no.js │ │ │ ├── angular-locale_nb-sj.js │ │ │ ├── angular-locale_nb.js │ │ │ ├── angular-locale_nd-zw.js │ │ │ ├── angular-locale_nd.js │ │ │ ├── angular-locale_nds-de.js │ │ │ ├── angular-locale_nds-nl.js │ │ │ ├── angular-locale_nds.js │ │ │ ├── angular-locale_ne-in.js │ │ │ ├── angular-locale_ne-np.js │ │ │ ├── angular-locale_ne.js │ │ │ ├── angular-locale_nl-aw.js │ │ │ ├── angular-locale_nl-be.js │ │ │ ├── angular-locale_nl-bq.js │ │ │ ├── angular-locale_nl-cw.js │ │ │ ├── angular-locale_nl-nl.js │ │ │ ├── angular-locale_nl-sr.js │ │ │ ├── angular-locale_nl-sx.js │ │ │ ├── angular-locale_nl.js │ │ │ ├── angular-locale_nmg-cm.js │ │ │ ├── angular-locale_nmg.js │ │ │ ├── angular-locale_nn-no.js │ │ │ ├── angular-locale_nn.js │ │ │ ├── angular-locale_nnh-cm.js │ │ │ ├── angular-locale_nnh.js │ │ │ ├── angular-locale_no-no.js │ │ │ ├── angular-locale_no.js │ │ │ ├── angular-locale_nus-ss.js │ │ │ ├── angular-locale_nus.js │ │ │ ├── angular-locale_nyn-ug.js │ │ │ ├── angular-locale_nyn.js │ │ │ ├── angular-locale_om-et.js │ │ │ ├── angular-locale_om-ke.js │ │ │ ├── angular-locale_om.js │ │ │ ├── angular-locale_or-in.js │ │ │ ├── angular-locale_or.js │ │ │ ├── angular-locale_os-ge.js │ │ │ ├── angular-locale_os-ru.js │ │ │ ├── angular-locale_os.js │ │ │ ├── angular-locale_pa-arab-pk.js │ │ │ ├── angular-locale_pa-arab.js │ │ │ ├── angular-locale_pa-guru-in.js │ │ │ ├── angular-locale_pa-guru.js │ │ │ ├── angular-locale_pa.js │ │ │ ├── angular-locale_pl-pl.js │ │ │ ├── angular-locale_pl.js │ │ │ ├── angular-locale_prg-001.js │ │ │ ├── angular-locale_prg.js │ │ │ ├── angular-locale_ps-af.js │ │ │ ├── angular-locale_ps.js │ │ │ ├── angular-locale_pt-ao.js │ │ │ ├── angular-locale_pt-br.js │ │ │ ├── angular-locale_pt-ch.js │ │ │ ├── angular-locale_pt-cv.js │ │ │ ├── angular-locale_pt-gq.js │ │ │ ├── angular-locale_pt-gw.js │ │ │ ├── angular-locale_pt-lu.js │ │ │ ├── angular-locale_pt-mo.js │ │ │ ├── angular-locale_pt-mz.js │ │ │ ├── angular-locale_pt-pt.js │ │ │ ├── angular-locale_pt-st.js │ │ │ ├── angular-locale_pt-tl.js │ │ │ ├── angular-locale_pt.js │ │ │ ├── angular-locale_qu-bo.js │ │ │ ├── angular-locale_qu-ec.js │ │ │ ├── angular-locale_qu-pe.js │ │ │ ├── angular-locale_qu.js │ │ │ ├── angular-locale_rm-ch.js │ │ │ ├── angular-locale_rm.js │ │ │ ├── angular-locale_rn-bi.js │ │ │ ├── angular-locale_rn.js │ │ │ ├── angular-locale_ro-md.js │ │ │ ├── angular-locale_ro-ro.js │ │ │ ├── angular-locale_ro.js │ │ │ ├── angular-locale_rof-tz.js │ │ │ ├── angular-locale_rof.js │ │ │ ├── angular-locale_ru-by.js │ │ │ ├── angular-locale_ru-kg.js │ │ │ ├── angular-locale_ru-kz.js │ │ │ ├── angular-locale_ru-md.js │ │ │ ├── angular-locale_ru-ru.js │ │ │ ├── angular-locale_ru-ua.js │ │ │ ├── angular-locale_ru.js │ │ │ ├── angular-locale_rw-rw.js │ │ │ ├── angular-locale_rw.js │ │ │ ├── angular-locale_rwk-tz.js │ │ │ ├── angular-locale_rwk.js │ │ │ ├── angular-locale_sah-ru.js │ │ │ ├── angular-locale_sah.js │ │ │ ├── angular-locale_saq-ke.js │ │ │ ├── angular-locale_saq.js │ │ │ ├── angular-locale_sbp-tz.js │ │ │ ├── angular-locale_sbp.js │ │ │ ├── angular-locale_se-fi.js │ │ │ ├── angular-locale_se-no.js │ │ │ ├── angular-locale_se-se.js │ │ │ ├── angular-locale_se.js │ │ │ ├── angular-locale_seh-mz.js │ │ │ ├── angular-locale_seh.js │ │ │ ├── angular-locale_ses-ml.js │ │ │ ├── angular-locale_ses.js │ │ │ ├── angular-locale_sg-cf.js │ │ │ ├── angular-locale_sg.js │ │ │ ├── angular-locale_sh.js │ │ │ ├── angular-locale_shi-latn-ma.js │ │ │ ├── angular-locale_shi-latn.js │ │ │ ├── angular-locale_shi-tfng-ma.js │ │ │ ├── angular-locale_shi-tfng.js │ │ │ ├── angular-locale_shi.js │ │ │ ├── angular-locale_si-lk.js │ │ │ ├── angular-locale_si.js │ │ │ ├── angular-locale_sk-sk.js │ │ │ ├── angular-locale_sk.js │ │ │ ├── angular-locale_sl-si.js │ │ │ ├── angular-locale_sl.js │ │ │ ├── angular-locale_smn-fi.js │ │ │ ├── angular-locale_smn.js │ │ │ ├── angular-locale_sn-zw.js │ │ │ ├── angular-locale_sn.js │ │ │ ├── angular-locale_so-dj.js │ │ │ ├── angular-locale_so-et.js │ │ │ ├── angular-locale_so-ke.js │ │ │ ├── angular-locale_so-so.js │ │ │ ├── angular-locale_so.js │ │ │ ├── angular-locale_sq-al.js │ │ │ ├── angular-locale_sq-mk.js │ │ │ ├── angular-locale_sq-xk.js │ │ │ ├── angular-locale_sq.js │ │ │ ├── angular-locale_sr-cyrl-ba.js │ │ │ ├── angular-locale_sr-cyrl-me.js │ │ │ ├── angular-locale_sr-cyrl-rs.js │ │ │ ├── angular-locale_sr-cyrl-xk.js │ │ │ ├── angular-locale_sr-cyrl.js │ │ │ ├── angular-locale_sr-latn-ba.js │ │ │ ├── angular-locale_sr-latn-me.js │ │ │ ├── angular-locale_sr-latn-rs.js │ │ │ ├── angular-locale_sr-latn-xk.js │ │ │ ├── angular-locale_sr-latn.js │ │ │ ├── angular-locale_sr.js │ │ │ ├── angular-locale_sv-ax.js │ │ │ ├── angular-locale_sv-fi.js │ │ │ ├── angular-locale_sv-se.js │ │ │ ├── angular-locale_sv.js │ │ │ ├── angular-locale_sw-cd.js │ │ │ ├── angular-locale_sw-ke.js │ │ │ ├── angular-locale_sw-tz.js │ │ │ ├── angular-locale_sw-ug.js │ │ │ ├── angular-locale_sw.js │ │ │ ├── angular-locale_ta-in.js │ │ │ ├── angular-locale_ta-lk.js │ │ │ ├── angular-locale_ta-my.js │ │ │ ├── angular-locale_ta-sg.js │ │ │ ├── angular-locale_ta.js │ │ │ ├── angular-locale_te-in.js │ │ │ ├── angular-locale_te.js │ │ │ ├── angular-locale_teo-ke.js │ │ │ ├── angular-locale_teo-ug.js │ │ │ ├── angular-locale_teo.js │ │ │ ├── angular-locale_th-th.js │ │ │ ├── angular-locale_th.js │ │ │ ├── angular-locale_ti-er.js │ │ │ ├── angular-locale_ti-et.js │ │ │ ├── angular-locale_ti.js │ │ │ ├── angular-locale_tk-tm.js │ │ │ ├── angular-locale_tk.js │ │ │ ├── angular-locale_tl.js │ │ │ ├── angular-locale_to-to.js │ │ │ ├── angular-locale_to.js │ │ │ ├── angular-locale_tr-cy.js │ │ │ ├── angular-locale_tr-tr.js │ │ │ ├── angular-locale_tr.js │ │ │ ├── angular-locale_twq-ne.js │ │ │ ├── angular-locale_twq.js │ │ │ ├── angular-locale_tzm-ma.js │ │ │ ├── angular-locale_tzm.js │ │ │ ├── angular-locale_ug-cn.js │ │ │ ├── angular-locale_ug.js │ │ │ ├── angular-locale_uk-ua.js │ │ │ ├── angular-locale_uk.js │ │ │ ├── angular-locale_ur-in.js │ │ │ ├── angular-locale_ur-pk.js │ │ │ ├── angular-locale_ur.js │ │ │ ├── angular-locale_uz-arab-af.js │ │ │ ├── angular-locale_uz-arab.js │ │ │ ├── angular-locale_uz-cyrl-uz.js │ │ │ ├── angular-locale_uz-cyrl.js │ │ │ ├── angular-locale_uz-latn-uz.js │ │ │ ├── angular-locale_uz-latn.js │ │ │ ├── angular-locale_uz.js │ │ │ ├── angular-locale_vai-latn-lr.js │ │ │ ├── angular-locale_vai-latn.js │ │ │ ├── angular-locale_vai-vaii-lr.js │ │ │ ├── angular-locale_vai-vaii.js │ │ │ ├── angular-locale_vai.js │ │ │ ├── angular-locale_vi-vn.js │ │ │ ├── angular-locale_vi.js │ │ │ ├── angular-locale_vo-001.js │ │ │ ├── angular-locale_vo.js │ │ │ ├── angular-locale_vun-tz.js │ │ │ ├── angular-locale_vun.js │ │ │ ├── angular-locale_wae-ch.js │ │ │ ├── angular-locale_wae.js │ │ │ ├── angular-locale_xog-ug.js │ │ │ ├── angular-locale_xog.js │ │ │ ├── angular-locale_yav-cm.js │ │ │ ├── angular-locale_yav.js │ │ │ ├── angular-locale_yi-001.js │ │ │ ├── angular-locale_yi.js │ │ │ ├── angular-locale_yo-bj.js │ │ │ ├── angular-locale_yo-ng.js │ │ │ ├── angular-locale_yo.js │ │ │ ├── angular-locale_yue-hk.js │ │ │ ├── angular-locale_yue.js │ │ │ ├── angular-locale_zgh-ma.js │ │ │ ├── angular-locale_zgh.js │ │ │ ├── angular-locale_zh-cn.js │ │ │ ├── angular-locale_zh-hans-cn.js │ │ │ ├── angular-locale_zh-hans-hk.js │ │ │ ├── angular-locale_zh-hans-mo.js │ │ │ ├── angular-locale_zh-hans-sg.js │ │ │ ├── angular-locale_zh-hans.js │ │ │ ├── angular-locale_zh-hant-hk.js │ │ │ ├── angular-locale_zh-hant-mo.js │ │ │ ├── angular-locale_zh-hant-tw.js │ │ │ ├── angular-locale_zh-hant.js │ │ │ ├── angular-locale_zh-hk.js │ │ │ ├── angular-locale_zh-tw.js │ │ │ ├── angular-locale_zh.js │ │ │ ├── angular-locale_zu-za.js │ │ │ └── angular-locale_zu.js │ │ ├── sitemap.xml │ │ ├── test-bundles │ │ │ ├── angular-aria.js │ │ │ ├── angular-cookies.js │ │ │ ├── angular-message-format.js │ │ │ ├── angular-messages.js │ │ │ ├── angular-resource.js │ │ │ ├── angular-route.js │ │ │ ├── angular-sanitize.js │ │ │ └── angular-touch.js │ │ ├── version.json │ │ └── version.txt │ ├── angularjs-toaster │ │ ├── toaster.css │ │ ├── toaster.js │ │ ├── toaster.min.css │ │ └── toaster.min.js │ ├── bootstrap │ │ ├── config.json │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ └── bootstrap.min.css │ │ └── js │ │ │ ├── bootstrap.js │ │ │ └── bootstrap.min.js │ ├── clipboard │ │ └── clipboard.js │ ├── closure │ │ └── long.js │ ├── console-polyfill │ │ └── console-polyfill.js │ ├── cryptoJS │ │ ├── THIRDPARTY_LICENSE │ │ └── crypto.js │ ├── jquery.emojiarea │ │ ├── jquery.emojiarea-orig.js │ │ └── jquery.emojiarea.js │ ├── jquery.nanoscroller │ │ ├── nanoscroller.css │ │ └── nanoscroller.js │ ├── jquery │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ └── jquery.min.map │ ├── jsbn │ │ ├── THIRDPARTY_LICENSE │ │ └── jsbn_combined.js │ ├── leemon_bigint │ │ └── bigint.js │ ├── libwebpjs │ │ ├── libwebp-0.1.13.js │ │ ├── libwebp-0.2.0.js │ │ └── libwebp-0.2.0.min.js │ ├── ogv.js │ │ ├── COPYING │ │ ├── COPYING-ogg.txt │ │ ├── COPYING-opus.txt │ │ ├── COPYING-theora.txt │ │ ├── COPYING-vorbis.txt │ │ ├── LICENSE-nestegg.txt │ │ ├── LICENSE-vpx.txt │ │ ├── PATENTS-vpx.txt │ │ ├── README.md │ │ ├── dynamicaudio.swf │ │ ├── ogv-decoder-audio-opus-wasm.js │ │ ├── ogv-decoder-audio-opus-wasm.wasm │ │ ├── ogv-decoder-audio-opus.js │ │ ├── ogv-decoder-audio-vorbis-wasm.js │ │ ├── ogv-decoder-audio-vorbis-wasm.wasm │ │ ├── ogv-decoder-audio-vorbis.js │ │ ├── ogv-decoder-video-theora-wasm.js │ │ ├── ogv-decoder-video-theora-wasm.wasm │ │ ├── ogv-decoder-video-theora.js │ │ ├── ogv-decoder-video-vp8-mt.js │ │ ├── ogv-decoder-video-vp8-wasm.js │ │ ├── ogv-decoder-video-vp8-wasm.wasm │ │ ├── ogv-decoder-video-vp8.js │ │ ├── ogv-decoder-video-vp9-mt.js │ │ ├── ogv-decoder-video-vp9-wasm.js │ │ ├── ogv-decoder-video-vp9-wasm.wasm │ │ ├── ogv-decoder-video-vp9.js │ │ ├── ogv-demuxer-ogg-wasm.js │ │ ├── ogv-demuxer-ogg-wasm.wasm │ │ ├── ogv-demuxer-ogg.js │ │ ├── ogv-demuxer-webm-wasm.js │ │ ├── ogv-demuxer-webm-wasm.wasm │ │ ├── ogv-demuxer-webm.js │ │ ├── ogv-support.js │ │ ├── ogv-version.js │ │ ├── ogv-worker-audio.js │ │ ├── ogv-worker-video.js │ │ ├── ogv.js │ │ └── pthread-main.js │ ├── recorderjs │ │ ├── encoder_worker.js │ │ ├── recorder.js │ │ └── recorder.min.js │ ├── rusha │ │ └── rusha.js │ ├── ui-bootstrap │ │ ├── THIRDPARTY_LICENSE │ │ └── ui-bootstrap-custom-tpls-0.12.0.js │ └── zlib │ │ ├── THIRDPARTY_LICENSE │ │ ├── gunzip.min.js │ │ ├── gunzip.min.js.map │ │ ├── gzip.min.js │ │ └── gzip.min.js.map └── webogram.appcache ├── gulpfile.js ├── karma.conf.js ├── package-lock.json ├── package.json ├── scripts ├── cldr_localize.js ├── emoji_data │ ├── build.php │ └── emoji.json ├── google_fonts_download.sh └── ua_handler.js ├── test ├── test-init.js └── unit │ ├── controllers │ ├── AppFooterControllerSpec.js │ ├── AppImPanelControllerSpec.js │ ├── AppLangSelectControllerSpec.js │ ├── AppWelcomeControllerSpec.js │ ├── ChangelogModalControlelerSpec.js │ ├── CountrySelectModalControllerSpec.js │ ├── DocumentModalControllerSpec.js │ ├── EmbedModalController.js │ ├── ImportContactModalControllerSpec.js │ ├── PasswordRecoveryModalControllerSpec.js │ ├── PeerSelectControllerSpec.js │ ├── ProfileEditModalControllerSpec.js │ ├── UsernameEditModalControllerSpec.js │ └── VideoModalControllerSpec.js │ ├── directives │ ├── myHeadDirective.js │ └── myLangFooterDirective.js │ ├── filters │ ├── chatTitleFilterSpec.js │ ├── dateOrTimeFilterSpec.js │ ├── durationFilterSpec.js │ ├── durationRemainsFilterSpec.js │ ├── formatShortNumberFilterSpec.js │ ├── formatSizeFilterSpec.js │ ├── formatSizeProgressFilterSpec.js │ ├── myDateFilterSpec.js │ ├── nl2brFilterSpec.js │ ├── phoneNumberFilterSpec.js │ ├── realtiveTimeFilterSpec.js │ ├── richTextFilterSpec.js │ ├── shortUrlFilterSpec.js │ ├── timeFilterSpec.js │ ├── userFirstNameFilterSpec.js │ ├── userNameFilterSpec.js │ └── userStatusFilterSpec.js │ └── services │ └── PhonebookContactsServiceSpec.js ├── update-angular.sh └── webogram.sublime-project /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | .publish 4 | *.sublime-workspace 5 | *.*~ 6 | *.swp 7 | 8 | # Node.js package manager 9 | node_modules 10 | npm-debug.log 11 | dist 12 | dist_package 13 | releases 14 | webogram*.zip 15 | app/js/templates.js 16 | app/css 17 | cldr 18 | coverage/ 19 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [telegram-web.en-usjson] 5 | file_filter = app/js/locales/.json 6 | lang_map = de:de-de, es:es-es, it:it-it, ru:ru-ru, nl:nl-nl, pt_BR:pt-br 7 | source_file = app/js/locales/en-us.json 8 | source_lang = en_US 9 | type = KEYVALUEJSON 10 | 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node 2 | 3 | ADD . /opt/webogram 4 | WORKDIR /opt/webogram 5 | 6 | RUN npm install -g gulp && npm install 7 | 8 | EXPOSE 8000 9 | 10 | CMD ["gulp", "watch"] 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | package: 2 | rm -rf dist_package 3 | ./node_modules/gulp/bin/gulp.js clean 4 | ./node_modules/gulp/bin/gulp.js package 5 | cp -r dist dist_package 6 | find dist_package | grep "\.git\|DS_Store\|.swp" | xargs rm -rf 7 | cd dist_package && zip -r ../releases/webogram_v$(version).zip . 8 | 9 | ghdist: 10 | rm -rf dist 11 | mkdir dist 12 | cp -r .git dist/ 13 | cd dist && git checkout gh-pages 14 | 15 | publish: 16 | ./node_modules/gulp/bin/gulp.js clean 17 | cd dist && git pull origin gh-pages 18 | ./node_modules/gulp/bin/gulp.js publish 19 | echo -n "Please open http://localhost:8000/dist/index.html and check if everything works fine." && read -e 20 | cd dist && git add --all . && git commit -am "merged with master" && git push origin gh-pages 21 | 22 | bump: 23 | ./node_modules/gulp/bin/gulp.js bump 24 | 25 | txinstall: 26 | curl -O https://raw.githubusercontent.com/pypa/pip/master/contrib/get-pip.py 27 | sudo python get-pip.py 28 | sudo pip install transifex-client 29 | 30 | txupdate: 31 | tx pull -f 32 | 33 | txupload: 34 | tx pull -f 35 | tx push -s 36 | -------------------------------------------------------------------------------- /app/badbrowser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Telegram Web 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |

Your browser is outdated!

23 | 24 |
25 |

26 | Don't take this personally, but your browser is too old to run Telegram Web.
27 | We require HTML5 support for the MTProto secure messaging protocol to work. 28 |

29 |

30 | Unfortunately, your current browser doesn't support HTML5.
31 | Please download a modern browser or update to latest version and come back soon! 32 |

33 |
34 | 35 | 36 | Download Mozilla Firefox 37 | Download Google Chrome 38 | 39 |
40 | 41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/favicon.ico -------------------------------------------------------------------------------- /app/favicon_unread.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/favicon_unread.ico -------------------------------------------------------------------------------- /app/fonts/400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/400.ttf -------------------------------------------------------------------------------- /app/fonts/400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/400.woff -------------------------------------------------------------------------------- /app/fonts/400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/400.woff2 -------------------------------------------------------------------------------- /app/fonts/400c.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/400c.woff2 -------------------------------------------------------------------------------- /app/fonts/400cn.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/400cn.woff2 -------------------------------------------------------------------------------- /app/fonts/400l.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/400l.woff2 -------------------------------------------------------------------------------- /app/fonts/400ln.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/400ln.woff2 -------------------------------------------------------------------------------- /app/fonts/600.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/600.ttf -------------------------------------------------------------------------------- /app/fonts/600.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/600.woff -------------------------------------------------------------------------------- /app/fonts/600.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/600.woff2 -------------------------------------------------------------------------------- /app/fonts/600c.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/600c.woff2 -------------------------------------------------------------------------------- /app/fonts/600cn.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/600cn.woff2 -------------------------------------------------------------------------------- /app/fonts/600l.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/600l.woff2 -------------------------------------------------------------------------------- /app/fonts/600ln.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/fonts/600ln.woff2 -------------------------------------------------------------------------------- /app/img/Manytabs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/Manytabs.png -------------------------------------------------------------------------------- /app/img/Manytabs_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/Manytabs_2x.png -------------------------------------------------------------------------------- /app/img/Telegram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/Telegram.png -------------------------------------------------------------------------------- /app/img/Telegram72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/Telegram72.png -------------------------------------------------------------------------------- /app/img/Telegram72_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/Telegram72_2x.png -------------------------------------------------------------------------------- /app/img/Telegram_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/Telegram_2x.png -------------------------------------------------------------------------------- /app/img/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/blank.gif -------------------------------------------------------------------------------- /app/img/changelog/card_wecandoit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/changelog/card_wecandoit.png -------------------------------------------------------------------------------- /app/img/emojisprite_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/emojisprite_0.png -------------------------------------------------------------------------------- /app/img/emojisprite_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/emojisprite_1.png -------------------------------------------------------------------------------- /app/img/emojisprite_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/emojisprite_2.png -------------------------------------------------------------------------------- /app/img/emojisprite_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/emojisprite_3.png -------------------------------------------------------------------------------- /app/img/emojisprite_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/emojisprite_4.png -------------------------------------------------------------------------------- /app/img/icons/AboutLogos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/AboutLogos.png -------------------------------------------------------------------------------- /app/img/icons/AboutLogos_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/AboutLogos_2x.png -------------------------------------------------------------------------------- /app/img/icons/General.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/General.png -------------------------------------------------------------------------------- /app/img/icons/General_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/General_2x.png -------------------------------------------------------------------------------- /app/img/icons/IconsetSmiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/IconsetSmiles.png -------------------------------------------------------------------------------- /app/img/icons/IconsetSmiles_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/IconsetSmiles_2x.png -------------------------------------------------------------------------------- /app/img/icons/IconsetW.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/IconsetW.png -------------------------------------------------------------------------------- /app/img/icons/IconsetW_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/IconsetW_2x.png -------------------------------------------------------------------------------- /app/img/icons/Major.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/Major.png -------------------------------------------------------------------------------- /app/img/icons/Major_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/Major_2x.png -------------------------------------------------------------------------------- /app/img/icons/MobileIcons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/MobileIcons.png -------------------------------------------------------------------------------- /app/img/icons/MobileIcons_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/MobileIcons_2x.png -------------------------------------------------------------------------------- /app/img/icons/PhotoIcons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/PhotoIcons.png -------------------------------------------------------------------------------- /app/img/icons/PhotoIcons_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/PhotoIcons_2x.png -------------------------------------------------------------------------------- /app/img/icons/ProfileIcons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/ProfileIcons.png -------------------------------------------------------------------------------- /app/img/icons/ProfileIcons_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/ProfileIcons_2x.png -------------------------------------------------------------------------------- /app/img/icons/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | -------------------------------------------------------------------------------- /app/img/icons/icon120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/icon120.png -------------------------------------------------------------------------------- /app/img/icons/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/icon128.png -------------------------------------------------------------------------------- /app/img/icons/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/icon16.png -------------------------------------------------------------------------------- /app/img/icons/icon192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/icon192.png -------------------------------------------------------------------------------- /app/img/icons/icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/icon32.png -------------------------------------------------------------------------------- /app/img/icons/icon512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/icon512.png -------------------------------------------------------------------------------- /app/img/icons/icon60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/icon60.png -------------------------------------------------------------------------------- /app/img/icons/icon64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/icon64.png -------------------------------------------------------------------------------- /app/img/icons/icon90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/icons/icon90.png -------------------------------------------------------------------------------- /app/img/iphone_home120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/iphone_home120.png -------------------------------------------------------------------------------- /app/img/iphone_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/iphone_startup.png -------------------------------------------------------------------------------- /app/img/logo_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/logo_share.png -------------------------------------------------------------------------------- /app/img/placeholders/DialogListAvatarSystem@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/DialogListAvatarSystem@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/Fave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/Fave.png -------------------------------------------------------------------------------- /app/img/placeholders/GroupAvatar1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/GroupAvatar1@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/GroupAvatar2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/GroupAvatar2@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/GroupAvatar3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/GroupAvatar3@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/GroupAvatar4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/GroupAvatar4@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/PhotoThumbConversation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/PhotoThumbConversation.gif -------------------------------------------------------------------------------- /app/img/placeholders/PhotoThumbModal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/PhotoThumbModal.gif -------------------------------------------------------------------------------- /app/img/placeholders/UserAvatar1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/UserAvatar1@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/UserAvatar2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/UserAvatar2@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/UserAvatar3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/UserAvatar3@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/UserAvatar4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/UserAvatar4@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/UserAvatar5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/UserAvatar5@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/UserAvatar6@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/UserAvatar6@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/UserAvatar7@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/UserAvatar7@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/UserAvatar8@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/UserAvatar8@2x.png -------------------------------------------------------------------------------- /app/img/placeholders/VideoThumbConversation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/VideoThumbConversation.gif -------------------------------------------------------------------------------- /app/img/placeholders/VideoThumbModal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/placeholders/VideoThumbModal.gif -------------------------------------------------------------------------------- /app/img/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/screenshot1.png -------------------------------------------------------------------------------- /app/img/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/screenshot2.png -------------------------------------------------------------------------------- /app/img/screenshot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/screenshot3.png -------------------------------------------------------------------------------- /app/img/sound_a.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/img/sound_a.mp3 -------------------------------------------------------------------------------- /app/js/app.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Webogram v0.7.0 - messaging web application for MTProto 3 | * https://github.com/zhukov/webogram 4 | * Copyright (C) 2014 Igor Zhukov 5 | * https://github.com/zhukov/webogram/blob/master/LICENSE 6 | */ 7 | 8 | 'use strict' 9 | /* global Config, templateUrl */ 10 | 11 | var extraModules = [] 12 | if (Config.Modes.animations) { 13 | extraModules.push('ngAnimate') 14 | } 15 | 16 | // Declare app level module which depends on filters, and services 17 | angular.module('myApp', [ 18 | 'ngRoute', 19 | 'ngSanitize', 20 | 'ngTouch', 21 | 'ui.bootstrap', 22 | 'mediaPlayer', 23 | 'toaster', 24 | 'izhukov.utils', 25 | 'izhukov.mtproto', 26 | 'izhukov.mtproto.wrapper', 27 | 'myApp.filters', 28 | 'myApp.services', 29 | /*PRODUCTION_ONLY_BEGIN 30 | 'myApp.templates', 31 | PRODUCTION_ONLY_END*/ 32 | 'myApp.directives', 33 | 'myApp.controllers' 34 | ].concat(extraModules)).config(['$locationProvider', '$routeProvider', '$compileProvider', 'StorageProvider', function ($locationProvider, $routeProvider, $compileProvider, StorageProvider) { 35 | $locationProvider.hashPrefix(''); 36 | $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|blob|filesystem|chrome-extension|app):|data:image\//) 37 | $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|file|tg|mailto|blob|filesystem|chrome-extension|app):|data:/) 38 | 39 | /*PRODUCTION_ONLY_BEGIN 40 | $compileProvider.debugInfoEnabled(false) 41 | PRODUCTION_ONLY_END*/ 42 | 43 | if (Config.Modes.test) { 44 | StorageProvider.setPrefix('t_') 45 | } 46 | 47 | $routeProvider.when('/', {template: '', controller: 'AppWelcomeController'}) 48 | $routeProvider.when('/login', {templateUrl: templateUrl('login'), controller: 'AppLoginController'}) 49 | $routeProvider.when('/im', {templateUrl: templateUrl('im'), controller: 'AppIMController', reloadOnSearch: false}) 50 | $routeProvider.otherwise({redirectTo: '/'}) 51 | }]) 52 | -------------------------------------------------------------------------------- /app/js/background.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Webogram v0.7.0 - messaging web application for MTProto 3 | * https://github.com/zhukov/webogram 4 | * Copyright (C) 2014 Igor Zhukov 5 | * https://github.com/zhukov/webogram/blob/master/LICENSE 6 | */ 7 | 8 | chrome.app.runtime.onLaunched.addListener(function (launchData) { 9 | var isWindows = typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.match(/windows/i) ? true : false 10 | chrome.app.window.create('../index.html', { 11 | id: 'webogram-chat', 12 | innerBounds: { 13 | width: 1000, 14 | height: 700 15 | }, 16 | minWidth: 320, 17 | minHeight: 400, 18 | frame: isWindows ? { color: '#5682a3' } : 'chrome' 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /app/js/lib/crypto_worker.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Webogram v0.7.0 - messaging web application for MTProto 3 | * https://github.com/zhukov/webogram 4 | * Copyright (C) 2014 Igor Zhukov 5 | * https://github.com/zhukov/webogram/blob/master/LICENSE 6 | */ 7 | 8 | importScripts( 9 | 'polyfill.js', 10 | 'bin_utils.js', 11 | '../../vendor/jsbn/jsbn_combined.js', 12 | '../../vendor/leemon_bigint/bigint.js', 13 | '../../vendor/closure/long.js', 14 | '../../vendor/cryptoJS/crypto.js', 15 | '../../vendor/rusha/rusha.js' 16 | ) 17 | 18 | onmessage = function (e) { 19 | var taskID = e.data.taskID, 20 | result 21 | 22 | switch (e.data.task) { 23 | case 'factorize': 24 | result = pqPrimeFactorization(e.data.bytes) 25 | break 26 | 27 | case 'mod-pow': 28 | result = bytesModPow(e.data.x, e.data.y, e.data.m) 29 | break 30 | 31 | case 'sha1-hash': 32 | result = sha1HashSync(e.data.bytes) 33 | break 34 | 35 | case 'aes-encrypt': 36 | result = aesEncryptSync(e.data.bytes, e.data.keyBytes, e.data.ivBytes) 37 | break 38 | 39 | case 'aes-decrypt': 40 | result = aesDecryptSync(e.data.encryptedBytes, e.data.keyBytes, e.data.ivBytes) 41 | break 42 | 43 | default: 44 | throw new Error('Unknown task: ' + e.data.task) 45 | } 46 | 47 | postMessage({taskID: taskID, result: result}) 48 | } 49 | 50 | postMessage('ready') 51 | -------------------------------------------------------------------------------- /app/less/font.less: -------------------------------------------------------------------------------- 1 | /* From http://fonts.googleapis.com/css?family=Open+Sans:400&subset=latin,cyrillic */ 2 | 3 | /* cyrillic */ 4 | @font-face { 5 | font-family: 'Open Sans'; 6 | font-style: normal; 7 | font-weight: 400; 8 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/400cn.woff2) format('woff2'); 9 | unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; 10 | } 11 | /* latin */ 12 | @font-face { 13 | font-family: 'Open Sans'; 14 | font-style: normal; 15 | font-weight: 400; 16 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/400ln.woff2) format('woff2'); 17 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; 18 | } 19 | 20 | /* cyrillic */ 21 | @font-face { 22 | font-family: 'Open Sans'; 23 | font-style: normal; 24 | font-weight: 600; 25 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/600cn.woff2) format('woff2'); 26 | unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; 27 | } 28 | /* latin */ 29 | @font-face { 30 | font-family: 'Open Sans'; 31 | font-style: normal; 32 | font-weight: 600; 33 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/600ln.woff2) format('woff2'); 34 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; 35 | } 36 | 37 | @font-face { 38 | font-family: 'Open Sans'; 39 | font-style: normal; 40 | font-weight: 400; 41 | src: local('Open Sans'), local('OpenSans'), url(../fonts/400.woff2) format('woff2'), url(../fonts/400.woff) format('woff'), url(../fonts/400.ttf) format('truetype'), url(../fonts/400.svg#OpenSans) format('svg'); 42 | } 43 | @font-face { 44 | font-family: 'Open Sans'; 45 | font-style: normal; 46 | font-weight: 600; 47 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/600.woff2) format('woff2'), url(../fonts/600.woff) format('woff'), url(../fonts/600.ttf) format('truetype'), url(../fonts/600.svg#OpenSans) format('svg'); 48 | } -------------------------------------------------------------------------------- /app/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Telegram", 3 | "description": "Telegram Web App.\nMore info & source code here: https://github.com/zhukov/webogram", 4 | "version": "0.7.0", 5 | "short_name": "Telegram", 6 | "manifest_version": 2, 7 | "app": { 8 | "background": { 9 | "scripts": ["js/background.js"] 10 | } 11 | }, 12 | "permissions": [ 13 | "notifications", 14 | "webview", 15 | {"fileSystem": ["write"]}, 16 | "storage", 17 | "unlimitedStorage", 18 | "fullscreen" 19 | ], 20 | "gcm_sender_id": "122867383838", 21 | "icons": { 22 | "16": "img/icons/icon16.png", 23 | "32": "img/icons/icon32.png", 24 | "60": "img/icons/icon60.png", 25 | "64": "img/icons/icon64.png", 26 | "90": "img/icons/icon90.png", 27 | "128": "img/icons/icon128.png" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/manifest.webapp: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Telegram", 3 | "description": "Telegram Web App.\nMore info & source code here: https://github.com/zhukov/webogram", 4 | "version": "0.7.0", 5 | "type": "privileged", 6 | "launch_path": "/index.html", 7 | "developer": { 8 | "name": "Igor Zhukov", 9 | "url": "https://github.com/zhukov" 10 | }, 11 | "installs_allowed_from": [ 12 | "*" 13 | ], 14 | "messages": [{ 15 | "push": "/index.html" 16 | }, { 17 | "push-register": "/index.html" 18 | }, { 19 | "notification": "/index.html" 20 | }], 21 | "permissions": { 22 | "desktop-notification": { 23 | "description": "Required to show new message notifications" 24 | }, 25 | "contacts": { 26 | "description": "Required to import phonebook contacts", 27 | "access": "readonly" 28 | }, 29 | "push": { 30 | "description": "Required for notifications" 31 | }, 32 | "device-storage:music": { 33 | "description": "Required for voice notes download", 34 | "access": "createonly" 35 | }, 36 | "device-storage:pictures": { 37 | "description": "Required for photos download", 38 | "access": "createonly" 39 | }, 40 | "device-storage:sdcard": { 41 | "description": "Required for documents download", 42 | "access": "createonly" 43 | }, 44 | "device-storage:videos": { 45 | "description": "Required for videos download", 46 | "access": "createonly" 47 | }, 48 | "audio-capture" : { 49 | "description" : "Required to record voice messages" 50 | } 51 | }, 52 | "activities": { 53 | "share": { 54 | "href": "/index.html", 55 | "disposition": "window", 56 | "filters": { 57 | "type": ["image/*","audio/*","video/*", "url"], 58 | "url": { 59 | "pattern": "https?:.{1,16384}", 60 | "regexp": "^https?:" 61 | } 62 | }, 63 | "returnValue": false 64 | }, 65 | "view": { 66 | "href": "/index.html", 67 | "disposition": "window", 68 | "filters": { 69 | "type": "url", 70 | "url": { 71 | "required": true, 72 | "pattern": "tg:.{1,16384}", 73 | "regexp": "^tg:" 74 | } 75 | }, 76 | "returnValue": false 77 | } 78 | }, 79 | "orientation": "portrait-primary", 80 | "icons": { 81 | "16": "/img/icons/icon16.png", 82 | "32": "/img/icons/icon32.png", 83 | "60": "/img/icons/icon60.png", 84 | "64": "/img/icons/icon64.png", 85 | "90": "/img/icons/icon90.png", 86 | "120": "/img/icons/icon120.png", 87 | "128": "/img/icons/icon128.png" 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/manifest.webapp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Telegram", 3 | "description": "Telegram Web App.\nMore info & source code here: https://github.com/zhukov/webogram", 4 | "short_name": "Telegram", 5 | "display": "standalone", 6 | "theme_color": "#497495", 7 | "gcm_sender_id": "122867383838", 8 | "start_url": "./", 9 | "scope": "/", 10 | "background_color": "#fff", 11 | "icons": [ 12 | { 13 | "src": "img/icons/icon16.png", 14 | "type": "image/png", 15 | "sizes": "16x16" 16 | }, 17 | { 18 | "src": "img/icons/icon32.png", 19 | "type": "image/png", 20 | "sizes": "32x32" 21 | }, 22 | { 23 | "src": "img/icons/icon60.png", 24 | "type": "image/png", 25 | "sizes": "60x60" 26 | }, 27 | { 28 | "src": "img/icons/icon64.png", 29 | "type": "image/png", 30 | "sizes": "64x64" 31 | }, 32 | { 33 | "src": "img/icons/icon90.png", 34 | "type": "image/png", 35 | "sizes": "90x90" 36 | }, 37 | { 38 | "src": "img/icons/icon128.png", 39 | "type": "image/png", 40 | "sizes": "128x128" 41 | }, 42 | { 43 | "src": "img/icons/icon192.png", 44 | "type": "image/png", 45 | "sizes": "192x192" 46 | }, 47 | { 48 | "src": "img/icons/icon512.png", 49 | "type": "image/png", 50 | "sizes": "512x512" 51 | }, 52 | { 53 | "src": "img/icons/icon.svg", 54 | "type": "image/svg+xml", 55 | "sizes": "513x513" 56 | } 57 | ], 58 | "related_applications": [ 59 | { 60 | "platform": "play", 61 | "id": "org.telegram.messenger", 62 | "url": "https://telegram.org/dl/android?ref=webmanifest" 63 | }, 64 | { 65 | "platform": "itunes", 66 | "url": "https://telegram.org/dl/ios?ref=webmanifest" 67 | } 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /app/nacl/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 The Native Client Authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style license that can be 3 | # found in the LICENSE file. 4 | 5 | # 6 | # GNU Make based build file.  For details on GNU Make see: 7 | # http://www.gnu.org/software/make/manual/make.html 8 | # 9 | 10 | # 11 | # Get pepper directory for toolchain and includes. 12 | # 13 | # If NACL_SDK_ROOT is not set, then assume it can be found three directories up. 14 | # 15 | THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST))) 16 | NACL_SDK_ROOT ?= $(abspath $(dir $(THIS_MAKEFILE))../..) 17 | 18 | # Project Build flags 19 | WARNINGS := -Wno-long-long -Wall -Wswitch-enum -pedantic -Werror 20 | CXXFLAGS := -pthread -std=gnu++98 $(WARNINGS) 21 | 22 | # 23 | # Compute tool paths 24 | # 25 | GETOS := python $(NACL_SDK_ROOT)/tools/getos.py 26 | OSHELPERS = python $(NACL_SDK_ROOT)/tools/oshelpers.py 27 | OSNAME := $(shell $(GETOS)) 28 | RM := $(OSHELPERS) rm 29 | 30 | PNACL_TC_PATH := $(abspath $(NACL_SDK_ROOT)/toolchain/$(OSNAME)_pnacl) 31 | PNACL_CXX := $(PNACL_TC_PATH)/bin/pnacl-clang++ 32 | PNACL_FINALIZE := $(PNACL_TC_PATH)/bin/pnacl-finalize 33 | CXXFLAGS := -I$(NACL_SDK_ROOT)/include 34 | LDFLAGS := -L$(NACL_SDK_ROOT)/lib/pnacl/Release -lppapi_cpp -lppapi 35 | 36 | # 37 | # Disable DOS PATH warning when using Cygwin based tools Windows 38 | # 39 | CYGWIN ?= nodosfilewarning 40 | export CYGWIN 41 | 42 | 43 | # Declare the ALL target first, to make the 'all' target the default build 44 | all: mtproto_crypto.pexe 45 | 46 | clean: 47 | $(RM) mtproto_crypto.pexe mtproto_crypto.bc 48 | 49 | mtproto_crypto.bc: mtproto_crypto.cc aes_core.c aes_ige.c aes_misc.c 50 | $(PNACL_CXX) -o $@ $^ -O2 $(CXXFLAGS) $(LDFLAGS) 51 | # $(PNACL_CXX) -g -o $@ $^ $(CXXFLAGS) $(LDFLAGS) 52 | 53 | mtproto_crypto.pexe: mtproto_crypto.bc 54 | $(PNACL_FINALIZE) -o $@ $< 55 | -------------------------------------------------------------------------------- /app/nacl/mtproto_crypto.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/nacl/mtproto_crypto.bc -------------------------------------------------------------------------------- /app/nacl/mtproto_crypto.nmf: -------------------------------------------------------------------------------- 1 | { 2 | "program": { 3 | "portable": { 4 | "pnacl-translate": { 5 | "url": "mtproto_crypto.pexe?67", 6 | "optlevel": 2 7 | } 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /app/nacl/mtproto_crypto.pexe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/nacl/mtproto_crypto.pexe -------------------------------------------------------------------------------- /app/partials/desktop/changelog_modal.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 | 7 |
8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 |
Telegram Web
17 |
18 | 19 |
20 |
21 |
22 |
23 | 24 |
25 |
26 | 27 | 28 | 29 |
30 |
31 | 32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 | 40 |
41 | 42 | 43 | 47 | 48 |
49 | 50 |
-------------------------------------------------------------------------------- /app/partials/desktop/channel_edit_modal.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 20 | 21 |
22 | 23 | 27 | 28 |
-------------------------------------------------------------------------------- /app/partials/desktop/chat_create_modal.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 15 | 16 |
17 | 18 | 22 | 23 |
-------------------------------------------------------------------------------- /app/partials/desktop/chat_edit_modal.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 15 | 16 |
17 | 18 | 22 | 23 |
-------------------------------------------------------------------------------- /app/partials/desktop/chat_invite_link_modal.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 27 | 28 |
29 | 30 | 36 | 37 |
-------------------------------------------------------------------------------- /app/partials/desktop/composer_dropdown.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 12 | 13 | 22 | 23 |
    24 | 25 |
    26 | 27 |
    -------------------------------------------------------------------------------- /app/partials/desktop/country_select_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |
    5 |
    6 | 7 |
    8 |
    9 |
    10 |
    11 | 12 |
    13 | 14 | 21 | 22 |
    23 | 24 |
    25 |
    26 | 27 | 37 | 38 |
    39 |
    40 | 41 |
    42 | 43 |
    44 | 45 |
    46 | -------------------------------------------------------------------------------- /app/partials/desktop/document_modal.html: -------------------------------------------------------------------------------- 1 | 4 | 5 |
    6 |
    7 | 18 | 19 |
    20 | 21 |
    22 | 23 |
    24 |
    25 | 26 | 27 |
    28 |
    29 | 30 |
    31 | 32 |
    33 |
    34 | 35 | -------------------------------------------------------------------------------- /app/partials/desktop/edit_contact_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 25 | 26 |
    27 | 28 | 32 | 33 |
    -------------------------------------------------------------------------------- /app/partials/desktop/embed_modal.html: -------------------------------------------------------------------------------- 1 | 4 | 5 |
    6 |
    7 | 15 | 16 |
    17 |
    18 | 19 |
    20 |
    21 |
    22 | 23 |
    24 |
    25 |
    26 | 27 | -------------------------------------------------------------------------------- /app/partials/desktop/emoji_btn_tooltip.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |
    5 | 6 |
    7 | 8 |
    9 | 10 |
    11 |
    12 | 13 |
    14 |
    15 | 16 |
    17 |
    18 | 19 |
    20 |
    21 | 22 | 23 | 24 | 25 | 26 |
    -------------------------------------------------------------------------------- /app/partials/desktop/footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/partials/desktop/forwarded_messages.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | 10 |
    11 |
    12 | 13 |
    14 |
    15 |
    16 | 17 |
    18 |
    19 | 20 | 22 | 23 | 24 |
    25 |
    26 |
    -------------------------------------------------------------------------------- /app/partials/desktop/full_document.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 |
    7 |
    8 |
    9 |
    10 |
    11 | 16 |
    17 |
    18 |
    19 | 20 |
    21 |
    -------------------------------------------------------------------------------- /app/partials/desktop/full_gif.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 | 5 |
    6 |
    7 | 8 | 9 | 10 | 11 |
    12 |
    13 |
    [GIF]
    14 |
    15 | 16 |
    17 | 20 | 21 |
    22 | 23 | 24 |
    25 | 26 |
    -------------------------------------------------------------------------------- /app/partials/desktop/full_photo.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 |
    7 |
    8 |
    9 |
    10 |
    11 | 12 | 13 | 14 |
    15 |
    16 |
    17 |
    18 |
    19 |
    -------------------------------------------------------------------------------- /app/partials/desktop/full_round.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 | 5 |
    6 |
    7 | 8 | 9 | 10 | 11 |
    12 |
    13 | 14 |
    15 |
    16 | 17 |
    18 | 21 | 22 |
    23 | 24 | 25 |
    26 | 27 |
    -------------------------------------------------------------------------------- /app/partials/desktop/full_video.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 |
    7 |
    8 |
    9 |
    10 | 15 |
    16 |
    17 | 18 | 21 |
    22 |
    23 |
    24 |
    25 |
    26 |
    -------------------------------------------------------------------------------- /app/partials/desktop/game_modal.html: -------------------------------------------------------------------------------- 1 | 4 | 5 |
    6 |
    7 |
    8 | 9 | 10 | 11 |
    12 | 13 |
    14 | 15 |
    16 | 17 |
    18 |
    19 | 20 |
    21 |
    22 | 23 |
    24 |
    25 |
    26 | 27 | -------------------------------------------------------------------------------- /app/partials/desktop/import_contact_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 28 | 29 |
    30 | 31 | 35 | 36 |
    -------------------------------------------------------------------------------- /app/partials/desktop/inactive.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | 6 |

    7 |
    8 |
    9 | 10 |
    11 |
    12 |
    13 |
    -------------------------------------------------------------------------------- /app/partials/desktop/lang_footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/partials/desktop/media_modal_layout.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/partials/desktop/megagroup_edit_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 20 | 21 |
    22 | 23 | 27 | 28 |
    -------------------------------------------------------------------------------- /app/partials/desktop/message_attach_contact.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 6 |
    7 |
    8 |
    -------------------------------------------------------------------------------- /app/partials/desktop/message_attach_game.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | 6 |
    7 |
    8 |
    9 | 10 | [{{::media.game.title}}] 16 | 17 |
    18 |
    19 |
    20 | -------------------------------------------------------------------------------- /app/partials/desktop/message_attach_geo.html: -------------------------------------------------------------------------------- 1 | 2 | [{{::'conversation_media_location' | i18n}} {{::media.mapUrl}}] 9 | -------------------------------------------------------------------------------- /app/partials/desktop/message_attach_pending.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 |
    5 |
    6 |
    7 | 8 | 9 |
    10 |
    11 | 12 |
    13 |
    14 |
    15 |
    16 |
    17 |
    18 |
    19 |
    20 | -------------------------------------------------------------------------------- /app/partials/desktop/message_attach_photo.html: -------------------------------------------------------------------------------- 1 | 2 | [{{::'conversation_media_photo' | i18n}}] 8 | 9 |
    -------------------------------------------------------------------------------- /app/partials/desktop/message_attach_venue.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 | [{{::'conversation_media_location' | i18n}} {{::media.mapUrl}}] 11 | 12 | 13 |
    14 |
    15 | 16 |
    17 |
    18 |
    19 | 20 |
    21 | -------------------------------------------------------------------------------- /app/partials/desktop/message_media.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 |
    7 |
    8 |
    9 |
    10 | 11 |
    12 | 15 |
    16 | 17 |
    18 |
    19 | web.telegram.org 20 |
    21 |
    22 |
    -------------------------------------------------------------------------------- /app/partials/desktop/password_recovery_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 22 | 23 |
    24 | 25 | 31 | 32 |
    -------------------------------------------------------------------------------- /app/partials/desktop/peer_pinned_message_bar.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 |
    -------------------------------------------------------------------------------- /app/partials/desktop/pinned_message.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/partials/desktop/profile_edit_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 20 | 21 |
    22 | 23 | 27 | 28 |
    29 | -------------------------------------------------------------------------------- /app/partials/desktop/reply_markup.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | 6 | 7 |
    8 |
    9 |
    10 |
    -------------------------------------------------------------------------------- /app/partials/desktop/reply_message.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | 5 |
    6 |
    7 | 13 |
    14 |
    15 | 16 | 17 | 18 |
    19 |
    20 | 21 | 22 |
    23 |
    -------------------------------------------------------------------------------- /app/partials/desktop/report_msgs_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 43 | 44 |
    45 | 46 | 50 | 51 |
    -------------------------------------------------------------------------------- /app/partials/desktop/slider.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 |
    -------------------------------------------------------------------------------- /app/partials/desktop/stickerset_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |
    5 |
    6 | 7 |
    8 |
    9 |
    10 | 11 | 12 |
    13 |
    14 | 15 |
    16 | 17 |
    18 | 19 |
    20 |
    21 | 22 |
    23 | 24 | 25 | 26 |
    27 | 28 | 34 | 35 |
    36 |
    37 | 38 |
    39 | 40 |
    41 |
    42 | 43 | 44 | 45 |
    46 |
    47 | 48 |
    49 | 50 |
    51 | -------------------------------------------------------------------------------- /app/partials/desktop/username_edit_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 17 | 18 |
    19 | 20 | 26 | 27 |
    -------------------------------------------------------------------------------- /app/partials/desktop/video_modal.html: -------------------------------------------------------------------------------- 1 | 4 | 5 |
    6 |
    7 | 18 | 19 |
    20 | 21 |
    22 | 23 |
    24 |
    25 | 26 | 27 |
    28 |
    29 | 30 |
    31 |
    32 |
    33 | 34 | -------------------------------------------------------------------------------- /app/partials/mobile/chat_create_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 27 |
    28 | 29 | 40 | 41 |
    -------------------------------------------------------------------------------- /app/partials/mobile/chat_edit_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 27 |
    28 | 29 | 40 | 41 |
    -------------------------------------------------------------------------------- /app/partials/mobile/country_select_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 24 |
    25 | 26 | 49 | 50 |
    51 | -------------------------------------------------------------------------------- /app/partials/mobile/edit_contact_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 27 |
    28 | 29 | 46 | 47 |
    -------------------------------------------------------------------------------- /app/partials/mobile/full_gif.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 | 5 |
    6 |
    7 | 8 | 9 | 10 | 11 |
    12 |
    13 |
    GIF
    14 |
    15 | 16 |
    17 | 20 | 21 |
    22 | 23 | 24 |
    25 | 26 |
    -------------------------------------------------------------------------------- /app/partials/mobile/full_photo.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 |
    7 |
    8 |
    9 |
    10 |
    11 | 12 | 13 | 14 |
    15 |
    16 |
    17 |
    18 |
    19 |
    -------------------------------------------------------------------------------- /app/partials/mobile/full_video.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 |
    7 |
    8 |
    9 |
    10 | 15 |
    16 |
    17 | 18 | 21 |
    22 |
    23 |
    24 |
    25 |
    26 |
    -------------------------------------------------------------------------------- /app/partials/mobile/game_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 41 |
    42 | 43 | 44 | 45 |
    46 | -------------------------------------------------------------------------------- /app/partials/mobile/import_contact_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 27 |
    28 | 29 | 50 |
    -------------------------------------------------------------------------------- /app/partials/mobile/message_actions_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 | 13 |
    14 | -------------------------------------------------------------------------------- /app/partials/mobile/message_attach_contact.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 6 |
    7 |
    8 |
    -------------------------------------------------------------------------------- /app/partials/mobile/message_attach_geo.html: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /app/partials/mobile/message_attach_pending.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 |
    5 |
    6 |
    7 | 8 | 9 |
    10 |
    11 | 12 |
    13 |
    14 |
    15 |
    16 |
    17 |
    18 |
    19 |
    20 | -------------------------------------------------------------------------------- /app/partials/mobile/message_attach_photo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 |
    -------------------------------------------------------------------------------- /app/partials/mobile/message_attach_venue.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 | [{{::'conversation_media_location' | i18n}} {{::media.mapUrl}}] 11 | 12 | 13 |
    14 |
    15 | 16 |
    17 |
    18 |
    19 | 20 |
    21 | -------------------------------------------------------------------------------- /app/partials/mobile/message_attach_webpage.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | 6 |
    7 |
    8 | 9 | 14 | 15 |
    16 |
    17 |
    18 |
    19 | 20 |
    21 |
    22 | 23 | 24 | 25 | 30 | 31 |
    32 | 33 |
    34 |
    35 | 36 | 41 | 42 |
    43 | 44 |
    45 |
    46 |
    47 |
    48 | -------------------------------------------------------------------------------- /app/partials/mobile/password_recovery_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 27 |
    28 | 29 | 48 | 49 |
    -------------------------------------------------------------------------------- /app/partials/mobile/photo_modal.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | 5 | 6 | 7 |
    8 | 9 |
    10 | 11 | 12 | 13 |
    14 | 15 |
    16 | 17 |
    18 | 19 |
    20 | 21 |
    22 |
    23 | 24 | 48 | 49 | 62 | 63 | -------------------------------------------------------------------------------- /app/partials/mobile/profile_edit_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 27 |
    28 | 29 | 43 | 44 |
    -------------------------------------------------------------------------------- /app/partials/mobile/stickerset_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 31 |
    32 | 33 | 59 | 60 |
    -------------------------------------------------------------------------------- /app/partials/mobile/username_edit_modal.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 27 |
    28 | 29 | 43 | 44 |
    -------------------------------------------------------------------------------- /app/partials/mobile/video_modal.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | 5 | 6 | 7 |
    8 | 9 |
    10 | 11 | 12 | 13 |
    14 | 15 |
    16 | 17 |
    18 | 19 |
    20 | 21 |
    22 |
    23 | 24 |
    25 |
    26 |
    27 | 28 | 29 | 30 |
    31 | 39 |
    40 |
    41 | 42 | 55 | 56 | -------------------------------------------------------------------------------- /app/service_worker.js: -------------------------------------------------------------------------------- 1 | /* global importScripts */ 2 | importScripts('js/lib/push_worker.js') 3 | 4 | // Version 53 5 | -------------------------------------------------------------------------------- /app/vendor/README.md: -------------------------------------------------------------------------------- 1 | ## Third party libraries 2 | 3 | ### [AngularJS](http://angularjs.org/) 4 | 5 | **Author**: Google, Inc. 6 | **License**: MIT, https://github.com/angular/angular.js/blob/master/LICENSE 7 | 8 | ### [JSBN](http://www-cs-students.stanford.edu/~tjw/jsbn/) 9 | 10 | **Author**: Tom Wu 11 | **License**: BSD, http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE 12 | 13 | Biginteger for RSA, PQ prime factorization 14 | 15 | 16 | ### [jQuery Emojiarea](https://github.com/diy/jquery-emojiarea) 17 | 18 | **Author**: diy 19 | **License**: Apache, Version 2.0, https://github.com/diy/jquery-emojiarea#license 20 | 21 | Emoji keyboard and rich-textfield for composing messages with emoticons 22 | 23 | 24 | ### [UI Bootstrap](http://angular-ui.github.io/bootstrap/) 25 | 26 | **Author**: AngularUI Team, https://github.com/organizations/angular-ui/teams/291112 27 | **License**: MIT, https://github.com/angular-ui/bootstrap/blob/master/LICENSE 28 | 29 | Modal windows 30 | 31 | 32 | ### [jQuery](https://github.com/jquery/jquery) 33 | 34 | **Author**: jQuery Foundation and other contributors 35 | **License**: MIT, https://github.com/jquery/jquery/blob/master/LICENSE.txt 36 | 37 | Dom manupulations. 38 | 39 | ### [Bootstrap](https://github.com/twbs/bootstrap) 40 | 41 | **Author**: Twitter, Inc 42 | **License**: MIT, https://github.com/twbs/bootstrap/blob/master/LICENSE 43 | 44 | Normalize, CSS-framework 45 | 46 | ### [nanoScrollerJS](https://github.com/jamesflorentino/nanoScrollerJS) 47 | 48 | **Author**: James Florentino 49 | **License**: MIT, https://github.com/jamesflorentino/nanoScrollerJS/blob/master/LICENSE 50 | 51 | Beautiful OS X Lion-like scrollbars 52 | 53 | 54 | ### [CryptoJS](https://code.google.com/p/crypto-js/) 55 | 56 | **Author**: Jeff Mott 57 | **License**: BSD-3-Clause, https://code.google.com/p/crypto-js/wiki/License 58 | 59 | AES, SHA-1 implementation 60 | 61 | ### [zlib.js](https://github.com/imaya/zlib.js) 62 | 63 | **Author**: imaya 64 | **License**: MIT, https://github.com/imaya/zlib.js/blob/master/LICENSE 65 | 66 | GZIP for decompressing server responses 67 | 68 | ### [emoji-data](https://github.com/iamcal/emoji-data) 69 | 70 | **Author**: iamcal 71 | **License**: not specified 72 | 73 | Build emoji list in apropriate format. Generate sheet in future, when needed. 74 | 75 | 76 | ### [gemoji](https://github.com/github/gemoji) 77 | 78 | **Author**: GitHub Inc, 37signals, id Software, whynne@deviantart, Apple Inc. 79 | **License**: https://github.com/github/gemoji/blob/master/LICENSE 80 | 81 | Emoji images 82 | -------------------------------------------------------------------------------- /app/vendor/angular/angular-cookies.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.7.8 3 | (c) 2010-2018 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(n,e){'use strict';function m(d,k,l){var a=l.baseHref(),h=d[0];return function(f,b,c){var d,g;c=c||{};g=c.expires;d=e.isDefined(c.path)?c.path:a;e.isUndefined(b)&&(g="Thu, 01 Jan 1970 00:00:00 GMT",b="");e.isString(g)&&(g=new Date(g));b=encodeURIComponent(f)+"="+encodeURIComponent(b);b=b+(d?";path="+d:"")+(c.domain?";domain="+c.domain:"");b+=g?";expires="+g.toUTCString():"";b+=c.secure?";secure":"";b+=c.samesite?";samesite="+c.samesite:"";c=b.length+1;4096 4096 bytes)!");h.cookie=b}}e.module("ngCookies",["ng"]).info({angularVersion:"1.7.8"}).provider("$cookies",[function(){var d=this.defaults={};this.$get=["$$cookieReader","$$cookieWriter",function(k,l){return{get:function(a){return k()[a]},getObject:function(a){return(a=this.get(a))?e.fromJson(a):a},getAll:function(){return k()},put:function(a,h,f){l(a,h,f?e.extend({},d,f):d)},putObject:function(a,d,f){this.put(a,e.toJson(d),f)},remove:function(a,h){l(a,void 0,h?e.extend({},d,h):d)}}}]}]);m.$inject= 8 | ["$document","$log","$browser"];e.module("ngCookies").provider("$$cookieWriter",function(){this.$get=m})})(window,window.angular); 9 | //# sourceMappingURL=angular-cookies.min.js.map 10 | -------------------------------------------------------------------------------- /app/vendor/angular/angular-csp.css: -------------------------------------------------------------------------------- 1 | /* Include this file in your html if you are using the CSP mode. */ 2 | 3 | @charset "UTF-8"; 4 | 5 | [ng\:cloak], 6 | [ng-cloak], 7 | [data-ng-cloak], 8 | [x-ng-cloak], 9 | .ng-cloak, 10 | .x-ng-cloak, 11 | .ng-hide:not(.ng-hide-animate) { 12 | display: none !important; 13 | } 14 | 15 | ng\:form { 16 | display: block; 17 | } 18 | 19 | .ng-animate-shim { 20 | visibility:hidden; 21 | } 22 | 23 | .ng-anchor { 24 | position:absolute; 25 | } 26 | -------------------------------------------------------------------------------- /app/vendor/angular/angular-loader.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.7.8 3 | (c) 2010-2018 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(){'use strict';function g(a,f){f=f||Error;return function(){var d=arguments[0],e;e="["+(a?a+":":"")+d+"] http://errors.angularjs.org/1.7.8/"+(a?a+"/":"")+d;for(d=1;db&&0b/a}var m=a(f[g]),d,l,r=["touch"];p.isDefined(f.ngSwipeDisableMouse)||r.push("mouse");b.bind(e,{start:function(a,b){d=a;l=!0},cancel:function(a){l=!1},end:function(a,b){k(a)&&c.$apply(function(){e.triggerHandler(s);m(c,{$event:b})})}},r)}}])}var n=p.module("ngTouch",[]);n.info({angularVersion:"1.7.8"}); 7 | n.factory("$swipe",[function(){function g(a){a=a.originalEvent||a;var b=a.touches&&a.touches.length?a.touches:[a];a=a.changedTouches&&a.changedTouches[0]||b[0];return{x:a.clientX,y:a.clientY}}function h(a,b){var c=[];p.forEach(a,function(a){(a=n[a][b])&&c.push(a)});return c.join(" ")}var n={mouse:{start:"mousedown",move:"mousemove",end:"mouseup"},touch:{start:"touchstart",move:"touchmove",end:"touchend",cancel:"touchcancel"},pointer:{start:"pointerdown",move:"pointermove",end:"pointerup",cancel:"pointercancel"}}; 8 | return{bind:function(a,b,c){var e,f,k,m,d=!1;c=c||["mouse","touch","pointer"];a.on(h(c,"start"),function(a){k=g(a);d=!0;f=e=0;m=k;b.start&&b.start(k,a)});var l=h(c,"cancel");if(l)a.on(l,function(a){d=!1;b.cancel&&b.cancel(a)});a.on(h(c,"move"),function(a){if(d&&k){var c=g(a);e+=Math.abs(c.x-m.x);f+=Math.abs(c.y-m.y);m=c;10>e&&10>f||(f>e?(d=!1,b.cancel&&b.cancel(a)):(a.preventDefault(),b.move&&b.move(c,a)))}});a.on(h(c,"end"),function(a){d&&(d=!1,b.end&&b.end(g(a),a))})}}}]);q("ngSwipeLeft",-1,"swipeleft"); 9 | q("ngSwipeRight",1,"swiperight")})(window,window.angular); 10 | //# sourceMappingURL=angular-touch.min.js.map 11 | -------------------------------------------------------------------------------- /app/vendor/angular/i18n/angular-locale_ms-my.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module("ngLocale", [], ["$provide", function($provide) { 3 | var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; 4 | $provide.value("$locale", { 5 | "DATETIME_FORMATS": { 6 | "AMPMS": [ 7 | "PG", 8 | "PTG" 9 | ], 10 | "DAY": [ 11 | "Ahad", 12 | "Isnin", 13 | "Selasa", 14 | "Rabu", 15 | "Khamis", 16 | "Jumaat", 17 | "Sabtu" 18 | ], 19 | "ERANAMES": [ 20 | "S.M.", 21 | "TM" 22 | ], 23 | "ERAS": [ 24 | "S.M.", 25 | "TM" 26 | ], 27 | "FIRSTDAYOFWEEK": 0, 28 | "MONTH": [ 29 | "Januari", 30 | "Februari", 31 | "Mac", 32 | "April", 33 | "Mei", 34 | "Jun", 35 | "Julai", 36 | "Ogos", 37 | "September", 38 | "Oktober", 39 | "November", 40 | "Disember" 41 | ], 42 | "SHORTDAY": [ 43 | "Ahd", 44 | "Isn", 45 | "Sel", 46 | "Rab", 47 | "Kha", 48 | "Jum", 49 | "Sab" 50 | ], 51 | "SHORTMONTH": [ 52 | "Jan", 53 | "Feb", 54 | "Mac", 55 | "Apr", 56 | "Mei", 57 | "Jun", 58 | "Jul", 59 | "Ogo", 60 | "Sep", 61 | "Okt", 62 | "Nov", 63 | "Dis" 64 | ], 65 | "STANDALONEMONTH": [ 66 | "Januari", 67 | "Februari", 68 | "Mac", 69 | "April", 70 | "Mei", 71 | "Jun", 72 | "Julai", 73 | "Ogos", 74 | "September", 75 | "Oktober", 76 | "November", 77 | "Disember" 78 | ], 79 | "WEEKENDRANGE": [ 80 | 5, 81 | 6 82 | ], 83 | "fullDate": "EEEE, d MMMM y", 84 | "longDate": "d MMMM y", 85 | "medium": "d MMM y h:mm:ss a", 86 | "mediumDate": "d MMM y", 87 | "mediumTime": "h:mm:ss a", 88 | "short": "d/MM/yy h:mm a", 89 | "shortDate": "d/MM/yy", 90 | "shortTime": "h:mm a" 91 | }, 92 | "NUMBER_FORMATS": { 93 | "CURRENCY_SYM": "RM", 94 | "DECIMAL_SEP": ".", 95 | "GROUP_SEP": ",", 96 | "PATTERNS": [ 97 | { 98 | "gSize": 3, 99 | "lgSize": 3, 100 | "maxFrac": 3, 101 | "minFrac": 0, 102 | "minInt": 1, 103 | "negPre": "-", 104 | "negSuf": "", 105 | "posPre": "", 106 | "posSuf": "" 107 | }, 108 | { 109 | "gSize": 3, 110 | "lgSize": 3, 111 | "maxFrac": 2, 112 | "minFrac": 2, 113 | "minInt": 1, 114 | "negPre": "-\u00a4", 115 | "negSuf": "", 116 | "posPre": "\u00a4", 117 | "posSuf": "" 118 | } 119 | ] 120 | }, 121 | "id": "ms-my", 122 | "localeID": "ms_MY", 123 | "pluralCat": function(n, opt_precision) { return PLURAL_CATEGORY.OTHER;} 124 | }); 125 | }]); 126 | -------------------------------------------------------------------------------- /app/vendor/angular/i18n/angular-locale_ms-sg.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module("ngLocale", [], ["$provide", function($provide) { 3 | var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; 4 | $provide.value("$locale", { 5 | "DATETIME_FORMATS": { 6 | "AMPMS": [ 7 | "PG", 8 | "PTG" 9 | ], 10 | "DAY": [ 11 | "Ahad", 12 | "Isnin", 13 | "Selasa", 14 | "Rabu", 15 | "Khamis", 16 | "Jumaat", 17 | "Sabtu" 18 | ], 19 | "ERANAMES": [ 20 | "S.M.", 21 | "TM" 22 | ], 23 | "ERAS": [ 24 | "S.M.", 25 | "TM" 26 | ], 27 | "FIRSTDAYOFWEEK": 6, 28 | "MONTH": [ 29 | "Januari", 30 | "Februari", 31 | "Mac", 32 | "April", 33 | "Mei", 34 | "Jun", 35 | "Julai", 36 | "Ogos", 37 | "September", 38 | "Oktober", 39 | "November", 40 | "Disember" 41 | ], 42 | "SHORTDAY": [ 43 | "Ahd", 44 | "Isn", 45 | "Sel", 46 | "Rab", 47 | "Kha", 48 | "Jum", 49 | "Sab" 50 | ], 51 | "SHORTMONTH": [ 52 | "Jan", 53 | "Feb", 54 | "Mac", 55 | "Apr", 56 | "Mei", 57 | "Jun", 58 | "Jul", 59 | "Ogo", 60 | "Sep", 61 | "Okt", 62 | "Nov", 63 | "Dis" 64 | ], 65 | "STANDALONEMONTH": [ 66 | "Januari", 67 | "Februari", 68 | "Mac", 69 | "April", 70 | "Mei", 71 | "Jun", 72 | "Julai", 73 | "Ogos", 74 | "September", 75 | "Oktober", 76 | "November", 77 | "Disember" 78 | ], 79 | "WEEKENDRANGE": [ 80 | 5, 81 | 6 82 | ], 83 | "fullDate": "EEEE, d MMMM y", 84 | "longDate": "d MMMM y", 85 | "medium": "d MMM y h:mm:ss a", 86 | "mediumDate": "d MMM y", 87 | "mediumTime": "h:mm:ss a", 88 | "short": "d/MM/yy h:mm a", 89 | "shortDate": "d/MM/yy", 90 | "shortTime": "h:mm a" 91 | }, 92 | "NUMBER_FORMATS": { 93 | "CURRENCY_SYM": "$", 94 | "DECIMAL_SEP": ".", 95 | "GROUP_SEP": ",", 96 | "PATTERNS": [ 97 | { 98 | "gSize": 3, 99 | "lgSize": 3, 100 | "maxFrac": 3, 101 | "minFrac": 0, 102 | "minInt": 1, 103 | "negPre": "-", 104 | "negSuf": "", 105 | "posPre": "", 106 | "posSuf": "" 107 | }, 108 | { 109 | "gSize": 3, 110 | "lgSize": 3, 111 | "maxFrac": 2, 112 | "minFrac": 2, 113 | "minInt": 1, 114 | "negPre": "-\u00a4", 115 | "negSuf": "", 116 | "posPre": "\u00a4", 117 | "posSuf": "" 118 | } 119 | ] 120 | }, 121 | "id": "ms-sg", 122 | "localeID": "ms_SG", 123 | "pluralCat": function(n, opt_precision) { return PLURAL_CATEGORY.OTHER;} 124 | }); 125 | }]); 126 | -------------------------------------------------------------------------------- /app/vendor/angular/i18n/angular-locale_ms.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module("ngLocale", [], ["$provide", function($provide) { 3 | var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; 4 | $provide.value("$locale", { 5 | "DATETIME_FORMATS": { 6 | "AMPMS": [ 7 | "PG", 8 | "PTG" 9 | ], 10 | "DAY": [ 11 | "Ahad", 12 | "Isnin", 13 | "Selasa", 14 | "Rabu", 15 | "Khamis", 16 | "Jumaat", 17 | "Sabtu" 18 | ], 19 | "ERANAMES": [ 20 | "S.M.", 21 | "TM" 22 | ], 23 | "ERAS": [ 24 | "S.M.", 25 | "TM" 26 | ], 27 | "FIRSTDAYOFWEEK": 0, 28 | "MONTH": [ 29 | "Januari", 30 | "Februari", 31 | "Mac", 32 | "April", 33 | "Mei", 34 | "Jun", 35 | "Julai", 36 | "Ogos", 37 | "September", 38 | "Oktober", 39 | "November", 40 | "Disember" 41 | ], 42 | "SHORTDAY": [ 43 | "Ahd", 44 | "Isn", 45 | "Sel", 46 | "Rab", 47 | "Kha", 48 | "Jum", 49 | "Sab" 50 | ], 51 | "SHORTMONTH": [ 52 | "Jan", 53 | "Feb", 54 | "Mac", 55 | "Apr", 56 | "Mei", 57 | "Jun", 58 | "Jul", 59 | "Ogo", 60 | "Sep", 61 | "Okt", 62 | "Nov", 63 | "Dis" 64 | ], 65 | "STANDALONEMONTH": [ 66 | "Januari", 67 | "Februari", 68 | "Mac", 69 | "April", 70 | "Mei", 71 | "Jun", 72 | "Julai", 73 | "Ogos", 74 | "September", 75 | "Oktober", 76 | "November", 77 | "Disember" 78 | ], 79 | "WEEKENDRANGE": [ 80 | 5, 81 | 6 82 | ], 83 | "fullDate": "EEEE, d MMMM y", 84 | "longDate": "d MMMM y", 85 | "medium": "d MMM y h:mm:ss a", 86 | "mediumDate": "d MMM y", 87 | "mediumTime": "h:mm:ss a", 88 | "short": "d/MM/yy h:mm a", 89 | "shortDate": "d/MM/yy", 90 | "shortTime": "h:mm a" 91 | }, 92 | "NUMBER_FORMATS": { 93 | "CURRENCY_SYM": "RM", 94 | "DECIMAL_SEP": ".", 95 | "GROUP_SEP": ",", 96 | "PATTERNS": [ 97 | { 98 | "gSize": 3, 99 | "lgSize": 3, 100 | "maxFrac": 3, 101 | "minFrac": 0, 102 | "minInt": 1, 103 | "negPre": "-", 104 | "negSuf": "", 105 | "posPre": "", 106 | "posSuf": "" 107 | }, 108 | { 109 | "gSize": 3, 110 | "lgSize": 3, 111 | "maxFrac": 2, 112 | "minFrac": 2, 113 | "minInt": 1, 114 | "negPre": "-\u00a4", 115 | "negSuf": "", 116 | "posPre": "\u00a4", 117 | "posSuf": "" 118 | } 119 | ] 120 | }, 121 | "id": "ms", 122 | "localeID": "ms", 123 | "pluralCat": function(n, opt_precision) { return PLURAL_CATEGORY.OTHER;} 124 | }); 125 | }]); 126 | -------------------------------------------------------------------------------- /app/vendor/angular/version.json: -------------------------------------------------------------------------------- 1 | {"raw":"v1.7.8","major":1,"minor":7,"patch":8,"prerelease":[],"build":[],"version":"1.7.8","codeName":"enthusiastic-oblation","full":"1.7.8","branch":"v1.7.x","cdn":{"raw":"v1.7.7","major":1,"minor":7,"patch":7,"prerelease":[],"build":[],"version":"1.7.7","docsUrl":"http://code.angularjs.org/1.7.7/docs"}} -------------------------------------------------------------------------------- /app/vendor/angular/version.txt: -------------------------------------------------------------------------------- 1 | 1.7.8 -------------------------------------------------------------------------------- /app/vendor/console-polyfill/console-polyfill.js: -------------------------------------------------------------------------------- 1 | // Console-polyfill. MIT license. 2 | // https://github.com/paulmillr/console-polyfill 3 | // Make it safe to do console.log() always. 4 | (function (con) { 5 | 'use strict'; 6 | var prop, method; 7 | var empty = {}; 8 | var dummy = function() {}; 9 | var properties = 'memory'.split(','); 10 | var methods = ('assert,count,debug,dir,dirxml,error,exception,group,' + 11 | 'groupCollapsed,groupEnd,info,log,markTimeline,profile,profileEnd,' + 12 | 'time,timeEnd,trace,warn').split(','); 13 | while (prop = properties.pop()) con[prop] = con[prop] || empty; 14 | while (method = methods.pop()) con[method] = con[method] || dummy; 15 | })(this.console = this.console || {}); 16 | 17 | // For Workers compatibility `window` object is replaced with `this` keyword -------------------------------------------------------------------------------- /app/vendor/cryptoJS/THIRDPARTY_LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2013 Jeff Mott 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /app/vendor/jquery.nanoscroller/nanoscroller.css: -------------------------------------------------------------------------------- 1 | /** initial setup **/ 2 | .nano { 3 | position : relative; 4 | width : 100%; 5 | height : 100%; 6 | overflow : hidden; 7 | } 8 | .nano > .nano-content { 9 | position : absolute; 10 | overflow : scroll; 11 | overflow-x : hidden; 12 | top : 0; 13 | right : 0; 14 | bottom : 0; 15 | left : 0; 16 | } 17 | .nano > .nano-content:focus { 18 | outline: thin dotted; 19 | } 20 | .nano > .nano-content::-webkit-scrollbar { 21 | display: none; 22 | } 23 | .has-scrollbar > .nano-content::-webkit-scrollbar { 24 | display: block; 25 | } 26 | .nano > .nano-pane { 27 | background : rgba(0,0,0,.25); 28 | position : absolute; 29 | width : 10px; 30 | right : 0; 31 | top : 0; 32 | bottom : 0; 33 | visibility : hidden\9; /* Target only IE7 and IE8 with this hack */ 34 | opacity : .01; 35 | -webkit-transition : .2s; 36 | -moz-transition : .2s; 37 | -o-transition : .2s; 38 | transition : .2s; 39 | -moz-border-radius : 5px; 40 | -webkit-border-radius : 5px; 41 | border-radius : 5px; 42 | } 43 | .nano > .nano-pane > .nano-slider { 44 | background: #444; 45 | background: rgba(0,0,0,.5); 46 | position : relative; 47 | margin : 0 1px; 48 | -moz-border-radius : 3px; 49 | -webkit-border-radius : 3px; 50 | border-radius : 3px; 51 | } 52 | .nano:hover > .nano-pane, .nano-pane.active, .nano-pane.flashed { 53 | visibility : visible\9; /* Target only IE7 and IE8 with this hack */ 54 | opacity : 0.99; 55 | } 56 | -------------------------------------------------------------------------------- /app/vendor/jsbn/THIRDPARTY_LICENSE: -------------------------------------------------------------------------------- 1 | Licensing 2 | --------- 3 | 4 | This software is covered under the following copyright: 5 | 6 | /* 7 | * Copyright (c) 2003-2005 Tom Wu 8 | * All Rights Reserved. 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining 11 | * a copy of this software and associated documentation files (the 12 | * "Software"), to deal in the Software without restriction, including 13 | * without limitation the rights to use, copy, modify, merge, publish, 14 | * distribute, sublicense, and/or sell copies of the Software, and to 15 | * permit persons to whom the Software is furnished to do so, subject to 16 | * the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be 19 | * included in all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 22 | * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 23 | * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 24 | * 25 | * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, 26 | * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER 27 | * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF 28 | * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT 29 | * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 30 | * 31 | * In addition, the following condition applies: 32 | * 33 | * All redistributions must retain an intact copy of this copyright notice 34 | * and disclaimer. 35 | */ 36 | 37 | Address all questions regarding this license to: 38 | 39 | Tom Wu 40 | tjw@cs.Stanford.EDU 41 | -------------------------------------------------------------------------------- /app/vendor/ogv.js/COPYING: -------------------------------------------------------------------------------- 1 | ogv.js & ogv.swf wrapper and player code 2 | 3 | Copyright (c) 2013-2014 Brion Vibber and other contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/vendor/ogv.js/COPYING-ogg.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2002, Xiph.org Foundation 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | 7 | - Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | - Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | - Neither the name of the Xiph.org Foundation nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION 22 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /app/vendor/ogv.js/COPYING-opus.txt: -------------------------------------------------------------------------------- 1 | Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic, 2 | Jean-Marc Valin, Timothy B. Terriberry, 3 | CSIRO, Gregory Maxwell, Mark Borgerding, 4 | Erik de Castro Lopo 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions 8 | are met: 9 | 10 | - Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 13 | - Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | 17 | - Neither the name of Internet Society, IETF or IETF Trust, nor the 18 | names of specific contributors, may be used to endorse or promote 19 | products derived from this software without specific prior written 20 | permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 26 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | Opus is subject to the royalty-free patent licenses which are 35 | specified at: 36 | 37 | Xiph.Org Foundation: 38 | https://datatracker.ietf.org/ipr/1524/ 39 | 40 | Microsoft Corporation: 41 | https://datatracker.ietf.org/ipr/1914/ 42 | 43 | Broadcom Corporation: 44 | https://datatracker.ietf.org/ipr/1526/ 45 | -------------------------------------------------------------------------------- /app/vendor/ogv.js/COPYING-theora.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2002-2009 Xiph.org Foundation 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | 7 | - Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | - Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | - Neither the name of the Xiph.org Foundation nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION 22 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /app/vendor/ogv.js/COPYING-vorbis.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2002-2008 Xiph.org Foundation 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | 7 | - Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | - Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | - Neither the name of the Xiph.org Foundation nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION 22 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /app/vendor/ogv.js/LICENSE-nestegg.txt: -------------------------------------------------------------------------------- 1 | Copyright © 2010 Mozilla Foundation 2 | 3 | Permission to use, copy, modify, and distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /app/vendor/ogv.js/LICENSE-vpx.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010, The WebM Project authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 15 | * Neither the name of Google, nor the WebM Project, nor the names 16 | of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written 18 | permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | -------------------------------------------------------------------------------- /app/vendor/ogv.js/PATENTS-vpx.txt: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | ------------------------------------ 3 | 4 | "These implementations" means the copyrightable works that implement the WebM 5 | codecs distributed by Google as part of the WebM Project. 6 | 7 | Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, 8 | royalty-free, irrevocable (except as stated in this section) patent license to 9 | make, have made, use, offer to sell, sell, import, transfer, and otherwise 10 | run, modify and propagate the contents of these implementations of WebM, where 11 | such license applies only to those patent claims, both currently owned by 12 | Google and acquired in the future, licensable by Google that are necessarily 13 | infringed by these implementations of WebM. This grant does not include claims 14 | that would be infringed only as a consequence of further modification of these 15 | implementations. If you or your agent or exclusive licensee institute or order 16 | or agree to the institution of patent litigation or any other patent 17 | enforcement activity against any entity (including a cross-claim or 18 | counterclaim in a lawsuit) alleging that any of these implementations of WebM 19 | or any code incorporated within any of these implementations of WebM 20 | constitute direct or contributory patent infringement, or inducement of 21 | patent infringement, then any patent rights granted to you under this License 22 | for these implementations of WebM shall terminate as of the date such 23 | litigation is filed. 24 | -------------------------------------------------------------------------------- /app/vendor/ogv.js/dynamicaudio.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/vendor/ogv.js/dynamicaudio.swf -------------------------------------------------------------------------------- /app/vendor/ogv.js/ogv-decoder-audio-opus-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/vendor/ogv.js/ogv-decoder-audio-opus-wasm.wasm -------------------------------------------------------------------------------- /app/vendor/ogv.js/ogv-decoder-audio-vorbis-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/vendor/ogv.js/ogv-decoder-audio-vorbis-wasm.wasm -------------------------------------------------------------------------------- /app/vendor/ogv.js/ogv-decoder-video-theora-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/vendor/ogv.js/ogv-decoder-video-theora-wasm.wasm -------------------------------------------------------------------------------- /app/vendor/ogv.js/ogv-decoder-video-vp8-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/vendor/ogv.js/ogv-decoder-video-vp8-wasm.wasm -------------------------------------------------------------------------------- /app/vendor/ogv.js/ogv-decoder-video-vp9-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/vendor/ogv.js/ogv-decoder-video-vp9-wasm.wasm -------------------------------------------------------------------------------- /app/vendor/ogv.js/ogv-demuxer-ogg-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/vendor/ogv.js/ogv-demuxer-ogg-wasm.wasm -------------------------------------------------------------------------------- /app/vendor/ogv.js/ogv-demuxer-webm-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhukov/webogram/928731935f36b15a1a886e4be1f3fdec81b6fe7f/app/vendor/ogv.js/ogv-demuxer-webm-wasm.wasm -------------------------------------------------------------------------------- /app/vendor/ogv.js/ogv-version.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) 10 | /******/ return installedModules[moduleId].exports; 11 | 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ exports: {}, 15 | /******/ id: moduleId, 16 | /******/ loaded: false 17 | /******/ }; 18 | 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | 22 | /******/ // Flag the module as loaded 23 | /******/ module.loaded = true; 24 | 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | 29 | 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | 36 | /******/ // __webpack_public_path__ 37 | /******/ __webpack_require__.p = ""; 38 | 39 | /******/ // Load entry module and return exports 40 | /******/ return __webpack_require__(0); 41 | /******/ }) 42 | /************************************************************************/ 43 | /******/ ([ 44 | /* 0 */ 45 | /***/ (function(module, exports, __webpack_require__) { 46 | 47 | // 48 | // -- ogv-support.js 49 | // https://github.com/brion/ogv.js 50 | // Copyright (c) 2013-2016 Brion Vibber 51 | // 52 | 53 | (function() { 54 | 55 | var OGVVersion = ("1.4.2-20170425024925-504d7197"); 56 | 57 | if (window) { 58 | // 1.0-compat globals 59 | window.OGVVersion = OGVVersion; 60 | } 61 | 62 | module.exports = { 63 | OGVVersion: OGVVersion 64 | }; 65 | 66 | })(); 67 | 68 | 69 | /***/ }) 70 | /******/ ]); -------------------------------------------------------------------------------- /app/vendor/ui-bootstrap/THIRDPARTY_LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2012-2013 the AngularUI Team, https://github.com/organizations/angular-ui/teams/291112 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /app/vendor/zlib/THIRDPARTY_LICENSE: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * zlib.js 4 | * JavaScript Zlib Library 5 | * https://github.com/imaya/zlib.js 6 | * 7 | * The MIT License 8 | * 9 | * Copyright (c) 2012 imaya 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy 12 | * of this software and associated documentation files (the "Software"), to deal 13 | * in the Software without restriction, including without limitation the rights 14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | * copies of the Software, and to permit persons to whom the Software is 16 | * furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included in 19 | * all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | * THE SOFTWARE. 28 | */ 29 | -------------------------------------------------------------------------------- /app/webogram.appcache: -------------------------------------------------------------------------------- 1 | CACHE MANIFEST 2 | 3 | # 78 4 | 5 | NETWORK: 6 | * 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Telegram", 3 | "description": "Telegram Web App.\nMore info & source code here: https://github.com/zhukov/webogram", 4 | "version": "0.7.0", 5 | "main": "app/index.html", 6 | "single-instance": true, 7 | "dom_storage_quota": 40, 8 | "window": { 9 | "title": "Telegram", 10 | "icon": "app/img/icons/icon128.png", 11 | "toolbar": false, 12 | "frame": true, 13 | "position": "center", 14 | "resizable": true, 15 | "width": 800, 16 | "min_width": 675, 17 | "height": 650, 18 | "min_height": 650, 19 | "show": true 20 | }, 21 | "scripts": { 22 | "clean": "gulp clean", 23 | "start": "gulp watch", 24 | "test": "gulp test", 25 | "build": "gulp publish" 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/zhukov/webogram.git" 30 | }, 31 | "author": "zhukov", 32 | "license": "GPL-3.0", 33 | "bugs": { 34 | "url": "https://github.com/zhukov/webogram/issues" 35 | }, 36 | "locales": [ 37 | "en-us", 38 | "es-es", 39 | "de-de", 40 | "it-it", 41 | "ru-ru", 42 | "nl-nl", 43 | "pt-br" 44 | ], 45 | "homepage": "http://zhukov.github.io/webogram", 46 | "devDependencies": { 47 | "del": "^4.1.1", 48 | "gulp": "^4.0.2", 49 | "gulp-angular-templatecache": "^3.0.0", 50 | "gulp-concat": "^2.1.7", 51 | "gulp-grep-stream": "0.0.2", 52 | "gulp-imagemin": "^5.0.3", 53 | "gulp-less": "^4.0.1", 54 | "gulp-livereload": "^4.0.1", 55 | "gulp-load-plugins": "^2.0.1", 56 | "gulp-manifest3": "0.1.2", 57 | "gulp-minify-css": "^0.3.12", 58 | "gulp-minify-html": "^0.1.1", 59 | "gulp-ng-annotate": "~0.5.2", 60 | "gulp-replace": "^0.2.0", 61 | "gulp-rev": "^1.1.0", 62 | "gulp-standard": "^7.0.1", 63 | "gulp-uglify": "^1.0.2", 64 | "gulp-usemin": "^0.3.29", 65 | "gulp-zip": "^0.1.2", 66 | "http": "0.0.0", 67 | "jasmine-core": "^2.5.2", 68 | "karma": "^4.1.0", 69 | "karma-coverage": "^1.1.1", 70 | "karma-jasmine": "^1.1.0", 71 | "karma-phantomjs-launcher": "^1.0.2", 72 | "phantomjs-prebuilt": "^2.1.14", 73 | "st": ">=1.2.2", 74 | "sw-precache": "^3.2.0" 75 | }, 76 | "standard": { 77 | "globals": [ 78 | "angular", 79 | "$", 80 | "chrome" 81 | ] 82 | }, 83 | "dependencies": {} 84 | } 85 | -------------------------------------------------------------------------------- /scripts/emoji_data/build.php: -------------------------------------------------------------------------------- 1 | > 10) & 0x3FF); 56 | $byte2 = 0xDC00 | ($code & 0x3FF); 57 | 58 | return "\\u".sprintf('%04X', $byte1)."\\u".sprintf('%04X', $byte2); 59 | } -------------------------------------------------------------------------------- /scripts/ua_handler.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'), path = require('path'); 2 | var uaList = fs.readFileSync(path.join(__dirname, 'ua.txt')); 3 | 4 | 5 | uaList = uaList.toString().split('\n'); 6 | 7 | 8 | var OSs = {}; 9 | var browsers = {}; 10 | var browserVersions = {}; 11 | var unknown = []; 12 | 13 | var osMatch = { 14 | ios: /iOS|iPhone OS/i, 15 | android: /Android/i, 16 | linux: /Linux/i, 17 | win: /Windows/i, 18 | osx: /Mac|OS X/i, 19 | blackberry: /BlackBerry|BB10/i, 20 | series60: /Series 60|Series60/i, 21 | series40: /Series 40|Series40/i, 22 | j2me: /J2ME|MIDP/i 23 | }; 24 | 25 | var browserMatch = { 26 | opera: /opera/i, 27 | ie: /msie|trident\//i, 28 | chrome: /chrome/i, 29 | chromium: /chromium/i, 30 | safari: /safari|AppleWebKit/i, 31 | firefox: /firefox/i, 32 | blackberry: /BlackBerry/i 33 | }; 34 | 35 | var featureMatch = { 36 | ipad: /ipad/i, 37 | opera_mobile: /opera mini|opera mobi/i, 38 | opera_mini: /opera mini/i, 39 | blackberry: /blackberry/i 40 | }; 41 | 42 | uaList.forEach(function (uaName) { 43 | var os = 'unknown'; 44 | for (var curOs in osMatch) { 45 | if (uaName.match(osMatch[curOs])) { 46 | os = curOs; 47 | break; 48 | } 49 | } 50 | 51 | var browser = 'unknown'; 52 | for (var curBrowser in browserMatch) { 53 | if (uaName.match(browserMatch[curBrowser])) { 54 | browser = curBrowser; 55 | break; 56 | } 57 | } 58 | 59 | var version = ( 60 | uaName.match(/MSIE ([\d.]+)/) || 61 | uaName.match( /.+(?:me|ox|on|rv|it|era|opr|ie)[\/: ]([\d.]+)/) || 62 | [0,'0'] 63 | )[1]; 64 | 65 | if (!OSs[os]) { 66 | OSs[os] = 1; 67 | } else { 68 | OSs[os]++; 69 | } 70 | 71 | if (!browsers[os + ' ' + browser]) { 72 | browsers[os + ' ' + browser] = 1; 73 | } else { 74 | browsers[os + ' ' + browser]++; 75 | } 76 | 77 | if (os == 'unknown' || browser == 'unknown') { 78 | unknown.push(uaName); 79 | } 80 | 81 | if (!browserVersions[os + ' ' + browser + ' ' + version]) { 82 | browserVersions[os + ' ' + browser + ' ' + version] = 1; 83 | } else { 84 | browserVersions[os + ' ' + browser + ' ' + version]++; 85 | } 86 | 87 | }) 88 | 89 | 90 | console.log(OSs); 91 | console.log(browsers); 92 | console.log(browserVersions); 93 | // console.log(unknown); 94 | 95 | -------------------------------------------------------------------------------- /test/test-init.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global ConfigStorage, Config */ 3 | 4 | ;(function initTestApplication () { 5 | ConfigStorage.get('layout_selected', 'i18n_locale', function (params) { 6 | var locale = params[1] 7 | var defaultLocale = 'en-us' 8 | var bootReady = { 9 | dom: false, 10 | i18n_ng: false, 11 | i18n_messages: false, 12 | i18n_fallback: false 13 | } 14 | 15 | if (!locale) { 16 | locale = (navigator.language || '').toLowerCase() 17 | locale = Config.I18n.aliases[locale] || locale 18 | } 19 | for (var i = 0; i < Config.I18n.supported.length; i++) { 20 | if (Config.I18n.supported[i] === locale) { 21 | Config.I18n.locale = locale 22 | break 23 | } 24 | } 25 | bootReady.i18n_ng = Config.I18n.locale === defaultLocale // Already included 26 | 27 | $.getJSON('base/js/locales/' + Config.I18n.locale + '.json').success(function (json) { 28 | Config.I18n.messages = json 29 | bootReady.i18n_messages = true 30 | if (Config.I18n.locale === defaultLocale) { // No fallback, leave empty object 31 | bootReady.i18n_fallback = true 32 | } 33 | }) 34 | 35 | if (Config.I18n.locale !== defaultLocale) { 36 | $.getJSON('base/js/locales/' + defaultLocale + '.json').success(function (json) { 37 | Config.I18n.fallback_messages = json 38 | bootReady.i18n_fallback = true 39 | }) 40 | } 41 | }) 42 | })() 43 | -------------------------------------------------------------------------------- /test/unit/controllers/AppFooterControllerSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('AppFooterController', function () { 5 | beforeEach(module('myApp.controllers')) 6 | 7 | beforeEach(function () { 8 | this.LayoutSwitchService = { 9 | serviceFlag: false, 10 | switchLayout: function (parameter) { 11 | this.serviceFlag = true 12 | } 13 | } 14 | 15 | inject(function (_$controller_, _$rootScope_) { 16 | this.$controller = _$controller_ 17 | 18 | this.$scope = _$rootScope_.$new() 19 | this.$controller('AppFooterController', { 20 | $scope: this.$scope, 21 | LayoutSwitchService: this.LayoutSwitchService 22 | }) 23 | }) 24 | }) 25 | 26 | // define tests 27 | it('calls the right function', function (done) { 28 | expect(this.LayoutSwitchService.serviceFlag).toBe(false) 29 | this.$scope.switchLayout(true) 30 | expect(this.LayoutSwitchService.serviceFlag).toBe(true) 31 | done() 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /test/unit/controllers/AppImPanelControllerSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach, jasmine */ 3 | 4 | describe('AppImPanelController', function () { 5 | beforeEach(module('myApp.controllers')) 6 | 7 | beforeEach(function () { 8 | inject(function (_$controller_, _$rootScope_) { 9 | this.$scope = _$rootScope_.$new() 10 | this.$scope.$on = jasmine.createSpy('$on') 11 | _$controller_('AppImPanelController', { $scope: this.$scope }) 12 | }) 13 | }) 14 | 15 | // define tests 16 | it('sets $on(user_update) to no-operation function', function (done) { 17 | expect(this.$scope.$on).toHaveBeenCalledWith('user_update', angular.noop) 18 | done() 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /test/unit/controllers/AppLangSelectControllerSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach, xit */ 3 | 4 | describe('AppLangSelectController', function () { 5 | beforeEach(module('ui.bootstrap')) 6 | beforeEach(module('myApp.services')) 7 | beforeEach(module('myApp.controllers')) 8 | 9 | beforeEach(function () { 10 | inject(function (_$controller_, _$rootScope_, _, Storage, ErrorService, AppRuntimeManager) { 11 | this.$controller = _$controller_ 12 | this.$scope = _$rootScope_.$new() 13 | 14 | this.$controller('AppLangSelectController', { 15 | $scope: this.$scope, 16 | _: _, 17 | Storage: Storage, 18 | ErrorService: ErrorService, 19 | AppRuntimeManager: AppRuntimeManager 20 | }) 21 | }) 22 | }) 23 | 24 | it('holds the supportedLocales', function () { 25 | expect(this.$scope.supportedLocales).toBeDefined() 26 | }) 27 | 28 | it('holds langNames', function () { 29 | expect(this.$scope.langNames).toBeDefined() 30 | }) 31 | 32 | it('holds the current locale', function () { 33 | expect(this.$scope.curLocale).toBeDefined() 34 | }) 35 | 36 | it('has a locale form', function () { 37 | expect(this.$scope.form).toBeDefined() 38 | expect(this.$scope.form.locale).toBeDefined() 39 | }) 40 | 41 | it('allows to select a locale', function () { 42 | expect(this.$scope.localeSelect).toBeDefined() 43 | }) 44 | 45 | describe('when the user switches the locale', function () { 46 | describe('and confirms the dialogue', function () { 47 | xit('reloads the app', function (done) { 48 | done() 49 | }) 50 | }) 51 | }) 52 | }) 53 | -------------------------------------------------------------------------------- /test/unit/controllers/AppWelcomeControllerSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('AppWelcomeController', function () { 5 | beforeEach(module('myApp.controllers')) 6 | 7 | beforeEach(function () { 8 | this.ChangelogNotifyService = { 9 | checkUpdate: function () {} 10 | } 11 | 12 | this.LayoutSwitchService = { 13 | start: function () {} 14 | } 15 | 16 | this.MtpApiManager = { 17 | getUserID: function () { 18 | return { 19 | then: function () {} 20 | } 21 | } 22 | } 23 | 24 | inject(function (_$controller_, _$rootScope_, _$location_) { 25 | this.$controller = _$controller_ 26 | this.$rootScope = _$rootScope_ 27 | this.$location = _$location_ 28 | this.$scope = _$rootScope_.$new() 29 | 30 | this.$controller('AppWelcomeController', { 31 | $scope: this.$scope, 32 | $location: this.$location, 33 | MtpApiManager: this.MtpApiManager, 34 | ErrorService: this.ErrorService, 35 | ChangelogNotifyService: this.ChangelogNotifyService, 36 | LayoutSwitchService: this.LayoutSwitchService 37 | }) 38 | }) 39 | }) 40 | 41 | // https://stackoverflow.com/a/36460924 42 | it('executes a dummy spec', function (done) { 43 | expect(true).toBe(true) 44 | done() 45 | }) 46 | }) 47 | -------------------------------------------------------------------------------- /test/unit/controllers/ChangelogModalControlelerSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach, Config */ 3 | 4 | describe('ChangeLogModalController', function () { 5 | beforeEach(module('myApp.controllers')) 6 | 7 | beforeEach(function () { 8 | this.modal = { 9 | modalFlag: false, 10 | open: function (data) { 11 | this.modalFlag = true 12 | } 13 | } 14 | 15 | inject(function (_$controller_, _$rootScope_) { 16 | this.$controller = _$controller_ 17 | 18 | this.$scope = _$rootScope_.$new() 19 | 20 | this.$controller('ChangelogModalController', { 21 | $scope: this.$scope, 22 | $modal: this.modal 23 | }) 24 | }) 25 | }) 26 | 27 | // define tests 28 | it('will have standard data when no function is called', function (done) { 29 | expect(this.$scope.changelogHidden).toBe(false) 30 | expect(this.$scope.changelogShown).toBe(false) 31 | expect(this.$scope.currentVersion).toBe(Config.App.version) 32 | done() 33 | }) 34 | 35 | it('will show the changelog', function (done) { 36 | this.$scope.showAllVersions() 37 | expect(this.$scope.changelogHidden).toBe(false) 38 | expect(this.$scope.changelogShown).toBe(true) 39 | done() 40 | }) 41 | 42 | it('will allow to show any version when "changelogShown" is true', function (done) { 43 | this.$scope.changelogShown = true 44 | expect(this.$scope.canShowVersion(null)).toBe(true) 45 | expect(this.$scope.canShowVersion('0.0.1')).toBe(true) 46 | expect(this.$scope.canShowVersion('0.1.0')).toBe(true) 47 | expect(this.$scope.canShowVersion('1.0.0')).toBe(true) 48 | done() 49 | }) 50 | 51 | it('will allow the version to be shown when the current verion is bigger than the last function', function (done) { 52 | expect(this.$scope.canShowVersion('100.100.100')).toBe(true) 53 | done() 54 | }) 55 | 56 | it('won\'t allow the version to be shown when it is smaller than the current version', function (done) { 57 | expect(this.$scope.changelogHidden).toBe(false) 58 | expect(this.$scope.canShowVersion('0.0.0')).toBe(false) 59 | expect(this.$scope.changelogHidden).toBe(true) 60 | done() 61 | }) 62 | 63 | it('will call modal when the changeUsername function is called', function (done) { 64 | expect(this.modal.modalFlag).toBe(false) 65 | this.$scope.changeUsername() 66 | expect(this.modal.modalFlag).toBe(true) 67 | done() 68 | }) 69 | }) 70 | -------------------------------------------------------------------------------- /test/unit/directives/myHeadDirective.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('myHead directive', function () { 5 | beforeEach(module('myApp.templates')) 6 | beforeEach(module('myApp.directives')) 7 | 8 | beforeEach(inject(function (_$compile_, _$rootScope_) { 9 | this.$compile = _$compile_ 10 | this.$rootScope = _$rootScope_ 11 | })) 12 | 13 | it('compiles a my-head attribute', function () { 14 | var compiledElement = this.$compile('
    ')(this.$rootScope) 15 | this.$rootScope.$digest() 16 | expect(compiledElement.html()).toContain('tg_page_head') 17 | }) 18 | 19 | it('compiles a my-head element', function () { 20 | var compiledElement = this.$compile('')(this.$rootScope) 21 | this.$rootScope.$digest() 22 | expect(compiledElement.html()).toContain('tg_page_head') 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /test/unit/directives/myLangFooterDirective.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('myLangFooter directive', function () { 5 | beforeEach(module('ui.bootstrap')) 6 | beforeEach(module('myApp.templates')) 7 | // ErrorServiceProvider in myApp.services is needed by 8 | // AppLangSelectController in myApp.controllers 9 | beforeEach(module('myApp.services')) 10 | beforeEach(module('myApp.controllers')) 11 | beforeEach(module('myApp.directives')) 12 | 13 | beforeEach(inject(function (_$compile_, _$rootScope_) { 14 | this.$compile = _$compile_ 15 | this.$rootScope = _$rootScope_ 16 | })) 17 | 18 | it('compiles a my-lang-footer attribute', function () { 19 | var compiledElement = this.$compile('
    ')(this.$rootScope) 20 | this.$rootScope.$digest() 21 | expect(compiledElement.html()).toContain('footer_lang_link') 22 | expect(compiledElement.html()).toContain('AppLangSelectController') 23 | }) 24 | 25 | it('compiles a my-lang-footer element', function () { 26 | var compiledElement = this.$compile('')(this.$rootScope) 27 | this.$rootScope.$digest() 28 | expect(compiledElement.html()).toContain('footer_lang_link') 29 | expect(compiledElement.html()).toContain('AppLangSelectController') 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /test/unit/filters/chatTitleFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('chatTitle filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_, ___) { 8 | this.$filter = _$filter_ 9 | this._ = ___ 10 | })) 11 | 12 | beforeEach(function () { 13 | this.chatTitleFilter = this.$filter('chatTitle') 14 | }) 15 | 16 | it('displays chat title deleted', function () { 17 | var expected = this._('chat_title_deleted') 18 | var actual = this.chatTitleFilter(null) 19 | 20 | expect(actual).toEqual(expected) 21 | }) 22 | 23 | it('displays the chat title', function () { 24 | var chat = { 25 | title: 'Telegraph is hot!' 26 | } 27 | var expected = chat.title 28 | var actual = this.chatTitleFilter(chat) 29 | 30 | expect(actual).toEqual(expected) 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /test/unit/filters/dateOrTimeFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach, tsNow*/ 3 | 4 | describe('dateOrTime filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_) { 8 | this.$filter = _$filter_ 9 | })) 10 | 11 | beforeEach(function () { 12 | this.dateOrTimeFilter = this.$filter('dateOrTime') 13 | 14 | // https://stackoverflow.com/questions/4676195/why-do-i-need-to-multiply-unix-timestamps-by-1000-in-javascript 15 | this.miliSecondsToSeconds = 1000 16 | this.sevenDaysAgo = -3600 * 24 * 7 17 | this.thirteenHoursAgo = -3600 * 13 18 | }) 19 | 20 | it('can handle "zero"-values', function () { 21 | var input = 0 22 | var expected = '' 23 | var result = this.dateOrTimeFilter(input, false) 24 | 25 | expect(result).toBe(expected) 26 | }) 27 | 28 | it('can display the time based on timestamp', function () { 29 | var input = tsNow(true) 30 | // Outcome format expected: HH:MM AM/PM 31 | var expected = this.$filter('date')(input * this.miliSecondsToSeconds, 'shortTime') 32 | var result = this.dateOrTimeFilter(input, false) 33 | 34 | expect(result).toBe(expected) 35 | }) 36 | 37 | it('can display the short date based on timestamp', function () { 38 | var input = tsNow(true) 39 | // Outcome format expected: (M or MM)/(D or DD)/YY 40 | var expected = this.$filter('date')((input + this.sevenDaysAgo) * this.miliSecondsToSeconds, 'shortDate') 41 | var result = this.dateOrTimeFilter(input + this.sevenDaysAgo, false) 42 | 43 | expect(result).toBe(expected) 44 | }) 45 | 46 | it('can display the medium-size date based on timestamp', function () { 47 | var input = tsNow(true) 48 | // Outcome format expected: Month(3 letters) Day, Year 49 | var expected = this.$filter('date')((input + this.sevenDaysAgo) * this.miliSecondsToSeconds, 'mediumDate') 50 | var result = this.dateOrTimeFilter(input + this.sevenDaysAgo, true) 51 | 52 | expect(result).toBe(expected) 53 | }) 54 | 55 | it('can display the day of the week (in short) based on timestamp', function () { 56 | var input = tsNow(true) 57 | // Outcome format expcected: Day of week in three letters (Mon, Tue, etc.) 58 | var expected = this.$filter('date')((input + this.thirteenHoursAgo) * this.miliSecondsToSeconds, 'EEE') 59 | var result = this.dateOrTimeFilter(input + this.thirteenHoursAgo, false) 60 | 61 | expect(result).toBe(expected) 62 | }) 63 | 64 | it('can display the day of the week based on timestamp', function () { 65 | var input = tsNow(true) 66 | // Outcome format expcected: Day of week (Monday, Tuesday, etc.) 67 | var expected = this.$filter('date')((input + this.thirteenHoursAgo) * this.miliSecondsToSeconds, 'EEEE') 68 | var result = this.dateOrTimeFilter(input + this.thirteenHoursAgo, true) 69 | 70 | expect(result).toBe(expected) 71 | }) 72 | }) 73 | -------------------------------------------------------------------------------- /test/unit/filters/durationFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('duration filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_) { 8 | this.$filter = _$filter_ 9 | })) 10 | 11 | beforeEach(function () { 12 | this.durationFilter = this.$filter('duration') 13 | }) 14 | 15 | it('converts duration in seconds to a readable string', function () { 16 | var input = 55 17 | var expected = '0:55' 18 | var result = this.durationFilter(input) 19 | 20 | expect(result).toBe(expected) 21 | 22 | input = 147 23 | expected = '2:27' 24 | result = this.durationFilter(input) 25 | 26 | expect(result).toBe(expected) 27 | }) 28 | 29 | it('converts hours in seconds to readable string', function () { 30 | var input = 7282 31 | var expected = '2:01:22' 32 | var result = this.durationFilter(input) 33 | 34 | expect(result).toBe(expected) 35 | 36 | input = 4201 37 | expected = '1:10:01' 38 | result = this.durationFilter(input) 39 | 40 | expect(result).toBe(expected) 41 | }) 42 | 43 | it('returns "zero" when not a valid input was given', function () { 44 | var input = 'not a number' 45 | var expected = '0:00' 46 | var result = this.durationFilter(input) 47 | 48 | expect(result).toBe(expected) 49 | 50 | input = {} 51 | result = this.durationFilter(input) 52 | 53 | expect(result).toBe(expected) 54 | 55 | input = [] 56 | result = this.durationFilter(input) 57 | 58 | expect(result).toBe(expected) 59 | }) 60 | }) 61 | -------------------------------------------------------------------------------- /test/unit/filters/durationRemainsFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('durationRemains filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_) { 8 | this.$filter = _$filter_ 9 | })) 10 | 11 | beforeEach(function () { 12 | this.durationRemainsFilter = this.$filter('durationRemains') 13 | }) 14 | 15 | it('creates a readable string based on time and total time', function () { 16 | var totalTime = 120 // two minutes 17 | var currentTime = 100 18 | var expected = '-0:20' 19 | var result = this.durationRemainsFilter(currentTime, totalTime) 20 | 21 | expect(result).toBe(expected) 22 | }) 23 | 24 | // Other behaviour is tested in durationFilterSpec.js 25 | }) 26 | -------------------------------------------------------------------------------- /test/unit/filters/formatShortNumberFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('formatShortNumber filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_) { 8 | this.$filter = _$filter_ 9 | })) 10 | 11 | beforeEach(function () { 12 | this.formatShortNumberFilter = this.$filter('formatShortNumber') 13 | }) 14 | 15 | it('converts zero or undefined', function () { 16 | var input = 0 17 | var expected = '0' 18 | var result = this.formatShortNumberFilter(input) 19 | 20 | expect(result).toBe(expected) 21 | 22 | input = undefined 23 | result = this.formatShortNumberFilter(input) 24 | 25 | expect(result).toBe(expected) 26 | }) 27 | 28 | it('converts numbers below 1000 to string with same value', function () { 29 | var input = 127 30 | var expected = '127' 31 | var result = this.formatShortNumberFilter(input) 32 | 33 | expect(result).toBe(expected) 34 | 35 | input = 999 36 | expected = '999' 37 | result = this.formatShortNumberFilter(input) 38 | 39 | expect(result).toBe(expected) 40 | }) 41 | 42 | it('converts numbers between 1000 and 900000 to string with shortened value', function () { 43 | var input = 1276 44 | var expected = '1.3K' 45 | var result = this.formatShortNumberFilter(input) 46 | 47 | expect(result).toBe(expected) 48 | 49 | input = 35444 50 | expected = '35K' 51 | result = this.formatShortNumberFilter(input) 52 | 53 | expect(result).toBe(expected) 54 | 55 | input = 899999 56 | expected = '900K' 57 | result = this.formatShortNumberFilter(input) 58 | 59 | expect(result).toBe(expected) 60 | }) 61 | 62 | it('converts numbers above 900000 to string with shortened value', function () { 63 | var input = 900000 64 | var expected = '0.9M' 65 | var result = this.formatShortNumberFilter(input) 66 | 67 | expect(result).toBe(expected) 68 | 69 | input = 76785646867 70 | expected = '76786M' 71 | result = this.formatShortNumberFilter(input) 72 | 73 | expect(result).toBe(expected) 74 | }) 75 | }) 76 | -------------------------------------------------------------------------------- /test/unit/filters/formatSizeFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('formatSize filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_) { 8 | this.$filter = _$filter_ 9 | })) 10 | 11 | beforeEach(function () { 12 | this.formatSizeFilter = this.$filter('formatSize') 13 | }) 14 | 15 | it('converts zero', function () { 16 | var input = 0 17 | var expected = '0' 18 | var result = this.formatSizeFilter(input, false) 19 | 20 | expect(result).toBe(expected) 21 | }) 22 | 23 | it('converts sizes below 1024 to byte', function () { 24 | var input = 234 25 | var expected = '234 b' 26 | var result = this.formatSizeFilter(input, false) 27 | 28 | expect(result).toBe(expected) 29 | 30 | input = 1023 31 | expected = '1023 b' 32 | result = this.formatSizeFilter(input, false) 33 | 34 | expect(result).toBe(expected) 35 | }) 36 | 37 | it('converts sizes between 1024 and 1048576 to KB', function () { 38 | var input = 238994 39 | var expected = '233 KB' 40 | var result = this.formatSizeFilter(input, false) 41 | 42 | expect(result).toBe(expected) 43 | 44 | input = 1048575 45 | expected = '1024 KB' 46 | result = this.formatSizeFilter(input, false) 47 | 48 | expect(result).toBe(expected) 49 | }) 50 | 51 | it('converts sizes above 1048576 to MB', function () { 52 | var input = 10485726 53 | var expected = '10 MB' 54 | var result = this.formatSizeFilter(input, false) 55 | 56 | expect(result).toBe(expected) 57 | 58 | input = 1048572676967876 59 | expected = '999996830.9 MB' 60 | result = this.formatSizeFilter(input, false) 61 | 62 | expect(result).toBe(expected) 63 | 64 | input = 10485726 65 | expected = '10.0 MB' 66 | result = this.formatSizeFilter(input, true) 67 | 68 | expect(result).toBe(expected) 69 | 70 | input = 1048572676967876 71 | expected = '999996830.9 MB' 72 | result = this.formatSizeFilter(input, true) 73 | 74 | expect(result).toBe(expected) 75 | }) 76 | }) 77 | -------------------------------------------------------------------------------- /test/unit/filters/formatSizeProgressFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('formatSizeProgress filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_, ___) { 8 | this.$filter = _$filter_ 9 | this._ = ___ 10 | })) 11 | 12 | beforeEach(function () { 13 | this.formatSizeProgressFilter = this.$filter('formatSizeProgress') 14 | }) 15 | 16 | it('can handle "zero"-input', function () { 17 | var input = { total: 0 } 18 | var expected = '' 19 | var result = this.formatSizeProgressFilter(input) 20 | 21 | expect(result).toBe(expected) 22 | }) 23 | 24 | it('can format progress with different scale of magnitude', function () { 25 | var input = { total: 1024, done: 1023 } 26 | var expected = this._('format_size_progress', {done: '1023 b', total: '1 KB'}) 27 | var result = this.formatSizeProgressFilter(input) 28 | 29 | expect(result).toBe(expected) 30 | }) 31 | 32 | it('can format progress with the same scale of size', function () { 33 | var input = { total: 2048, done: 1024 } 34 | var expected = this._('format_size_progress_mulitple', {done: '1', total: '2', parts: 'KB'}) 35 | var result = this.formatSizeProgressFilter(input) 36 | 37 | expect(result).toBe(expected) 38 | }) 39 | 40 | // Further testing for options is done in formatSizeFilterSpec.js 41 | }) 42 | -------------------------------------------------------------------------------- /test/unit/filters/myDateFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('myDate filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_) { 8 | this.$filter = _$filter_ 9 | })) 10 | 11 | beforeEach(function () { 12 | this.myDateFilter = this.$filter('myDate') 13 | 14 | // https://stackoverflow.com/questions/4676195/why-do-i-need-to-multiply-unix-timestamps-by-1000-in-javascript 15 | this.miliSecondsToSeconds = 1000 16 | this.dateFilter = this.$filter('date') 17 | }) 18 | 19 | it('can create a date based on timestamp', function () { 20 | var input = 1222222222 21 | var expected = this.dateFilter(input * this.miliSecondsToSeconds, 'fullDate') // For CEST: 'Wednesday, September 24, 2008' 22 | var result = this.myDateFilter(input) 23 | 24 | expect(result).toBe(expected) 25 | }) 26 | 27 | it('can recollect a date based on timestamp', function () { 28 | var input = 12111114111 29 | var expected = this.dateFilter(input * this.miliSecondsToSeconds, 'fullDate') // For CEST: 'Thursday, October 15, 2353' 30 | var result1 = this.myDateFilter(input) 31 | 32 | expect(result1).toBe(expected) 33 | 34 | var result2 = this.myDateFilter(input) 35 | 36 | expect(result2).toBe(expected) 37 | }) 38 | }) 39 | -------------------------------------------------------------------------------- /test/unit/filters/nl2brFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('nl2br filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_, ___) { 8 | this.$filter = _$filter_ 9 | })) 10 | 11 | beforeEach(function () { 12 | this.nl2brFilter = this.$filter('nl2br') 13 | }) 14 | 15 | it('replaces an enter by a break-tag', function () { 16 | var input = 'Line one \n Line 2' 17 | var expected = 'Line one
    Line 2' 18 | var result = this.nl2brFilter(input) 19 | 20 | expect(result).toBe(expected) 21 | }) 22 | 23 | it('replaces enters by break-tags', function () { 24 | var input = 'Line one \n Line 2 \n Line 3' 25 | var expected = 'Line one
    Line 2
    Line 3' 26 | var result = this.nl2brFilter(input) 27 | 28 | expect(result).toBe(expected) 29 | }) 30 | 31 | it('does not change the text if no enter is present', function () { 32 | var input, expected 33 | input = expected = 'Some random line with no enters' 34 | var result = this.nl2brFilter(input) 35 | 36 | expect(result).toBe(expected) 37 | }) 38 | }) 39 | -------------------------------------------------------------------------------- /test/unit/filters/phoneNumberFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('phoneNumber filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_) { 8 | this.$filter = _$filter_ 9 | })) 10 | 11 | beforeEach(function () { 12 | this.phoneNumberFilter = this.$filter('phoneNumber') 13 | }) 14 | 15 | it('can handle "zero" values', function () { 16 | var input 17 | var expected = '+' 18 | var result = this.phoneNumberFilter(input) 19 | 20 | expect(result).toBe(expected) 21 | 22 | input = null 23 | result = this.phoneNumberFilter(input) 24 | 25 | expect(result).toBe(expected) 26 | 27 | input = 0 28 | result = this.phoneNumberFilter(input) 29 | 30 | expect(result).toBe(expected) 31 | }) 32 | 33 | it('removes all non-digits from a phoneNumber', function () { 34 | var input = '123nonnumber333333e3' 35 | var expected = '+1233333333' 36 | var result = this.phoneNumberFilter(input) 37 | 38 | expect(result).toBe(expected) 39 | }) 40 | 41 | it('converts phone number to a readable phone number (for Russia)', function () { 42 | // 7 is for russian Country calling code (https://en.wikipedia.org/wiki/Telephone_numbers_in_Europe) 43 | var input = '71234567890' 44 | var expected = '+7 (123) 456-78-90' 45 | var result = this.phoneNumberFilter(input) 46 | 47 | expect(result).toBe(expected) 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /test/unit/filters/realtiveTimeFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach, jasmine, tsNow*/ 3 | 4 | describe('relativeTime filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_, ___) { 8 | this.$filter = _$filter_ 9 | this._ = ___ 10 | })) 11 | 12 | beforeEach(function () { 13 | this.minuteSpy = jasmine.createSpy() 14 | this.hourSpy = jasmine.createSpy() 15 | // local vars are used to prevent scoping problems 16 | var ms = this.minuteSpy 17 | var hs = this.hourSpy 18 | this._.pluralize = function (msgid) { 19 | if (msgid === 'relative_time_pluralize_minutes_ago') { 20 | return ms 21 | } else if (msgid === 'relative_time_pluralize_hours_ago') { 22 | return hs 23 | } 24 | } 25 | 26 | this.relativeTimeFilter = this.$filter('relativeTime', {$filter: this.$filter, _: this._}) 27 | }) 28 | 29 | it('can mark time as "just now"', function () { 30 | var input = tsNow(true) 31 | var expected = this._('relative_time_just_now') 32 | var result = this.relativeTimeFilter(input) 33 | 34 | expect(result).toBe(expected) 35 | }) 36 | 37 | // because the exact of tsNow in hard to estimate, a Spy is used instead of checking the return value 38 | it('can convert time that is max. 1 hour away', function () { 39 | var input = tsNow(true) - 3500 40 | this.relativeTimeFilter(input) 41 | 42 | expect(this.minuteSpy).toHaveBeenCalled() 43 | }) 44 | 45 | // because the exact of tsNow in hard to estimate, a Spy is used instead of checking the return value 46 | it('can convert time that is max. 24 hours away', function () { 47 | var input = tsNow(true) - 86000 48 | this.relativeTimeFilter(input) 49 | 50 | expect(this.hourSpy).toHaveBeenCalled() 51 | }) 52 | 53 | it('can convert time after 24 hours based on timestamp', function () { 54 | var input = tsNow(true) - 1000000 55 | var expected = this.$filter('dateOrTime')(input, true) 56 | var result = this.relativeTimeFilter(input) 57 | 58 | expect(result).toBe(expected) 59 | }) 60 | 61 | // Further testing on the dateOrTimeFilter is present in dateOrTimeFilterSpec.js 62 | }) 63 | -------------------------------------------------------------------------------- /test/unit/filters/richTextFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('richText filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | beforeEach(module('ngSanitize')) // necessary for linky filter 7 | 8 | beforeEach(inject(function (_$filter_) { 9 | this.$filter = _$filter_ 10 | })) 11 | 12 | beforeEach(function () { 13 | this.richTextFilter = this.$filter('richText') 14 | }) 15 | 16 | it('changes url to actual link', function () { 17 | var input = 'a text that links to https://www.github.com' 18 | var expected = 'a text that links to https://www.github.com' 19 | var result = this.richTextFilter(input) 20 | 21 | expect(result).toBe(expected) 22 | }) 23 | 24 | it('changes urls to actual links', function () { 25 | var input = 'a text that links to https://www.github.com and https://www.github.com/zhukov/webogram' 26 | var expected = 'a text that links to https://www.github.com and https://www.github.com/zhukov/webogram' 27 | var result = this.richTextFilter(input) 28 | 29 | expect(result).toBe(expected) 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /test/unit/filters/shortUrlFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('shortUrl filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_) { 8 | this.$filter = _$filter_ 9 | })) 10 | 11 | beforeEach(function () { 12 | this.shortUrlFilter = this.$filter('shortUrl') 13 | }) 14 | 15 | it('does not do anything if the input is not a string', function () { 16 | var input = {} 17 | var expected = input 18 | var result = this.shortUrlFilter(input) 19 | 20 | expect(result).toBe(expected) 21 | 22 | input = [] 23 | expected = input 24 | result = this.shortUrlFilter(input) 25 | 26 | expect(result).toBe(expected) 27 | 28 | input = 11 29 | expected = input 30 | result = this.shortUrlFilter(input) 31 | 32 | expect(result).toBe(expected) 33 | }) 34 | 35 | it('removes "http(s)" from a Url', function () { 36 | var input = 'https://github.com' 37 | var expected = 'github.com' 38 | var result = this.shortUrlFilter(input) 39 | 40 | expect(result).toBe(expected) 41 | 42 | input = 'http://github.com' 43 | result = this.shortUrlFilter(input) 44 | 45 | expect(result).toBe(expected) 46 | }) 47 | 48 | it('does not remove other protocols from a Url', function () { 49 | var input, expected 50 | input = expected = 'ftp://github.com' 51 | var result = this.shortUrlFilter(input) 52 | 53 | expect(result).toBe(expected) 54 | 55 | input = expected = 'irc://github.com' 56 | result = this.shortUrlFilter(input) 57 | 58 | expect(result).toBe(expected) 59 | 60 | input = expected = 'tg://github.com' 61 | result = this.shortUrlFilter(input) 62 | 63 | expect(result).toBe(expected) 64 | }) 65 | 66 | it('removes "www." from a Url', function () { 67 | var input = 'www.github.com' 68 | var expected = 'github.com' 69 | var result = this.shortUrlFilter(input) 70 | 71 | expect(result).toBe(expected) 72 | }) 73 | 74 | it('removes "https://" and "www." from a Url', function () { 75 | var input = 'https://www.github.com' 76 | var expected = 'github.com' 77 | var result = this.shortUrlFilter(input) 78 | 79 | expect(result).toBe(expected) 80 | }) 81 | }) 82 | -------------------------------------------------------------------------------- /test/unit/filters/timeFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach, Config */ 3 | 4 | describe('time filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_) { 8 | this.$filter = _$filter_ 9 | })) 10 | 11 | beforeEach(function () { 12 | // https://stackoverflow.com/questions/4676195/why-do-i-need-to-multiply-unix-timestamps-by-1000-in-javascript 13 | this.miliSecondsToSeconds = 1000 14 | this.dateFilter = this.$filter('date') 15 | }) 16 | 17 | describe('on the mobile website', function () { 18 | beforeEach(function () { 19 | Config.Mobile = true 20 | this.timeFilter = this.$filter('time') 21 | }) 22 | 23 | it('can create a short time based on timestamp', function () { 24 | var input = 1222 25 | var expected = this.dateFilter(input * this.miliSecondsToSeconds, 'shortTime') // For CEST: '1:20 AM' 26 | var result = this.timeFilter(input) 27 | 28 | expect(result).toBe(expected) 29 | }) 30 | 31 | it('can recollect a short time based on timestamp', function () { 32 | var input = 121155 33 | var expected = this.dateFilter(input * this.miliSecondsToSeconds, 'shortTime') // For CEST: '10:39 AM' 34 | var result1 = this.timeFilter(input) 35 | 36 | expect(result1).toBe(expected) 37 | 38 | var result2 = this.timeFilter(input) 39 | 40 | expect(result2).toBe(expected) 41 | }) 42 | }) 43 | 44 | describe('on the desktop website', function () { 45 | beforeEach(function () { 46 | Config.Mobile = false 47 | this.timeFilter = this.$filter('time') 48 | }) 49 | 50 | it('can create a medium-size time based on timestamp', function () { 51 | var input = 1222 52 | var expected = this.dateFilter(input * this.miliSecondsToSeconds, 'mediumTime') // For CEST: '1:20:22 AM' 53 | var result = this.timeFilter(input) 54 | 55 | expect(result).toBe(expected) 56 | }) 57 | 58 | it('can recollect a medium-size time on timestamp', function () { 59 | var input = 121155 60 | var expected = this.dateFilter(input * this.miliSecondsToSeconds, 'mediumTime') // For CEST: '10:39:15 AM' 61 | var result1 = this.timeFilter(input) 62 | 63 | expect(result1).toBe(expected) 64 | 65 | var result2 = this.timeFilter(input) 66 | 67 | expect(result2).toBe(expected) 68 | }) 69 | }) 70 | }) 71 | -------------------------------------------------------------------------------- /test/unit/filters/userFirstNameFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('userFirstName filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_, ___) { 8 | this.$filter = _$filter_ 9 | this._ = ___ 10 | })) 11 | 12 | beforeEach(function () { 13 | this.userFirstNameFilter = this.$filter('userFirstName') 14 | }) 15 | 16 | it('displays user first name deleted', function () { 17 | var expected = this._('user_first_name_deleted') 18 | var actual = this.userFirstNameFilter(null) 19 | 20 | expect(actual).toEqual(expected) 21 | }) 22 | 23 | it('displays the first name', function () { 24 | var user = { 25 | first_name: 'John' 26 | } 27 | var expected = user.first_name 28 | var actual = this.userFirstNameFilter(user) 29 | 30 | expect(actual).toEqual(expected) 31 | }) 32 | 33 | it('displays the last name alternatively', function () { 34 | var user = { 35 | last_name: 'Doe' 36 | } 37 | var expected = user.last_name 38 | var actual = this.userFirstNameFilter(user) 39 | 40 | expect(actual).toEqual(expected) 41 | }) 42 | }) 43 | -------------------------------------------------------------------------------- /test/unit/filters/userNameFilterSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach */ 3 | 4 | describe('userName filter', function () { 5 | beforeEach(module('myApp.filters')) 6 | 7 | beforeEach(inject(function (_$filter_, ___) { 8 | this.$filter = _$filter_ 9 | this._ = ___ 10 | })) 11 | 12 | beforeEach(function () { 13 | this.userNameFilter = this.$filter('userName') 14 | }) 15 | 16 | it('displays user name deleted', function () { 17 | var expected = this._('user_name_deleted') 18 | var actual = this.userNameFilter(null) 19 | 20 | expect(actual).toEqual(expected) 21 | }) 22 | 23 | it('displays the first name', function () { 24 | var user = { 25 | first_name: 'John' 26 | } 27 | var expected = user.first_name 28 | var actual = this.userNameFilter(user) 29 | 30 | expect(actual).toEqual(expected) 31 | }) 32 | 33 | it('displays the last name', function () { 34 | var user = { 35 | last_name: 'Doe' 36 | } 37 | var expected = user.last_name 38 | var actual = this.userNameFilter(user) 39 | 40 | expect(actual).toEqual(expected) 41 | }) 42 | 43 | it('displays both, the first and the last name', function () { 44 | var user = { 45 | first_name: 'John', 46 | last_name: 'Doe' 47 | } 48 | var expected = user.first_name + ' ' + user.last_name 49 | var actual = this.userNameFilter(user) 50 | 51 | expect(actual).toEqual(expected) 52 | }) 53 | }) 54 | -------------------------------------------------------------------------------- /test/unit/services/PhonebookContactsServiceSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* global describe, it, inject, expect, beforeEach, jasmine, xit */ 3 | 4 | describe('PhonebookContactsService', function () { 5 | beforeEach(module('ui.bootstrap')) 6 | beforeEach(module('myApp.services')) 7 | 8 | beforeEach(inject(function (_PhonebookContactsService_) { 9 | this.PhonebookContactsService = _PhonebookContactsService_ 10 | })) 11 | 12 | describe('Public API:', function () { 13 | it('checks availability', function () { 14 | expect(this.PhonebookContactsService.isAvailable).toBeDefined() 15 | }) 16 | 17 | it('open the phonebook for import', function () { 18 | expect(this.PhonebookContactsService.openPhonebookImport).toBeDefined() 19 | }) 20 | 21 | it('get phonebook contacts', function () { 22 | expect(this.PhonebookContactsService.getPhonebookContacts).toBeDefined() 23 | }) 24 | 25 | describe('usage', function () { 26 | describe('of isAvailable()', function () { 27 | it('returns false in most cases', function (done) { 28 | expect(this.PhonebookContactsService.isAvailable()).toBe(false) 29 | done() 30 | }) 31 | }) 32 | 33 | describe('of openPhonebookImport()', function () { 34 | beforeEach(function () { 35 | this.$modal = { 36 | open: jasmine.createSpy('open') 37 | } 38 | }) 39 | 40 | xit('opens a modal', function () { 41 | this.PhonebookContactsService.openPhonebookImport() 42 | expect(this.$modal.open).toHaveBeenCalled() 43 | }) 44 | }) 45 | 46 | describe('of getPhonebookContacts()', function () { 47 | xit('will get rejected in most cases', function (done) { 48 | var promise = this.PhonebookContactsService.getPhonebookContacts() 49 | promise.finally(function () { 50 | expect(promise.isFullfilled()).toBe(true) 51 | done() 52 | }) 53 | }) 54 | }) 55 | }) 56 | }) 57 | }) 58 | -------------------------------------------------------------------------------- /update-angular.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | if [ -n "$1" ]; then 3 | mkdir tmp 4 | curl http://code.angularjs.org/$1/angular-$1.zip -L -o tmp/angular.zip 5 | rm -fr app/vendor/angular 6 | unzip tmp/angular.zip -d app/vendor 7 | mv app/vendor/angular-$1 app/vendor/angular 8 | rm -fr app/vendor/angular/docs tmp 9 | else 10 | echo "Usage: update-angular " 11 | fi 12 | -------------------------------------------------------------------------------- /webogram.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "follow_symlinks": true, 6 | "path": ".", 7 | "folder_exclude_patterns": ["*dist*", ".publish", "node_modules", "releases", ".tx", "css"], 8 | "file_exclude_patterns": ["*.zip", "templates.js"] 9 | } 10 | ] 11 | } 12 | --------------------------------------------------------------------------------