System.register(["@angular/core","@angular/material/core","@angular/cdk/coercion","@angular/common","rxjs","rxjs/operators","@angular/common/http","@angular/platform-browser"],(function(t){"use strict";var e,n,o,i,s,r,a,c,l,h,u,g,f,m,d,_,p,v,I,S,C,E,F,w,R;return{setters:[function(t){e=t.SecurityContext,n=t,t.Injectable,o=t.Optional,t.Inject,i=t.SkipSelf,s=t.ErrorHandler,r=t.InjectionToken,a=t.inject,t.Component,t.ViewEncapsulation,t.ChangeDetectionStrategy,t.Attribute,t.Input,t.NgModule},function(t){c=t.mixinColor,l=t.MatCommonModule},function(t){h=t.coerceBooleanProperty},function(t){u=t.DOCUMENT},function(t){g=t.of,f=t.throwError,m=t.forkJoin,d=t.Subscription},function(t){_=t.tap,p=t.map,v=t.catchError,I=t.finalize,S=t.share,C=t.take},function(t){E=t,F=t.HttpClient},function(t){w=t,R=t.DomSanitizer}],execute:function(){t({ICON_REGISTRY_PROVIDER_FACTORY:L,MAT_ICON_LOCATION_FACTORY:D,getMatIconFailedToSanitizeLiteralError:b,getMatIconFailedToSanitizeUrlError:x,getMatIconNameNotFoundError:y,getMatIconNoHttpProviderError:A});const N=["*"];function y(t){return Error(`Unable to find icon with the name "${t}"`)}function A(){return Error("Could not find HttpClient provider for use with Angular Material icons. Please include the HttpClientModule from @angular/common/http in your app imports.")}function x(t){return Error(`The URL provided to MatIconRegistry was not trusted as a resource URL via Angular's DomSanitizer. Attempted URL was "${t}".`)}function b(t){return Error(`The literal provided to MatIconRegistry was not trusted as safe HTML by Angular's DomSanitizer. Attempted literal was "${t}".`)}class T{constructor(t,e,n){this.url=t,this.svgText=e,this.options=n}}class M{constructor(t,e,n,o){this._httpClient=t,this._sanitizer=e,this._errorHandler=o,this._svgIconConfigs=new Map,this._iconSetConfigs=new Map,this._cachedIconsByUrl=new Map,this._inProgressUrlFetches=new Map,this._fontCssClassesByAlias=new Map,this._resolvers=[],this._defaultFontSetClass=["material-icons","mat-ligature-font"],this._document=n}addSvgIcon(t,e,n){return this.addSvgIconInNamespace("",t,e,n)}addSvgIconLiteral(t,e,n){return this.addSvgIconLiteralInNamespace("",t,e,n)}addSvgIconInNamespace(t,e,n,o){return this._addSvgIconConfig(t,e,new T(n,null,o))}addSvgIconResolver(t){return this._resolvers.push(t),this}addSvgIconLiteralInNamespace(t,n,o,i){const s=this._sanitizer.sanitize(e.HTML,o);if(!s)throw b(o);const r=s;return this._addSvgIconConfig(t,n,new T("",r,i))}addSvgIconSet(t,e){return this.addSvgIconSetInNamespace("",t,e)}addSvgIconSetLiteral(t,e){return this.addSvgIconSetLiteralInNamespace("",t,e)}addSvgIconSetInNamespace(t,e,n){return this._addSvgIconSetConfig(t,new T(e,null,n))}addSvgIconSetLiteralInNamespace(t,n,o){const i=this._sanitizer.sanitize(e.HTML,n);if(!i)throw b(n);const s=i;return this._addSvgIconSetConfig(t,new T("",s,o))}registerFontClassAlias(t,e=t){return this._fontCssClassesByAlias.set(t,e),this}classNameForFontAlias(t){return this._fontCssClassesByAlias.get(t)||t}setDefaultFontSetClass(...t){return this._defaultFontSetClass=t,this}getDefaultFontSetClass(){return this._defaultFontSetClass}getSvgIconFromUrl(t){const n=this._sanitizer.sanitize(e.RESOURCE_URL,t);if(!n)throw x(t);const o=this._cachedIconsByUrl.get(n);return o?g(O(o)):this._loadSvgIconFromConfig(new T(t,null)).pipe(_((t=>this._cachedIconsByUrl.set(n,t))),p((t=>O(t))))}getNamedSvgIcon(t,e=""){const n=U(e,t);let o=this._svgIconConfigs.get(n);if(o)return this._getSvgFromConfig(o);if(o=this._getIconConfigFromResolvers(e,t),o)return this._svgIconConfigs.set(n,o),this._getSvgFromConfig(o);const i=this._iconSetConfigs.get(e);return i?this._getSvgFromIconSetConfigs(t,i):f(y(n))}ngOnDestroy(){this._resolvers=[],this._svgIconConfigs.clear(),this._iconSetConfigs.clear(),this._cachedIconsByUrl.clear()}_getSvgFromConfig(t){return t.svgText?g(O(this._svgElementFromConfig(t))):this._loadSvgIconFromConfig(t).pipe(p((t=>O(t))))}_getSvgFromIconSetConfigs(t,n){const o=this._extractIconWithNameFromAnySet(t,n);if(o)return g(o);const i=n.filter((t=>!t.svgText)).map((t=>this._loadSvgIconSetFromConfig(t).pipe(v((n=>{const o=`Loading icon set URL: ${this._sanitizer.sanitize(e.RESOURCE_URL,t.url)} failed: ${n.message}`;return this._errorHandler.handleError(new Error(o)),g(null)})))));return m(i).pipe(p((()=>{const e=this._extractIconWithNameFromAnySet(t,n);if(!e)throw y(t);return e})))}_extractIconWithNameFromAnySet(t,e){for(let n=e.length-1;n>=0;n--){const o=e[n];if(o.svgText&&o.svgText.toString().indexOf(t)>-1){const e=this._svgElementFromConfig(o),n=this._extractSvgIconFromSet(e,t,o.options);if(n)return n}}return null}_loadSvgIconFromConfig(t){return this._fetchIcon(t).pipe(_((e=>t.svgText=e)),p((()=>this._svgElementFromConfig(t))))}_loadSvgIconSetFromConfig(t){return t.svgText?g(null):this._fetchIcon(t).pipe(_((e=>t.svgText=e)))}_extractSvgIconFromSet(t,e,n){const o=t.querySelector(`[id="${e}"]`);if(!o)return null;const i=o.cloneNode(!0);if(i.removeAttribute("id"),"svg"===i.nodeName.toLowerCase())return this._setSvgAttributes(i,n);if("symbol"===i.nodeName.toLowerCase())return this._setSvgAttributes(this._toSvgElement(i),n);const s=this._svgElementFromString("");return s.appendChild(i),this._setSvgAttributes(s,n)}_svgElementFromString(t){const e=this._document.createElement("DIV");e.innerHTML=t;const n=e.querySelector("svg");if(!n)throw Error(" tag not found");return n}_toSvgElement(t){const e=this._svgElementFromString(""),n=t.attributes;for(let t=0;tt)),I((()=>this._inProgressUrlFetches.delete(s))),S());return this._inProgressUrlFetches.set(s,a),a}_addSvgIconConfig(t,e,n){return this._svgIconConfigs.set(U(t,e),n),this}_addSvgIconSetConfig(t,e){const n=this._iconSetConfigs.get(t);return n?n.push(e):this._iconSetConfigs.set(t,[e]),this}_svgElementFromConfig(t){if(!t.svgElement){const e=this._svgElementFromString(t.svgText);this._setSvgAttributes(e,t.options),t.svgElement=e}return t.svgElement}_getIconConfigFromResolvers(t,e){for(let o=0;oe?e.pathname+e.search:""}}const k=["clip-path","color-profile","src","cursor","fill","filter","marker","marker-start","marker-mid","marker-end","mask","stroke"],H=k.map((t=>`[${t}]`)).join(", "),$=/^url\(['"]?#(.*?)['"]?\)$/;class W extends j{get inline(){return this._inline}set inline(t){this._inline=h(t)}get svgIcon(){return this._svgIcon}set svgIcon(t){t!==this._svgIcon&&(t?this._updateSvgIcon(t):this._svgIcon&&this._clearSvgElement(),this._svgIcon=t)}get fontSet(){return this._fontSet}set fontSet(t){const e=this._cleanupFontValue(t);e!==this._fontSet&&(this._fontSet=e,this._updateFontIconClasses())}get fontIcon(){return this._fontIcon}set fontIcon(t){const e=this._cleanupFontValue(t);e!==this._fontIcon&&(this._fontIcon=e,this._updateFontIconClasses())}constructor(t,e,n,o,i,s){super(t),this._iconRegistry=e,this._location=o,this._errorHandler=i,this._inline=!1,this._previousFontSetClass=[],this._currentIconFetch=d.EMPTY,s&&(s.color&&(this.color=this.defaultColor=s.color),s.fontSet&&(this.fontSet=s.fontSet)),n||t.nativeElement.setAttribute("aria-hidden","true")}_splitIconName(t){if(!t)return["",""];const e=t.split(":");switch(e.length){case 1:return["",e[0]];case 2:return e;default:throw Error(`Invalid icon name: "${t}"`)}}ngOnInit(){this._updateFontIconClasses()}ngAfterViewChecked(){const t=this._elementsWithExternalReferences;if(t&&t.size){const t=this._location.getPathname();t!==this._previousPath&&(this._previousPath=t,this._prependPathToReferences(t))}}ngOnDestroy(){this._currentIconFetch.unsubscribe(),this._elementsWithExternalReferences&&this._elementsWithExternalReferences.clear()}_usingFontIcon(){return!this.svgIcon}_setSvgElement(t){this._clearSvgElement();const e=this._location.getPathname();this._previousPath=e,this._cacheChildrenWithExternalReferences(t),this._prependPathToReferences(e),this._elementRef.nativeElement.appendChild(t)}_clearSvgElement(){const t=this._elementRef.nativeElement;let e=t.childNodes.length;for(this._elementsWithExternalReferences&&this._elementsWithExternalReferences.clear();e--;){const n=t.childNodes[e];1===n.nodeType&&"svg"!==n.nodeName.toLowerCase()||n.remove()}}_updateFontIconClasses(){if(!this._usingFontIcon())return;const t=this._elementRef.nativeElement,e=(this.fontSet?this._iconRegistry.classNameForFontAlias(this.fontSet).split(/ +/):this._iconRegistry.getDefaultFontSetClass()).filter((t=>t.length>0));this._previousFontSetClass.forEach((e=>t.classList.remove(e))),e.forEach((e=>t.classList.add(e))),this._previousFontSetClass=e,this.fontIcon===this._previousFontIconClass||e.includes("mat-ligature-font")||(this._previousFontIconClass&&t.classList.remove(this._previousFontIconClass),this.fontIcon&&t.classList.add(this.fontIcon),this._previousFontIconClass=this.fontIcon)}_cleanupFontValue(t){return"string"==typeof t?t.trim().split(" ")[0]:t}_prependPathToReferences(t){const e=this._elementsWithExternalReferences;e&&e.forEach(((e,n)=>{e.forEach((e=>{n.setAttribute(e.name,`url('${t}#${e.value}')`)}))}))}_cacheChildrenWithExternalReferences(t){const e=t.querySelectorAll(H),n=this._elementsWithExternalReferences=this._elementsWithExternalReferences||new Map;for(let t=0;t{const i=e[t],s=i.getAttribute(o),r=s?s.match($):null;if(r){let t=n.get(i);t||(t=[],n.set(i,t)),t.push({name:o,value:r[1]})}}))}_updateSvgIcon(t){if(this._svgNamespace=null,this._svgName=null,this._currentIconFetch.unsubscribe(),t){const[e,n]=this._splitIconName(t);e&&(this._svgNamespace=e),n&&(this._svgName=n),this._currentIconFetch=this._iconRegistry.getNamedSvgIcon(n,e).pipe(C(1)).subscribe((t=>this._setSvgElement(t)),(t=>{const o=`Error retrieving icon ${e}:${n}! ${t.message}`;this._errorHandler.handleError(new Error(o))}))}}static{this.\u0275fac=function(t){return new(t||W)(n.\u0275\u0275directiveInject(n.ElementRef),n.\u0275\u0275directiveInject(M),n.\u0275\u0275injectAttribute("aria-hidden"),n.\u0275\u0275directiveInject(z),n.\u0275\u0275directiveInject(n.ErrorHandler),n.\u0275\u0275directiveInject(P,8))}}static{this.\u0275cmp=n.\u0275\u0275defineComponent({type:W,selectors:[["mat-icon"]],hostAttrs:["role","img",1,"mat-icon","notranslate"],hostVars:8,hostBindings:function(t,e){2&t&&(n.\u0275\u0275attribute("data-mat-icon-type",e._usingFontIcon()?"font":"svg")("data-mat-icon-name",e._svgName||e.fontIcon)("data-mat-icon-namespace",e._svgNamespace||e.fontSet)("fontIcon",e._usingFontIcon()?e.fontIcon:null),n.\u0275\u0275classProp("mat-icon-inline",e.inline)("mat-icon-no-color","primary"!==e.color&&"accent"!==e.color&&"warn"!==e.color))},inputs:{color:"color",inline:"inline",svgIcon:"svgIcon",fontSet:"fontSet",fontIcon:"fontIcon"},exportAs:["matIcon"],features:[n.\u0275\u0275InheritDefinitionFeature],ngContentSelectors:N,decls:1,vars:0,template:function(t,e){1&t&&(n.\u0275\u0275projectionDef(),n.\u0275\u0275projection(0))},styles:["mat-icon,mat-icon.mat-primary,mat-icon.mat-accent,mat-icon.mat-warn{color:var(--mat-icon-color)}.mat-icon{-webkit-user-select:none;user-select:none;background-repeat:no-repeat;display:inline-block;fill:currentColor;height:24px;width:24px;overflow:hidden}.mat-icon.mat-icon-inline{font-size:inherit;height:inherit;line-height:inherit;width:inherit}.mat-icon.mat-ligature-font[fontIcon]::before{content:attr(fontIcon)}[dir=rtl] .mat-icon-rtl-mirror{transform:scale(-1, 1)}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon{display:block}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button .mat-icon{margin:auto}"],encapsulation:2,changeDetection:0})}}t("MatIcon",W);class B{static{this.\u0275fac=function(t){return new(t||B)}}static{this.\u0275mod=n.\u0275\u0275defineNgModule({type:B})}static{this.\u0275inj=n.\u0275\u0275defineInjector({imports:[l,l]})}}t("MatIconModule",B)}}})); Актуальное зеркало Riobet — сайт и вход через зеркало – Gavin Mostert Attorneys

Актуальное зеркало Riobet — сайт и вход через зеркало

Актуальное зеркало Riobet — сайт и вход через зеркало

Нет ни единого отличия и разницы между бонусными предложениями оператора. Клиенты казино Риобет вполне логично задаются вопросом о лимитах при пополнении и снятии средств на зеркальных сайтах. Также интересует вопрос о надежности транзакций и их сроках. Сразу скажем, что нет никакой разницы, где создавать заявки – на официальном сайте или на его копии. Если это настоящее Riobet зеркало 2026 , взятое из одного из четырех указанных источников, то проблем не будет. В некоторых случаях эффективно использовать поисковики, форумы и специализированные сайты букмекерской тематики, чтобы найти Riobet зеркало на сегодня.

  • В случае удачной проверки вы получите уведомление в личный кабинет.
  • Коэффициенты также зависят от вида ставки, популярности матча, чемпионата, лиги.
  • Чтобы оценить привлекательность программ лояльности в покере, выберите покер-рум из списка GipsyTeam и следуйте инструкции.
  • Все зарегистрированные игроки могут получить бонусы Риобет сразу после создания аккаунта.
  • Доступ к этим бонусам через работающее зеркало делает процесс еще более удобным и быстрым, позволяя новым игрокам сразу же погрузиться в игру.
  • Для этого достаточно вернуться на стартовую страницу и выбрать соответствующую вкладку меню.
  • Не забываем о турнирах и розыгрышах, которые часто проводятся для игроков запасного сайта.
  • Играть на зеркале Риобет безопасно, при условии, что вы используете официальные зеркала, предоставленные самим казино или его поддержкой.
  • Букмекерская контора Рио Бет – это относительно новый раздел на сайте.

Конкретный список разработчиков и доступность отдельных игр зависят от региона. Просьбы «подтвердить аккаунт» через сторонний мессенджер к казино отношения не имеют. Участники с VIP-статусом получат доступ к персонализированным условиям, а именно повышенному кэшбэку, индивидуальным лимитам, бонусам без отыгрыша и закрытым акциям. Также реализована синхронизация игры, когда запустив слот на смартфоне, можно продолжить на ноутбуке с того же спина.

Большая часть из них, а именно 12 тысяч – это слоты, также игрокам доступны порядка 300 Live-игр, еще порядка 700 – это быстрые и краш игры. В футере официального сайта Риобет расположены кнопки для перехода в соцсети. Подпишитесь на них, чтобы регулярно получать свежие промокоды на депозитные акции и бездепы. Активируйте их на станице Мои бонусы и пополните баланс при необходимости. Средства поступят на бонусный счет и будут доступны после отыгрыша. Также мы рекомендуем заполнить профиль и пройти верификации.

Вероятно, проблема будет быстро устранена, обеспечивая бесперебойную игру. Данное поощрение начисляется автоматически, однако у именинника должен быть верифицированный профиль. Для вывода бонусных средств нельзя иметь другие активные бонусы. Чтобы активировать и вывести в Риобет бонус в виде реальных денег, пользователям необходимо отыграть его с заявленным коэффициентом. Для выигрышей https://t.me/riobet_zerkalo_na_segodnya с фриспинов и бонусных денег предусмотрен вейджер х35.

В России запрещены все без исключения игровые заведения. Поэтому доступ к мобильной и компьютерной версии оф сайта Rio Bet может быть заблокирован. Для обхода блокировки и входа в систему используйте рабочее зеркало. Ссылку на доступное зеркало вы найдете на этой странице.

Букмекерская контора Riobet с офшорной лицензией Кюрасао не имеет лицензий других стран, включая Россию. Мобильная версия Riobet Casino адаптируется под размер экрана и сохраняет удобство навигации. Благодаря технологии PWA платформа загружается быстро даже при медленном интернете.

  • Любой пользователь, создавая аккаунт на Риобет, автоматически принимает публичную оферту, изложенную в документе «Terms & Conditions».
  • Один из них — Blazing Coins 40, разработанных Amatic Industries.
  • Кроме традиционных ставок, букмекер предлагает специальные рынки, например гандикапы, тоталы, точный счет, а также комбинированные ставки.
  • Официальный сайт казино не прекращал работу на территории РФ.
  • Нужно взять документы (паспорт), открыть первую страницу и сделать фото, где будет видно лицо игрока и данные на паспорте.
  • Чтобы сменить свой IP-адрес, пользователь может использовать браузеры, встроенно поддерживающие VPN, такие как TOR, Opera Turbo или Yandex.
  • Казино рассылает промокоды по почте, поэтому сразу после регистрации подтвердите контактные данные и согласитесь на рассылку.
  • Она дает игрокам те же функции, что и приложение, но при этом значительно более универсальна.
  • Зеркало копирует функциональность официального сайта, обеспечивая непрерывный доступ к играм, акциям и личному кабинету.
  • Заведение регулярно публикует промокоды, активирующие спины бесплатно на слотах.

зеркало Риобет на сегодня

  • Зеркало онлайн казино  повторяет оригинальный сайт казино, обеспечивающий доступ к играм и услугам при блокировке основного домена.
  • В разделе можно играть в слоты до их официального мирового релиза.
  • Новичкам, активным участникам и лояльным пользователям предлагаются разные уровни вознаграждений.
  • Есть также альтернативный способ играть на сайте Риобет, если он заблокирован – включить ВПН сервис на своем телефоне или ПК устройстве.
  • На создание аккаунта у Riobet можно претендовать из 120+ стран.
  • На нем установлено то же самое лицензионное программное обеспечение, что и на основной платформе.
  • Чтобы начать играть в лайв игры казино Риобет, нужно быть обязательно зарегистрированным пользователем.
  • Такой подход отмечается сотнями пользователей в интернете, которые регулярно положительно отзываются о казино Riobet.
  • Если на руках два зеркала и они оба рабочие, использовать можно то, которое нравится.
  • Проверка занимает от 24 до 48 часов, после чего вывод средств становится доступным.
  • Если средства не пришли вовремя, нужно обратиться в службу помощи.
  • Да, зеркала также могут подвергаться блокировкам со стороны регулирующих органов или интернет-провайдеров.
  • Однако кроме них можно встретить и такие более редкие игры, как Sic Bo, Keno, разновидность покера — Red Dog.

Альтернативный сайт платформы не просто дублирует основной сайт, а предлагает игрокам дополнительные привилегии. Сейчас мы подробно расскажем о лучших бонусах, доступных через резервный ресурс, а также объясним, почему игнорировать их будет ошибкой. Запасной сайт казино позволяет без преград и ограничений получить доступ к своей любимой платформе.

В обычных случаях на зеркалах появляется уведомление о проведении технических работ. Мы стремимся к оперативному восстановлению доступа для всех игроков. Следите за нашими обновлениями для получения информации о восстановлении работы казино. Наши зеркала обеспечивают стабильную работу и редко выходят из строя. В случае проблемы с доступом через зеркало, рекомендуем попробовать альтернативные варианты.

зеркало Риобет на сегодня

Чтобы обойти блокировку, клиенты используют для сайта Riobet зеркало (альтернативный ресурс). Кроме этого игроки могут брать участие в разных соревнованиях и турнирах, которые организовывают провайдеры либо же само казино Риобет. Онлайн казино Риобет работает с 2016 года и имеет много положительных отзывов от игроков. Клуб известный своей щедрой бонусной программой, лицензионными играми на деньги, быстрым выводом средств и профессиональной поддержкой. Riobet сотрудничает с лицензированными провайдерами, которые обеспечивают надежный софт. Азартные игры связаны с риском потери средств и не являются способом заработка.

зеркало Риобет на сегодня

Не работает оф сайт Riobet casino, появляется сообщение о блокировке или просто длится загрузка? Тогда используйте рабочее на сегодня зеркало для входа в Рио Бет. Актуальный адрес доступного сайта опубликован в этом обзоре. С его помощью вы сможете пройти регистрацию или войти в существующий аккаунт Rio Bet, чтобы продолжить играть на настоящие деньги. Онлайн-казино Riobet — проект российской и международной сферы ставок с 10-летним стажем.

Они создаются с той целью, чтобы у пользователей всегда была возможность авторизоваться и сыграть в любую игру. В нем есть те же разделы, ссылки и даже интерфейс тот же. Единственное отличие зеркала от официального сайта – в названии. Riobet Casino — лицензированная платформа с бонусом +300% до ₽75000 и 150 фриспинами. Риобет Казино работает под надзором регулятора Кюрасао и предлагает 3 500+ слотов от ведущих провайдеров. Аудитор BMM Testlabs подтверждает честность игровых процессов.

В случае его отсутствия, необходимо самостоятельно обратиться с запросом на его получение. Мобильная версия игрового клуба, предназначенная для использования на различных устройствах, включая телефоны и планшеты, была разработана с особым упором на качество. Независимо от размера экрана, страница автоматически адаптируется, а все иконки и элементы интерфейса гармонично располагаются на любом дисплее. Российские игроки могут войти в Riobet Casino с помощью любой операционной системы и модели телефона. На веб-сайте Риобет насчитывается целых 30 разновидностей игровых автоматов, которые распределены в соответствии с их визуальным оформлением.

Начав свою работу в 2014 году, сегодня оно уже успело обрести сотни тысяч фанатов в десятках стран мира. Россия среди них занимает одну из ведущих позиций по числу игроков. Популярность проект получил среди любителей просто делать ставки на рубли или выгодно использовать криптовалюту. Для всех них проект предлагает максимум удобств пополнения и минимальные комиссии. Эта наша статья будет посвящена официальному зеркалу проекта — Riobet 220. Этот сайт — это тот же официальный сайт Риобет, просто на другом адресе в интернете.

Несмотря на это, в играх с живыми дилерами есть много преимуществ. Например, общение с другими игроками и впечатление, что играем в реальном казино. Поддержка Riobet Casino доступна через email () и онлайн-чат. Наиболее оперативно решаются вопросы по выводам и бонусам.

Leave a Comment

Your email address will not be published. Required fields are marked *

Message Us on WhatsApp