1app.overlapIndicatorComponent={props:['value'],data(){this.observer=null;return{}},mounted(){this.observer=new IntersectionObserver(([e])=>{this.$emit('input',e.intersectionRatio<1)},{threshold:1});this.observer.observe(this.$refs.indicator)},beforeDestroy(){this.observer.unobserve(this.$refs.indicator)},template:` 2 <div ref="indicator"></div> 3 `};app.tpNutrientsComponent={props:['isApp','nutrients','sizes','loc'],data:function(){return{popupVisible:!1}},computed:{title:function(){return this.loc['topping/nutrients/title']},visible(){if(this.isApp){return this.nutrients&&this.nutrients.default} 4return this.nutrients&&this.nutrients.default&&this.nutrients.default.length},selectedNutrients(){return app.tpSizesAvailability.bySize(this.nutrients,this.sizes.selected)},processedNutrients(){const groups=[{title:this.title,items:[]}];let shortGroup=null;for(const item of this.selectedNutrients){const value=item.value+(item.unit?' '+item.unit:'');if(value.length>20){groups.push({title:item.name,items:[{value}]});shortGroup=null;continue} 5if(!shortGroup){shortGroup={title:'',items:[]};groups.push(shortGroup)} 6shortGroup.items.push({name:item.name,value})} 7return groups}},methods:{show:function(){if(!this.popupVisible){this.popupVisible=!0}}},directives:{close:{bind:function(el,binding,vnode){el.clickOutsideFn=function(){vnode.context.popupVisible=!1} 8setTimeout(function(){document.body.addEventListener('click',el.clickOutsideFn)},30)},unbind:function(el){document.body.removeEventListener('click',el.clickOutsideFn)}}},template:` 9 <div v-if="visible" 10 class="nutr"> 11 12 <div v-if="popupVisible" 13 class="nutr__popup-wrap" 14 v-close> 15 <div class="nutr__popup"> 16 17 <template v-if="isApp"> 18 <template v-for="group in processedNutrients"> 19 <div v-if="group.title" class="nutr__title">{{group.title}}</div> 20 <div v-for="item in group.items" class="nutr__item"> 21 <div v-if="item.name" class="nutr__name">{{item.name}}</div> 22 <div class="nutr__value">{{item.value}}</div> 23 </div> 24 </template> 25 </template> 26 27 <template v-else> 28 <div class="nutr__title">{{title}}</div> 29 30 <div v-for="item in selectedNutrients" 31 class="nutr__item"> 32 <div class="nutr__name">{{item.name}}</div> 33 <div class="nutr__value">{{item.value}}{{item.unit ? ' ' + item.unit : ''}}</div> 34 </div> 35 </template> 36 37 </div> 38 </div> 39 40 <i @click="show()" 41 class="nutr__ico">
42 <svg class="nutr__svg" width="3" height="11" viewBox="0 0 3 11"> 43 <path fill-rule="evenodd" clip-rule="evenodd" d="M1.44001 2.744C2.12042 2.744 2.67201 2.19241 2.67201 1.512C2.67201 0.831584 2.12042 0.279999 1.44001 0.279999C0.759593 0.279999 0.208008 0.831584 0.208008 1.512C0.208008 2.19241 0.759593 2.744 1.44001 2.744ZM2.34001 10.84V4.68H0.540008V10.84H2.34001Z" fill="#3D3D3D"/> 44 </svg> 45 <svg v-if="!isApp" class="nutr__svgDesktop" xmlns="http://www.w3.org/2000/svg" width="2" height="10" viewBox="0 0 2 10" fill="none"> 46 <rect y="4" width="2" height="6" rx="1" fill="#555454"/> 47 <rect width="2" height="2" rx="1" fill="#555454"/> 48 </svg> 49 </i> 50 51 </div> 52 `};app.tpParamsComponent={props:['isApp','dish','sizes'],computed:{params:function(){return app.tpSizesAvailability.visibleParams(this.dish,this.sizes.selected)}},template:` 53 <div v-if="params.length" class="tpar"> 54 55 <div v-for="param in params" 56 class="tpar__item"> 57 <template v-if="isApp"> 58 <span class="tpar__name">{{param.name}}</span> 59 <span class="tpar__dots"></span> 60 <span class="tpar__value">{{param.value}}</span> 61 </template> 62 <template v-else> 63 <b>{{param.name}}:</b> {{param.value}} 64 </template> 65 </div> 66 67 </div> 68 `};app.tpIngredientsComponent={components:{'tp-nutrients':app.tpNutrientsComponent,'tp-params':app.tpParamsComponent},props:['isApp','isDesktopVersion','dish','sizes','modifiers','loc','company',],data(){let collapsed=!1;if(this.isApp){const hasText=!!this.dish.ingredients;const isTextLong=hasText&&this.dish.ingredients.length>=200;const hasParams=hasText&&app.tpSizesAvailability.visibleParams(this.dish,this.sizes.selected).length>0;collapsed=isTextLong||hasParams;if(!this.sizes.options.length&&!this.modifiers.length){collapsed=!1}} 69return{isCollapsible:collapsed,collapsed:collapsed}},computed:{allergensLink(){return this.company&&this.company.allergensLink},locAllergensLink(){return this.loc['ingredients/allergens']},dishName(){if(!app.tpSizesAvailability.hasSwitcher(this.sizes.options)){return null} 70return this.dish.name},pricePerUnit(){const size=this.sizes.selected;const partial=this.dish.prices&&this.dish.prices[size]&&this.dish.prices[size].partialConfig;if(!partial||!partial.displayPerUnit||!partial.priceOneUnit||!partial.sizeTypeFormatted){return null} 71return{price:partial.priceOneUnitFormatted,size:'1 '+partial.sizeTypeFormatted}},ingredients(){if(!this.dish.ingredients){return null} 72const text=this.dish.ingredients;if(!this.isApp){return text.replace(/\n/g,'<br>')} 73return this.collapsed?text:text.replace(/\n/g,'<br> ')},composition(){const composition=this.dish.ingredients2;if(typeof composition==='string'){return composition} 74return app.tpSizesAvailability.bySize(composition,this.sizes.selected)||''},locComposition(){return this.loc['dish/param/ingredients']}},methods:{toggleCollapsed(){if(this.isCollapsible){this.collapsed=!this.collapsed}},navigateAllergens(){this.$emit('openLink',this.allergensLink)}},template:` 75 <div class="ingr__wrap"> 76 77 <tp-nutrients v-if="!isDesktopVersion" 78 :isApp="isApp" 79 :nutrients="dish.nutrients" 80 :sizes="sizes" 81 :loc="loc"/> 82 83 <div v-if="dishName" class="ingr__dish"> 84 {{dishName}} 85 <tp-nutrients v-if="isDesktopVersion" 86 :isApp="isApp" 87 :nutrients="dish.nutrients" 88 :sizes="sizes" 89 :loc="loc"/> 90 </div> 91 92 <div v-if="pricePerUnit" class="ingr__pricePerUnit"> 93 {{pricePerUnit.price}}<span class="ingr__pricePerUnit-size">{{pricePerUnit.size}}</span> 94 </div> 95 96 <div v-if="ingredients && isApp" class="ingr"> 97 98 <div class="ingr__text" 99 v-html="ingredients" 100 @click="toggleCollapsed" 101 :class="{'ingr__text--collapsed': collapsed}"></div> 102 103 </div> 104 105 <div v-if="ingredients && !isApp" class="ingr" v-html="ingredients"></div> 106 107 <tp-params v-if="isApp && !collapsed" 108 :isApp="isApp" 109 :dish="dish" 110 :sizes="sizes"/> 111 112 <div v-if="composition && isApp" class="ingr__composition"> 113 <b>{{locComposition}}:</b> {{composition}} 114 </div> 115 116 <div v-if="composition && !isApp" class="ingr2"> 117 {{composition}} 118 </div> 119 120 <div v-if="allergensLink && isApp" class="ingr__allergensLink" @click="navigateAllergens()"> 121 {{ locAllergensLink }} 122 </div> 123 124 <a v-if="allergensLink && !isApp" class="ingr__allergensLink" :href="allergensLink" target="_blank"> 125 {{ locAllergensLink }} 126 </a> 127 </div> 128 `};app.tpSizesAvailability={isAvailable(option){return!!option&&option.price!=='-'},visibleOptions(options){return(options||[]).filter(option=>this.isAvailable(option))},selectPos(options,selected){const visible=this.visibleOptions(options).filter(option=>typeof option.pos==='number');if(visible.some(option=>option.pos===selected)){return selected} 129return visible.length?visible[0].pos:0},pointerIndex(options,selected){const index=this.visibleOptions(options).findIndex(option=>option.pos===selected);return index===-1?0:index},hasSwitcher(options){return this.visibleOptions(options).length>1}
129,bySize(map,pos){return map?(map[pos]||map.default):undefined},visibleParams(dish,pos){const grouped=[];const indexByName=Object.create(null);(this.bySize(dish.params,pos)||[]).forEach(param=>{const name=param.name!=null?String(param.name):'';const value=param.value!=null?String(param.value).trim():'';if(!value){return} 130if(indexByName[name]===undefined){indexByName[name]=grouped.length;grouped.push(Object.assign({},param,{value}));return} 131grouped[indexByName[name]].value+=', '+value});return grouped},sizePack(sizes,pos){const option=sizes&&sizes.options&&sizes.options[pos];return(option&&option.modifiers)||null},pack(dishModifiers,pos){const modifiers=(this.sizePack(dishModifiers[0],pos)||dishModifiers.slice(1)).slice();modifiers.sort((a,b)=>{const aPos=a.required?-1:a.pos;const bPos=b.required?-1:b.pos;if(aPos===bPos){return 0} 132return aPos<bPos?-1:1});return modifiers},selectedPack(dishModifiers){const sizes=dishModifiers[0];return this.pack(dishModifiers,this.selectPos(sizes&&sizes.options,sizes&&sizes.selected))},isWithPoints(isApp,dish,pos){if(isApp){return dish.restrictions&&dish.restrictions.dishesWithPoints} 133return dish.prices&&dish.prices[pos]&&dish.prices[pos].isWithPoints},hasPointsMinSum(isApp,dish){if(isApp){return!!(dish.restrictions&&dish.restrictions.dishesWithPointsMinSum)} 134return Object.keys(dish.prices||{}).some(pos=>!!(this.isWithPoints(!1,dish,pos)&&dish.prices[pos].pointDishMinSum))},};app.tpSizesComponent={components:{'tp-ingredients':app.tpIngredientsComponent,'tp-nutrients':app.tpNutrientsComponent,pointIcon:app.pointIconComponent,},props:['isApp','isDesktopVersion','dish','sizes','modifiers','loc','company','hidePrice',],created(){const pos=app.tpSizesAvailability.selectPos(this.sizes.options,this.sizes.selected);if(this.sizes.selected!==pos){this.$set(this.sizes,'selected',pos)}},computed:{visibleSizeOptions(){return app.tpSizesAvailability.visibleOptions(this.sizes.options)},rowLimit(){return this.isApp?3:5},isMany(){return this.isApp&&this.visibleSizeOptions.length>=4},isLargeItems(){return!this.isApp&&this.visibleSizeOptions.length>=5},isGrid(){return this.isLargeItems&&this.isDesktopVersion},pointerStyle(){if(this.isGrid){return} 135const x=app.tpSizesAvailability.pointerIndex(this.sizes.options,this.sizes.selected)*100;return{"-webkit-transform":"translateX("+x+"%)",transform:this.isApp?"translate3d("+x+"%, 0, 0)":"translateX("+x+"%)"}},bgStyle(){if(this.isGrid){return} 136const len=this.visibleSizeOptions.length;return{width:len<=this.rowLimit?'100%':'calc(30% * '+len+')'}},optionStyle(){const len=this.visibleSizeOptions.length;return{width:len<=this.rowLimit?'calc(100% / '+len+')':'30%'}},info(){if(this.optionsVisible){return null} 137if(this.isApp){return{name:this.dish.name,price:this.dish.price,priceFrom:this.dish.priceFrom||'',size:this.dish.size}} 138const size=this.dish.size||'';const weight=size.split('|')[0].trim();const name=String(this.dish.name);const cutName=weight&&name.endsWith(weight)&&name.slice(0,-weight.length).trim();return{name:cutName||this.dish.name,price:this.dish.price,size:size}},optionsVisible(){return app.tpSizesAvailability.hasSwitcher(this.sizes.options)},options(){const options=[];this.sizes.options.forEach((option,i)=>{if(!app.tpSizesAvailability.isAvailable(option)){return} 139let price=app.tpSizesAvailability.isWithPoints(this.isApp,this.dish,i)?this.priceFormat(option.price):option.priceFormatted;if(!this.isApp&&this.visibleSizeOptions.length===4){price=price.replace('ÑÑб.','Ñ.')} 140options.push({pos:option.pos,price:price,size:option.size,balance:this.balanceFormat(option.balance),active:option.pos===this.sizes.selected,withPointer:options.length===0})});return options},isWithPoints(){return app.tpSizesAvailability.isWithPoints(this.isApp,this.dish,this.sizes.selected)},},methods:{select(option){if(this.sizes.selected!==option.pos){this.$emit('haptics')} 141this.sizes.selected=option.pos},priceFormat(value){return app.price.format(value,'',this.company.priceSeparator)},balanceFormat(balance){if(!balance){return''} 142const unit=(this.loc&&this.loc['unit/count'])||'';return(balance+' '+unit).trim()},},template:` 143 <div class="tsizes"> 144 145 <div v-if="info && isApp" class="tsizes__infoWrap"> 146 147 <div class="tsizes__info"> 148 149 <div class="tsizes__info-name"> 150 {{info.name}} <span v-if="info.size" class="tsizes__info-size">{{info.size}}</span> 151 </div> 152 <div v-if="!hidePrice" class="tsizes__info-price"> 153 {{info.priceFrom ? info.priceFrom : info.price}} 154 <point-icon v-if="isWithPoints" class="hIcon__point" variant="cart"></point-icon> 155 </div> 156 157 </div> 158 159 <tp-ingredients :isApp="isApp" 160 :dish="dish" 161 :sizes="sizes" 162 :modifiers="modifiers" 163 :loc="loc" 164 :company="company" 165 @openLink="$emit('openLink', $event)"/> 166 167 </div> 168 169 <template v-if="info && !isApp"> 170 171 <div class="tsizes__info"> 172 173 <div class="tsizes__info-name"> 174 {{info.name}} 175 <tp-nutrients v-if="isDesktopVersion" 176 :isApp="isApp" 177 :nutrients="dish.nutrients" 178 :sizes="sizes" 179 :loc="loc"/> 180 </div> 181 <div class="tsizes__info-price"> 182 {{info.price}} 183 <svg v-if="isWithPoints" class="tp__pointIcon"> 184 <use xlink:href="#tp__pointIcon"></use> 185 </svg> 186
187 <span v-if="info.size" class="tsizes__info-size">{{info.size}}</span> 188 </div> 189 190 </div> 191 192 <tp-ingredients :isApp="isApp" 193 :isDesktopVersion="isDesktopVersion" 194 :dish="dish" 195 :sizes="sizes" 196 :modifiers="modifiers" 197 :loc="loc" 198 :company="company"/> 199 200 </template> 201 202 <div v-if="optionsVisible" class="tsizes__scrollable" :class="{'tsizes__scrollable--many': isMany}"> 203 204 <div class="tsizes__options" :class="{'tsizes__options--large': isLargeItems}"> 205 206 <div class="tsizes__bg" :style="bgStyle"></div> 207 208 <div v-for="option in options" 209 :key="option.pos" 210 class="tsizes__option" 211 :style="optionStyle" 212 @click="select(option)" 213 :class="{'tsizes__option--active': option.active}"> 214 215 <div class="tsizes__content"> 216 <div class="tsizes__price"> 217 {{option.price}} 218 <point-icon v-if="isApp && isWithPoints" class="hIcon__point" variant="cart"></point-icon> 219 <svg v-if="!isApp && isWithPoints" class="tp__pointIcon"> 220 <use xlink:href="#tp__pointIcon"></use> 221 </svg> 222 </div> 223 <div v-if="option.size" class="tsizes__size" v-html="option.size"></div> 224 <div v-if="option.balance" class="tsizes__balance">{{option.balance}}</div> 225 </div> 226 227 <div v-if="option.withPointer" 228 class="tsizes__pointer" 229 :style="pointerStyle"></div> 230 231 </div> 232 233 </div> 234 235 </div> 236 237 </div> 238 `};app.tpOptionManyboxComponent={props:['count','price','isAppearanceTiles'],computed:{value(){return this.count||this.price},isEmpty(){return!this.count}},methods:{onMinus:function(){this.$emit('minus')}},template:` 239 <div class="tpmanybox" :class="{'tpmanybox--tiles': isAppearanceTiles, 'tpmanybox--empty': isEmpty}"> 240 <div class="tpmanybox__minus" @click.stop="onMinus()"></div> 241 <div class="tpmanybox__count">{{value}}</div> 242 <div class="tpmanybox__plus"></div> 243 </div> 244 `};app.tpOptionComponent={props:['isApp','option','modifier','sizes','isAppearanceTiles','isAddressOk'],components:{Manybox:app.tpOptionManyboxComponent},created(){if(!this.option.count){this.$set(this.option,'count',parseInt(this.option.defaultAmount)||0)} 245if(this.isCustom){this.$watch('sizes.selected',function(pos,prevPos){pos=this.resolvePricePos(pos);if(this.isNoPriceAt(pos)){this.$set(this.option,'count',0)}else if(prevPos!==undefined&&this.isNoPriceAt(this.resolvePricePos(prevPos))){this.applyDefaultAmount()} 246this.$set(this.option,'pos',pos)},{immediate:!0})} 247if(this.isRequired&&this.option.id===this.modifier.options[0].id){this.$watch('modifier.options',function(options){if(!this.countInModifier&&!this.countDefaultInModifier){options[0].count=1}},{immediate:!0,deep:!0})}},computed:{photo(){return this.option.photo},isPhotoSlot(){if(this.isApp){return!!this.photo} 248return!!this.modifier.options.find(option=>!!option.photo)},isRequired:function(){return this.modifier.required},isManyMany:function(){return this.modifier.type==='many_many'},isOneOne:function(){if(this.modifier.max&&this.modifier.max===1){return!0} 249return this.modifier.type==='one_one'},isCustom:function(){return this.modifier.custom},isVisible(){const isNoPrice=this.isCustom&&this.option.prices[this.option.pos].price==='-';const isHidden=isNoPrice||this.option.isService;this.option.isHidden=isHidden;return!isHidden},isManybox:function(){return this.isAppearanceTiles||(this.isManyMany&&this.count>0&&this.limitCount>1)},limitCount:function(){if(this.isOneOne){return 1} 250if(this.option.max){return this.option.max} 251if(this.modifier.max){return this.modifier.max}
252if(this.isCustom){return 1} 253if(!this.option.price){return 1} 254return this.option.prices.length>1?this.option.prices.length:99},isSelected:function(){return this.option.count>0},size:function(){return this.isCustom?this.option.prices[this.option.pos].sizeFormatted:this.option.sizeFormatted},name:function(){return this.option.name+(this.size?', '+this.size:'')},isPriceVisible(){return!this.isAppearanceTiles},price(){var p=this.isCustom?this.option.prices[this.option.pos]:this.option;if(!this.isApp&&!Object.keys(p).find(function(k){return k==='priceFormatted'})){p.priceFormatted=p.price_formatted} 255return p.price?'+'+p.priceFormatted:p.priceFormatted},count(){return this.option.count},countInModifier(){var count=0;for(var i=0;i<this.modifier.options.length;i++){var modifier=this.modifier.options[i];if(modifier.count){count+=modifier.count}} 256return count},countDefaultInModifier(){var count=0;for(var i=0;i<this.modifier.options.length;i++){var modifier=this.modifier.options[i];if(modifier.defaultAmount){count+=modifier.defaultAmount}} 257return count},isModifierMaxReached(){if(this.isOneOne){return!1} 258return this.modifier.max&&this.countInModifier>=this.modifier.max},issetEmptyOptions(){return!!this.modifier.options.find(option=>!option.count)},isMinReached(){const min=parseInt(this.option.min||0);if(this.count<=min){return!0} 259if(min===1&&this.isRequired){return!0} 260return!1},},methods:{resolvePricePos(pos){return this.option.prices[pos]?pos:0},isNoPriceAt(pos){return this.option.prices[pos].price==='-'},applyDefaultAmount(){const amount=parseInt(this.option.defaultAmount)||0;if(!amount||this.option.count){return} 261const isGroupFull=this.isOneOne?this.countInModifier>0:this.modifier.max&&this.countInModifier+amount>this.modifier.max;if(!isGroupFull){this.$set(this.option,'count',amount)}},onMinus(){if(this.isApp&&!this.isAddressOk()){return} 262if(this.option.min&&this.count<=this.option.min){return} 263if(this.count){this.option.count--;this.$emit('haptics')}},onPlus(){if(this.isApp&&!this.isAddressOk()){return} 264if(this.isModifierMaxReached){if(this.isManyMany&&this.limitCount===1&&this.isSelected&&this.issetEmptyOptions){this.option.count=0}else if(!this.isMinReached){this.option.count=0} 265return} 266this.$emit('haptics');if(this.isOneOne){if(this.isSelected){if(!this.isRequired&&!this.isAppearanceTiles){this.option.count=0}}else{this.option.count=1;for(var i=0;i<this.modifier.options.length;i++){var modOpt=this.modifier.options[i];if(modOpt.count&&modOpt.id!==this.option.id){modOpt.count=0}}}}else if(this.isManyMany&&this.limitCount>1){if(this.count<this.limitCount){this.option.count++}}else if(this.isManyMany&&this.limitCount===1){if(this.isSelected){if(!this.option.min||this.count>this.option.min){this.option.count=0}}else{this.option.count=1}}}},template:` 267 268 <div v-if="isVisible" 269 class="topt" 270 :class="{'topt--max-reached': isModifierMaxReached, 'topt--selected': count, 'topt--tiles': isAppearanceTiles}" 271 @click="onPlus()"> 272 273 <div v-if="isPhotoSlot" class="topt__photoWrap"> 274 <img v-if="photo" class="topt__photo" alt="" :src="photo"> 275 <svg v-else width="35" height="35" viewBox="0 0 35 35" fill="none"> 276 <rect width="35" height="35" rx="6" fill="black" fill-opacity="0.05"/> 277 <path d="M35 0L31.3238 -1.60692e-07L-8.92369e-07 31.3238L-1.05306e-06 35L3.67621 35L35 3.67622L35 0ZM35 9.17535L9.17535 35L16.524 35L35 16.524L35 9.17535ZM35 22.0231L22.0231 35L29.3755 35L35 29.3755L35 22.0231ZM25.8247 -4.01067e-07L18.476 -7.22286e-07L-3.30775e-07 18.476L-6.51994e-07 25.8247L25.8247 -4.01067e-07ZM12.9769 -9.62661e-07L5.62446 -1.28405e-06L2.30984e-07 5.62446L-9.04006e-08 12.9769L12.9769 -9.62661e-07Z" fill="white"/> 278 </svg> 279 </div> 280 281 282 <div class="topt__name"> 283 <span class="topt__name-wrap">{{name}}</span> 284 <span v-if="isPriceVisible" class="topt__price">{{price}}</span> 285 </div> 286 287 <Manybox v-if="isManybox" 288 :count="count" 289 :price="price" 290 :isAppearanceTiles="isAppearanceTiles" 291 @minus="onMinus()"/> 292 293 <!-- tpcheckbox--isOneOne: ÑÐ°Ð¹Ñ ÑиÑÑÐµÑ one_one кÑÑглÑм (checkbox.css), в пÑиложении пÑавила Ð½ÐµÑ --> 294 <div v-else 295 class="tpcheckbox" 296 :class="{'tpcheckbox--selected': isSelected, 'tpcheckbox--isOneOne': !isApp && isOneOne}"></div> 297 298 299 </div> 300 301 `};app.tpModifierComponent={components:{'tp-option':app.tpOptionComponent},props:['isApp','modifier','sizes','loc','isAppearanceTiles','isAddressOk'],data(){return{isVisible:!0}},mounted(){setTimeout(()=>{let allOptionsSet=!0;for(let i=0;i<this.options.length;i++){const option=this.options[i];
301if(!option.min||!option.max||!option.count||option.min!==option.max||option.min!==option.count){allOptionsSet=!1;break}} 302if(allOptionsSet){this.isVisible=!1}},50)},watch:{'options':{handler(options){this.$nextTick(()=>{let isHidden=!0;options.forEach(option=>{if(!option.isHidden){isHidden=!1}});this.isVisible=!isHidden})},deep:!0}},computed:{title(){return this.modifier.title},subTitle(){if(this.modifier.max){return `${this.loc['topping/max']}: ${this.modifier.max}`} 303return null},options:function(){return this.modifier.options||[]}},template:` 304 <div v-show="isVisible" class="tmod"> 305 306 <div class="tmod__title">{{title}}</div> 307 308 <div v-if="subTitle" class="tmod__subTitle">{{subTitle}}</div> 309 310 <div class="tmod__options" :class="{'tmod__options--tiles': isAppearanceTiles}"> 311 312 <tp-option v-for="(option, i) in options" 313 :key="i" 314 :isApp="isApp" 315 :modifier="modifier" 316 :option="option" 317 :sizes="sizes" 318 :isAppearanceTiles="isAppearanceTiles" 319 :isAddressOk="isAddressOk" 320 @haptics="$emit('haptics')"> 321 </tp-option> 322 323 <div v-if="isAppearanceTiles" class="tmod__dummy"></div> 324 325 </div> 326 327 328 </div> 329 `};app.tpQuarterPartComponent={props:['isApp','part','sizes'],computed:{style:function(){var src=this.isApp?'https://v8.foodpicasso.com/assets/home4/topping4/info/quarter/main/i/bg.png':'/assets/modules/topping/info/quarter/main/i/bg.png';for(var i=0;i<this.part.options.length;i++){var option=this.part.options[i];if(option.count){src=option.photoPart}} 330return{backgroundImage:'url('+src+')'}},type:function(){return this.part.quarterType}},methods:{navigate:function(){this.$emit('open',{part:this.part,pos:this.sizes.selected})}},template:` 331 <div class="tpart" 332 :class="'tpart--'+type" 333 :style="style" @click="navigate()"> 334 </div> 335 `};app.tpQuarterComponent={components:{'quarter-part':app.tpQuarterPartComponent},props:['isApp','modifiers','sizes','company'],computed:{rotateQuarter:function(){return this.isApp&&this.company&&this.company.rotateQuarter},parts:function(){return(this.modifiers||[]).filter(modifier=>modifier.quarterType)}},template:` 336 <div class="tpcn" 337 :class="{'tpcn--rotate': rotateQuarter}"> 338 339 <div class="tpcn__content"> 340 <quarter-part v-for="part in parts" 341 :isApp="isApp" 342 :part="part" 343 :sizes="sizes" 344 @open="$emit('openPart', $event)"/> 345 </div> 346 347 </div> 348 `};app.tpQuarterRule={isActive(modifiers){if(!app.tpQuarterComponent){return!1} 349const types=new Set((modifiers||[]).map(modifier=>modifier.quarterType).filter(Boolean));let quarters=0;let halfs=0;types.forEach(type=>{if(type.includes('quarter')){quarters++}else if(type.includes('half')){halfs++}});return(quarters===4&&halfs===0)||(halfs===2&&quarters===0)}};app.tpInfoComponent={components:{'tp-quarter':app.tpQuarterComponent,'tp-ingredients':app.tpIngredientsComponent,},props:['isApp','isDesktopVersion','dish','sizes','modifiers','isQuarterActive','loc','company',],data:function(){return{activeImage:0}},computed:{isImageVisible(){return!this.isDesktopVersion},ingredientsVisible:function(){return app.tpSizesAvailability.hasSwitcher(this.sizes.options)},media(){if(this.dish.media&&this.dish.media.length){return this.dish.media} 350if(!this.isApp){return[{high:'/assets/modules/topping/info/main/i/empty.png',low:'',ratio:'60.07',empty:!0}]} 351if(this.dish.photo){return[this.dish.photo,...(this.dish.extraPhotos||[])].map(photo=>({full:photo.full,ratio:photo.ratio||80,low:photo.low||'',}))} 352return[{full:'https://v8.foodpicasso.com/assets/home4/topping4/info/main/i/empty.png',low:'',ratio:'60.07'}]},mediaRatio(){return Math.max(...this.media.map((media)=>media.ratio||80))}},methods:{onScrollImages(){const scrollable=this.$refs.scrollable;this.activeImage=Math.round(scrollable.scrollLeft/scrollable.clientWidth)||0}},template:` 353 <div class="tinf"> 354 355 <template v-if="isImageVisible"> 356 357 <tp-quarter v-if="isQuarterActive" 358 :isApp="isApp" 359 :modifiers="modifiers" 360 :sizes="sizes" 361 :company="company" 362 @openPart="$emit('openPart', $event)"/> 363 364 <div v-else class="tinf__images"> 365 366 <div class="tinf__scrollable" 367 ref="scrollable" 368 @scroll="onScrollImages()"> 369 <div v-for="image of media" 370 class="tinf__image-wrap" 371 :class="{lazyload__wrap: !isApp}" 372 :style="{paddingBottom: mediaRatio + '%'}"> 373 374 <template v-if="image.type === 'video'"> 375 <video class="tinf__image tinf__image--video" 376 :src="image.preview" 377 autoplay muted loop playsinline webkit-playsinline></video> 378 </template> 379 380 <img v-else-if="isApp" 381 :src="image.full" 382 alt="" 383 class="tinf__image"> 384 385 <!-- Ð¡Ð°Ð¹Ñ Ð³ÑÑÐ·Ð¸Ñ ÑоÑо ÑеÑез lazysizes: ÑнаÑала low, поÑом high --> 386 <img v-else 387 :data-src="image.high" 388 :data-lowsrc="image.low" 389 :src="image.empty ? image.high : ''" 390 alt="" 391 class="tinf__image" 392 :class="{'tinf__image--empty': image.empty, lazyload: !image.empty}"> 393 394 </div> 395 396 </div> 397 398 <template v-if="media.length > 1"> 399 <div v-if="!isApp" class="tinf__bulletsShadow"></div> 400 <div class="tinf__bullets"> 401 <i v-for="(image, i) in media" 402 class="tinf__bullet" 403 :class="{'tinf__bullet--active': i === activeImage}"></i> 404 </div> 405 </template> 406 407 </div> 408 409 </template> 410 411 <div v-if="ingredientsVisible" 412 class="tinf__ingredients"> 413 <tp-ingredients :isApp="isApp" 414 :isDesktopVersion="isDesktopVersion" 415 :dish="dish" 416 :sizes="sizes" 417 :modifiers="modifiers" 418 :loc="loc" 419 :company="company" 420 @openLink="$emit('openLink', $event)"/> 421 </div> 422 423 </div> 424 `};app.tpSubmitComponent={components:{partialWeight:app.partialWeightComponent,animatedCount:app.commonAnimatedCountComponent,pointIcon:app.pointIconComponent,}
424,props:['isApp','dish','sizes','modifiers','dishSectionId','loc','company','cart','isAppearanceInput','forceRemoveDish','isAddressOk','hideCount','hidePrice','submitText','combo','issetRestriction','userHasToSubscribe','shadow',],data(){return{partialWeight:null}},watch:{partialWeight(newWeight){if(!this.isPartialWithSizes||!newWeight){return} 425var weights=this.sizeWeights;var options=this.sizes.options;var visible=app.tpSizesAvailability.visibleOptions(options);var bestIndex=visible.length?visible[0].pos:0;for(var i=weights.length-1;i>=0;i--){if(weights[i]>0&&newWeight>=weights[i]&&app.tpSizesAvailability.isAvailable(options[i])){bestIndex=i;break}} 426if(this.sizes.selected!==bestIndex){this._skipSizeWatch=!0;this.sizes.selected=bestIndex}},'sizes.selected':function(newIndex){if(!this.isPartialWithSizes){return} 427if(this._skipSizeWatch){this._skipSizeWatch=!1;return} 428var weight=this.sizeWeights[newIndex];if(weight>0){this.partialWeight=weight}}},created(){if(!this.dish.count){this.$set(this.dish,'count',1)} 429this.partialWeight=this.partial&&this.partial.defaultWeight;this._skipSizeWatch=!1},computed:{buttonState(){if(this.dish.isStop){return'stop'} 430if(this.dish.orderScheduleStop){return'schedule'} 431if(this.pointDishBlocked){return'pointMin'} 432return'add'},isBlocked(){return this.buttonState==='stop'||this.buttonState==='schedule'},isQrReadonly(){return!this.isApp&&this.company&&this.company.isQrReadonly},isCounterVisible(){return!this.hideCount&&!this.isQrReadonly&&(this.buttonState==='add'||this.buttonState==='stop')},orderScheduleText:function(){return this.dish.orderScheduleLabel||''},count(){return this.dish.count},selectedSizeOption(){const sizes=this.sizes||{};const option=(sizes.options||[])[sizes.selected];return(option&&option.dishId)?option:null},dishBalance(){const option=this.selectedSizeOption;return option?option.balance:this.dish.balance},customModifierPos(){return this.selectedSizeOption?0:this.sizes.selected},balance:function(){if(this.isBlocked){return null} 433var balance=this.dishBalance;if(!balance){return null} 434return `${this.loc['topping/remains']} ${balance} ${this.loc['unit/count']}`},minusInactive(){if(this.partial){var minWeight=this.partialMinWeight;return this.partialWeight<=minWeight} 435return this.count<=1},plusInactive(){const balance=this.dishBalance;if(balance&&this.count>=balance){return!0} 436if(this.partial){return this.partialWeight>=9999}},dishPrice(){const size=this.sizes.selected;return(this.dish.prices&&this.dish.prices[size])||{}},partial(){return this.dishPrice.partialConfig},isPartialWithSizes(){return this.partial&&this.sizes.options&&this.sizes.options.length>1},sizeWeights(){if(!this.sizes.options||!this.sizes.options.length){return[]} 437return this.sizes.options.map(function(opt){return parseFloat(opt.size)||0})},partialMinWeight(){if(!this.partial){return 0} 438return this.partial.defaultWeight||(this.isPartialWithSizes&&this.sizeWeights[0])||0},isWithPoints(){return app.tpSizesAvailability.isWithPoints(this.isApp,this.dish,this.sizes.selected)},pointDishMinSum(){if(this.isApp){return(this.dish.restrictions&&this.dish.restrictions.dishesWithPointsMinSum)||0} 439return(this.isWithPoints&&this.dishPrice.pointDishMinSum)||0},pointDishBlocked(){if(!this.pointDishMinSum){return!1} 440const amount=this.cart&&this.cart.amount;return((amount&&amount.pointDishRegularSum)||0)<this.pointDishMinSum},pointDishMinSumText(){if(this.isApp){return(this.dish.restrictions&&this.dish.restrictions.dishesWithPointsHint)||''} 441return(this.isWithPoints&&this.dishPrice.pointDishHint)||''},total(){const size=this.sizes.selected;const modifierSize=this.customModifierPos;const base=this.isApp?this.dishPrice:this.sizes.options&&this.sizes.options[size];let startPrice=base&&base.price;if(!app.tpSizesAvailability.isAvailable(base)){startPrice=0} 442if(this.partial){startPrice=this.partial.priceOneUnit*this.partialWeight} 443let total=startPrice||0;let separateTotal=0;for(let i=0;i<this.modifiers.length;i++){let modifier=this.modifiers[i];for(let j=0;j<modifier.options.length;j++){let option=modifier.options[j];if(option.isHidden&&!option.isService){continue} 444if(!option.count){continue} 445let price=option.price;if(modifier.custom){if(!option.prices[modifierSize]){this.$emit('alert',{message:"Invalid modifier configuration: all modifier prices should be tied to the dish size",kind:'config'});return"Error"} 446price=option.prices[modifierSize].price} 447if(typeof(price)!=='number'){continue} 448if(modifier.isSeparate){separateTotal+=price*option.count}else{total+=price*option.count}}}
449if(this.combo){total+=this.combo.filter(Boolean).reduce((sum,dish)=>sum+dish.dishTotal,0)} 450total=total*this.count+separateTotal;const currency=this.isWithPoints?'':(this.isApp?this.company.rub:this.company.currency);return app.price.format(total,currency,this.company.priceSeparator)}},methods:{changeCount(type){if(this.isApp&&!this.isAddressOk()){return} 451if(this.isBlocked){return} 452if(type==='plus'){this.increase()}else{this.decrease()}},increase(){if(this.plusInactive){return} 453if(this.partial){const newWeight=(Math.round(this.partialWeight*1000)+Math.round(this.partial.partialStep*1000))/1000;this.partialWeight=newWeight>9999?9999:newWeight;return}else{this.dish.count++} 454this.$emit('haptics')},decrease(){const isRaiseToMin=!this.isApp&&this.partial;if(this.minusInactive&&!isRaiseToMin){return} 455if(this.partial){var minWeight=this.partialMinWeight;const newWeight=(Math.round(this.partialWeight*1000)-Math.round(this.partial.partialStep*1000))/1000;this.partialWeight=newWeight<minWeight?minWeight:newWeight;return}else{this.dish.count=Math.max(this.dish.count-1,0)} 456this.$emit('haptics')},submit(){if(this.partial){var minWeight=this.partialMinWeight;if(this.partialWeight<minWeight){this.partialWeight=minWeight;return}} 457if(this.isQrReadonly){this.$emit('callWaiter');return} 458if(!this.isAddressOk()){return} 459if(this.issetRestriction){return} 460if(this.buttonState!=='add'){return} 461const sizeOption=this.selectedSizeOption;const dishId=sizeOption?sizeOption.dishId:this.dish.id;const size=(sizeOption||this.isPartialWithSizes)?0:this.sizes.selected;const options=[];let total=this.dish.priceRaw;for(let i=0;i<this.modifiers.length;i++){let modifier=this.modifiers[i];if(this.isApp&&modifier.type==='combo'){continue} 462let modifierActiveOptionsCount=0;let modifierHiddenOptionsCount=0;for(let j=0;j<modifier.options.length;j++){let option=modifier.options[j];if(option.isHidden&&!option.isService){modifierHiddenOptionsCount++;continue} 463if(!option.count){continue} 464modifierActiveOptionsCount+=option.count;options.push({id:option.id,idWithSize:option.id+(option.pos?'_'+option.pos:'')+'x'+option.count});total+=option.price*option.count} 465if(modifier.options.length!==modifierHiddenOptionsCount){if(modifier.min&&modifierActiveOptionsCount<modifier.min){let err=this.loc['topping/err/minOptions'].replace('{section}',modifier.title);let optionsLoc=this.loc['topping/option2'].split('|');err=err.replace('{options}',modifier.min+' '+app.plural(modifier.min,optionsLoc[0],optionsLoc[1],optionsLoc[2])) 466this.$emit('alert',{message:err,kind:'minOptions'});return}}} 467if(options.length){options.sort(function(a,b){return parseInt(a.id)<parseInt(b.id)?-1:1});for(let i in options){options[i]=options[i].idWithSize}} 468const dishSelected=dishId+'_'+size+(options.length?'+'+options.join(','):'');this.$emit('submit',{count:this.dish.count,dishId:this.dish.id,dishPos:dishSelected,dishName:this.dish.name,dishTotal:total,sectionId:this.dishSectionId,forceRemoveDish:this.forceRemoveDish,addWeight:this.partial&&this.partialWeight})}},template:` 469<div v-if="!userHasToSubscribe" 470 class="tsubmit" 471 :class="{'tsubmit--shadow': shadow, 'tsubmit--stop': buttonState === 'stop', 'tsubmit--orderSchedule': buttonState === 'schedule', 'tsubmit--pointDishMinSum': buttonState === 'pointMin'}"> 472 473 <div v-if="balance" 474 class="tsubmit__balance"> 475 {{balance}} 476 </div> 477 478 <div class="tsubmit__buttons"> 479 480 <div v-if="isCounterVisible" class="tsubmit__counter"> 481 482 <div class="tsubmit__minus" 483 :class="{'tsubmit__minus--inactive': minusInactive}" 484 v-tp-press 485 @click="changeCount('minus')"></div> 486 487 488 <div v-if="partial" class="tsubmit__partial"> 489 490 <partialWeight v-model="partialWeight" 491 :readonly="!isAppearanceInput" 492 :unit="partial.sizeTypeFormatted" 493 :min="partialMinWeight" 494 :max="9999"/> 495 496 </div> 497 <input v-else-if="isAppearanceInput" 498 class="tsubmit__count tsubmit__count--input" 499 v-model="dish.count"> 500 <div v-else class="tsubmit__count tsubmit__count--animated"> 501 <animatedCount :value="count"/> 502 </div> 503 504 <div class="tsubmit__plus" 505 :class="{'tsubmit__plus--inactive': plusInactive}" 506 v-tp-press 507 @click="changeCount('plus')"></div> 508 </div> 509 510 <div class="tsubmit__button" v-tp-press @click="submit()"> 511 512 <template v-if="isQrReadonly"> 513 {{ loc['site/qrMenu/callWaiter'] }} 514 </template> 515 516 <template v-else-if="buttonState === 'schedule'"> 517 <div class="tsubmit__text tsubmit__text--orderSchedule">{{ orderScheduleText }}</div> 518 </template> 519 520 <template v-else-if="isApp && buttonState === 'stop'">
521 {{ loc['dish/na'] }} 522 </template> 523 524 <template v-else-if="buttonState === 'pointMin'"> 525 <div class="tsubmit__text tsubmit__text--pointDishMinSum">{{ pointDishMinSumText }}</div> 526 </template> 527 528 <template v-else> 529 <div class="tsubmit__text">{{ submitText || loc['topping/add'] }}</div> 530 <svg v-if="!hidePrice" class="tsubmit__delimiter" width="2" height="20" viewBox="0 0 2 20" fill="none" xmlns="http://www.w3.org/2000/svg"> 531 <line x1="0.865723" y1="0.590576" x2="0.865722" y2="18.5906" stroke="currentColor" stroke-linecap="round" stroke-dasharray="1 4"/> 532 </svg> 533 <div v-if="!hidePrice" class="tsubmit__total"> 534 {{ total }} 535 <svg v-if="!isApp && isWithPoints" class="tp__pointIcon"> 536 <use xlink:href="#tp__pointIcon"></use> 537 </svg> 538 </div> 539 <point-icon v-if="isApp && isWithPoints" class="tsubmit__point hIcon__point" variant="cart"></point-icon> 540 </template> 541 542 </div> 543 544 </div> 545 546</div> 547 `};app.tpImageComponent={inject:['store','loc'],data(){this.swiper=null;return{}},computed:{textFormatted(){return this.loc['site/topping/emptyImage/promise'].replaceAll('\n','<br>')},media(){if(!this.store.dish.media||!this.store.dish.media.length){return null} 548return this.store.dish.media},},mounted(){if(!this.media){return} 549this.swiper=new Swiper(this.$refs.container,{direction:'horizontal',slidesPerView:1,spaceBetween:0,grabCursor:this.media.length>1,loop:this.media.length>1,pagination:{el:this.$refs.pagination,clickable:!0,},navigation:{nextEl:this.$refs.next,prevEl:this.$refs.prev,disabledClass:'tpImage__nav--disabled'},allowTouchMove:!0,})},beforeDestroy(){},destroyed(){this.swiper&&this.swiper.destroy()},template:` 550<div class="tpImage" :class="{'tpImage--slider': media}"> 551 552 <div v-if="!media" 553 class="tpImage__empty"> 554 <div class="tpImage__stub"> 555 <svg class="tpImage__serenity" xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" fill="none"> 556 <path d="M40.4895 46.7656L34.2343 40.5626C31.2159 37.5693 29.7066 36.0726 27.9746 35.5255C26.4514 35.0442 24.8143 35.0619 23.3018 35.576C21.582 36.1605 20.1055 37.6895 17.1526 40.7474L2.16536 55.5505M40.4895 46.7656L41.7697 45.4961C44.7919 42.4991 46.3029 41.0006 48.0367 40.4537C49.5615 39.9727 51.2001 39.9915 52.7134 40.5075C54.4341 41.0941 55.9104 42.627 58.8628 45.6927L62 48.8504M40.4895 46.7656L55.5311 61.837M55.5311 61.837C54.1909 62 52.4538 62 50 62H14C9.7996 62 7.69941 62 6.09507 61.1826C4.68386 60.4635 3.5365 59.3161 2.81745 57.9049C2.47986 57.2424 2.28169 56.4952 2.16536 55.5505M55.5311 61.837C56.485 61.721 57.2378 61.5225 57.9049 61.1826C59.3161 60.4635 60.4635 59.3161 61.1826 57.9049C62 56.3006 62 54.2004 62 50V48.8504M2.16536 55.5505C2 54.2077 2 52.4657 2 50V14C2 9.79961 2 7.69941 2.81745 6.09507C3.5365 4.68386 4.68386 3.5365 6.09507 2.81745C7.69941 2 9.7996 2 14 2H50C54.2004 2 56.3006 2 57.9049 2.81745C59.3161 3.5365 60.4635 4.68386 61.1826 6.09507C62 7.69941 62 9.79961 62 14V48.8504M50.75 20.7496C50.75 24.8917 47.3921 28.2496 43.25 28.2496C39.1079 28.2496 35.75 24.8917 35.75 20.7496C35.75 16.6075 39.1079 13.2496 43.25 13.2496C47.3921 13.2496 50.75 16.6075 50.75 20.7496Z" stroke="black" stroke-opacity="0.3" stroke-width="3.4" stroke-linecap="round" stroke-linejoin="round"/> 557 </svg> 558 <div class="tpImage__caption">{{ loc['site/topping/emptyImage/caption'] }}</div> 559 </div> 560 <div class="tpImage__text" v-html="textFormatted"></div> 561 </div> 562 563 <div v-else ref="container" class="tpImage__container swiper"> 564 565 <div class="tpImage__wrapper swiper-wrapper"> 566 567 <div v-for="(image, idx) in media" 568 class="tpImage__slide swiper-slide lazyload__wrap"> 569 570 <template v-if="image.type === 'video'"> 571 <video class="tpImage__img tpImage__img--video" 572 :src="image.preview" 573 autoplay muted loop playsinline webkit-playsinline></video> 574 </template> 575 576 <img v-else 577 :data-src="image.high" 578 :data-lowsrc="image.low" 579 :data-position="idx" 580 :src="image.low" 581 alt="" 582 class="tpImage__img lazyload"/> 583 584 </div> 585 586 </div> 587 588 <div ref="pagination" 589 class="tpImage__pagination swiper-pagination"> 590 </div> 591 592 <div ref="prev" class="tpImage__nav"><svg><use xlink:href="#icon__arrow"></use></svg></div> 593 <div ref="next" class="tpImage__nav"><svg><use xlink:href="#icon__arrow"></use></svg></div> 594 595 </div> 596 597 598</div> 599 `};app.tpCardComponent={components:{'tp-info':app.tpInfoComponent,'tp-sizes':app.tpSizesComponent,'tp-params':app.tpParamsComponent,'tp-modifier':app.tpModifierComponent,'tp-submit':app.tpSubmitComponent,}
599,props:['isApp','isDesktopVersion','dish','dishModifiers','loc','company','cart','isAppearanceTiles','isAppearanceInput','isAddressOk','dishSectionId','forceRemoveDish','hidePrice','hideCount','submitText','combo','issetRestriction','userHasToSubscribe','shadow',],data(){return{modifiersRevision:0}},watch:{'sizes.selected':function(pos,old){if(!app.tpSizesAvailability.sizePack(this.sizes,pos)){return} 600const prev=app.tpSizesAvailability.pack(this.dishModifiers,app.tpSizesAvailability.selectPos(this.sizes.options,old));this.carryModifierCounts(prev,this.modifiers);this.modifiersRevision++}},computed:{sizes(){return this.dishModifiers[0]},modifiers(){return app.tpSizesAvailability.selectedPack(this.dishModifiers)},quarterModifiers(){return this.isApp?this.modifiers:this.dishModifiers},isQuarterActive(){return app.tpQuarterRule.isActive(this.quarterModifiers)}},methods:{carryModifierCounts(from,to){const counts={};from.forEach(modifier=>(modifier.options||[]).forEach(option=>{if(option.count){counts[modifier.sectionId+':'+option.id]=option.count}}));to.forEach(modifier=>(modifier.options||[]).forEach(option=>{const carried=counts[modifier.sectionId+':'+option.id];if(carried){this.$set(option,'count',carried)}}))}},template:` 601 <div v-if="isApp" class="tpDish"> 602 603 <div class="tpDish__wrap"> 604 605 <slot name="beforeInfo"></slot> 606 607 <tp-info :isApp="true" 608 :dish="dish" 609 :sizes="sizes" 610 :modifiers="quarterModifiers" 611 :isQuarterActive="isQuarterActive" 612 :loc="loc" 613 :company="company" 614 @openLink="$emit('openLink', $event)" 615 @openPart="$emit('openPart', $event)"/> 616 617 <slot name="afterInfo"></slot> 618 619 <div class="tpDish__content"> 620 621 <tp-sizes v-if="sizes" 622 :isApp="true" 623 :dish="dish" 624 :sizes="sizes" 625 :modifiers="modifiers" 626 :loc="loc" 627 :company="company" 628 :hidePrice="hidePrice" 629 @haptics="$emit('haptics')" 630 @openLink="$emit('openLink', $event)"/> 631 632 <div v-if="combo" class="tpDish__combo"> 633 <slot name="combo" :modifiers="modifiers"></slot> 634 </div> 635 636 <div v-else class="tpDish__modifiers"> 637 <tp-modifier 638 v-for="(modifier, i) in modifiers" 639 :key="modifiersRevision + '_' + i" 640 :isApp="true" 641 :modifier="modifier" 642 :sizes="sizes" 643 :loc="loc" 644 :isAppearanceTiles="isAppearanceTiles" 645 :isAddressOk="isAddressOk" 646 @haptics="$emit('haptics')" 647 /> 648 </div> 649 650 </div> 651 652 <tp-submit 653 :isApp="true" 654 :dish="dish" 655 :sizes="sizes" 656 :modifiers="modifiers" 657 :dishSectionId="dishSectionId" 658 :loc="loc" 659 :company="company" 660 :cart="cart" 661 :isAppearanceInput="isAppearanceInput" 662 :forceRemoveDish="forceRemoveDish" 663 :isAddressOk="isAddressOk" 664 :issetRestriction="issetRestriction" 665 :hideCount="hideCount" 666 :hidePrice="hidePrice" 667 :submitText="submitText" 668 :combo="combo" 669 @submit="$emit('submit', $event)" 670 @haptics="$emit('haptics')" 671 @alert="$emit('alert', $event)" 672 /> 673 674 </div> 675 676 </div> 677 678 <div v-else class="tp" :class="{'tp--quarter': isQuarterActive}"> 679 680 <svg xmlns="http://www.w3.org/2000/svg" style="display: none"> 681 <symbol id="icon__arrow" viewBox="0 0 9 15" xmlns="http://www.w3.org/2000/svg"> 682 <path d="M7.85501 14.509L9.00001 13.349L2.90601 7.254L9.00001 1.16L7.85501 0L0.600006 7.255L7.85501 14.509Z" fill="currentColor"/> 683 </symbol> 684 <symbol id="tp__pointIcon" width="16" height="14" viewBox="0 0 16 14" fill="none"> 685 <path d="M6.5 1.25C9.67564 1.25 12.25 3.82436 12.25 7C12.25 10.1756 9.67564 12.75 6.5 12.75C3.32436 12.75 0.75 10.1756 0.75 7C0.75 3.82436 3.32436 1.25 6.5 1.25Z" stroke="currentColor" stroke-width="1.5"/> 686 <path d="M11.0867 13.1664C13.0422 11.7611 14.3164 9.46186 14.3164 6.86393C14.3164 4.22779 13.0044 1.89919 11 0.5C13.7024 1.33499 15.6666 3.86075 15.6666 6.84694C15.6666 9.80109 13.7444 12.3046 11.0867 13.1664Z" fill="currentColor"/> 687 </symbol> 688 </svg> 689 690 <!-- ÐеÑкÑоп ÑайÑа: Ñлева ÑеÑвеÑÑинки или галеÑеÑ, Ð¸Ñ ÑиÑÑÐµÑ Ð²Ñ Ð¾Ð´ --> 691 <slot name="aside" :isQuarterActive="isQuarterActive"></slot> 692 693 <div class="tp__data"> 694 695 <tp-info 696 :isApp="false" 697 :isDesktopVersion="isDesktopVersion" 698 :dish="dish" 699 :sizes="sizes" 700 :modifiers="quarterModifiers" 701 :isQuarterActive="isQuarterActive" 702 :loc="loc" 703 :company="company"/> 704 705 <div class="tp__content"> 706 707 <tp-sizes 708 :isApp="false" 709 :isDesktopVersion="isDesktopVersion" 710 :dish="dish" 711 :sizes="sizes" 712 :loc="loc" 713 :company="company"/> 714 715 <tp-params 716 :isApp="false" 717 :dish="dish" 718 :sizes="sizes"/> 719 720 <tp-modifier 721 v-for="(modifier, i) in modifiers" 722 :key="modifiersRevision + '_' + i" 723 :isApp="false" 724 :modifier="modifier" 725 :sizes="sizes" 726 :loc="loc" 727 :isAppearanceTiles="isAppearanceTiles"/> 728 729 <slot name="afterModifiers"></slot> 730 </div> 731 732 </div> 733 734 <tp-submit 735 :isApp="false" 736 :dish="dish" 737 :sizes="sizes" 738 :modifiers="modifiers" 739 :loc="loc" 740 :company="company" 741 :cart="cart" 742 :isAppearanceInput="isAppearanceInput" 743 :isAddressOk="isAddressOk" 744 :userHasToSubscribe="userHasToSubscribe" 745 :shadow="shadow" 746 @submit="$emit('submit', $event)" 747 @callWaiter="$emit('callWaiter')" 748 @alert="$emit('alert', $event)"/> 749 750 </div> 751 `};app.tpSiteAlert=function({message,kind}
751){if(kind==='config'){alert(message);return} 752app.alert(message,'danger')};Vue.directive('tp-press',{});app.addModule(function(){const show=(vrParams)=>{let vr;const runVm=(params)=>{const toppingComponent={components:Object.assign({'tp-card':app.tpCardComponent,'tp-image':app.tpImageComponent,'tp-quarter':app.tpQuarterComponent,'overlap-indicator':app.overlapIndicatorComponent,},app.siteDishFavComponent?{'site-dish-fav':app.siteDishFavComponent}:{}),provide(){return{store:this.store,loc:this.loc}},data(){return{store:{isAppearanceTiles:this.$store.state.company&&this.$store.state.company.toppingAppearance==='tiles',isAppearanceInput:this.$store.state.company&&this.$store.state.company.toppingCounterAppearance==='input',dish:params.dish,modifiers:params.modifiers,forceAddress:params.forceAddress,forceRemoveDish:params.forceRemoveDish},isOverlap:!1}},computed:Object.assign({sizes(){return this.store.modifiers[0]},isDesktopVersion(){return this.isKiosk||!this.mobile},isFav(){return!this.isDesktopVersion&&!!app.siteFav&&app.siteFav.state.ready},modifiers(){return app.tpSizesAvailability.selectedPack(this.store.modifiers)},pointsCart(){return app.tpSizesAvailability.hasPointsMinSum(!1,this.store.dish)?this.cart:null}},Vuex.mapState(['loc','mobile','isKiosk','company','cart','userHasToSubscribe'])),mounted(){this.$nextTick(()=>{this.restoreSelections()})},methods:{callWaiter(){setTimeout(()=>{PubSub.publish('showWaiter',{action:'call-waiter'})},600);this.$emit('close')},onSubmit(selected){PubSub.publish('dishSelected',{dishPosId:selected.dishPos,count:selected.count,addWeight:selected.addWeight,forceRemoveDish:this.store.forceRemoveDish,});this.$emit('close')},onAlert(e){app.tpSiteAlert(e)},isAddressOk(){if(this.store.forceAddress){var selections={sizeSelected:this.sizes.selected,modifiers:{},count:this.store.dish.count||1};this.modifiers.forEach(function(mod){(mod.options||[]).forEach(function(opt){if(opt.count&&opt.count!==(parseInt(opt.defaultAmount)||0)){selections.modifiers[opt.id]=opt.count}})});sessionStorage.setItem('restoreToppingSelections',JSON.stringify(selections));PubSub.publish(this.store.forceAddress,{forceReload:!0,openDishAfterReload:{id:this.store.dish.id,name:this.store.dish.name}});return!1} 753return!0},restoreSelections(){var raw=sessionStorage.getItem('restoreToppingSelections');if(!raw)return;sessionStorage.removeItem('restoreToppingSelections');var selections=JSON.parse(raw);if(selections.modifiers){this.modifiers.forEach(function(mod){(mod.options||[]).forEach(function(opt){if(selections.modifiers[opt.id]!==undefined){opt.count=selections.modifiers[opt.id]}})})} 754if(selections.sizeSelected!==undefined){this.sizes.selected=app.tpSizesAvailability.selectPos(this.sizes.options,selections.sizeSelected)} 755if(selections.count>1){this.$set(this.store.dish,'count',selections.count)}}},template:` 756 757 <tp-card 758 :isApp="false" 759 :isDesktopVersion="isDesktopVersion" 760 :dish="store.dish" 761 :dishModifiers="store.modifiers" 762 :loc="loc" 763 :company="company" 764 :cart="pointsCart" 765 :isAppearanceTiles="store.isAppearanceTiles" 766 :isAppearanceInput="store.isAppearanceInput" 767 :isAddressOk="isAddressOk" 768 :userHasToSubscribe="userHasToSubscribe" 769 :shadow="isOverlap" 770 @submit="onSubmit" 771 @callWaiter="callWaiter" 772 @alert="onAlert"> 773 774 <template #aside="{isQuarterActive}"> 775 <template v-if="isDesktopVersion"> 776 <tp-quarter v-if="isQuarterActive" 777 class="tp__quarter" 778 :isApp="false" 779 :modifiers="store.modifiers" 780 :sizes="sizes"/> 781 782 <tp-image v-else 783 class="tp__image"/> 784 </template> 785 786 <site-dish-fav v-else-if="isFav" 787 :dishId="Number(store.dish.id)" 788 size="big" 789 place="card"/> 790 </template> 791 792 <template #afterModifiers> 793 <overlap-indicator 794 v-if="isDesktopVersion" 795 v-model="isOverlap"/> 796 </template> 797 798 </tp-card> 799 800 `};app.openViewer({desktop:{maxWidth:'1050px',disableAutogrow:!0,overflow:'hidden',},mobile:{withTick:!0,withClose:!1,minHeight:'90dvh',maxHeight:'90dvh',backgroundColor:'transparent',},className:'tp__viewer',component:toppingComponent,})} 801if(vrParams.preload){app.fetch('/cart/topping/get',vrParams.preload,(response)=>{if(response.error){return vr.close()} 802runVm(response)})}else{runVm(vrParams)}};const tryToOpenDishAfterReload=()=>{const openDishAfterReload=sessionStorage.getItem('openDishAfterReload');if(!openDishAfterReload){return} 803sessionStorage.removeItem('openDishAfterReload');const dish=JSON.parse(openDishAfterReload);let dishEl=document.querySelector('.ddish[data-id="'+dish.id+'"]');if(!dishEl){dishEl=Array.from(document.querySelectorAll('.ddish__link')).find(item=>item.innerText===dish.name);
803dishEl=dishEl&&dishEl.closest('.ddish')} 804if(!dishEl){return} 805PubSub.publish('hydrateDish',{id:dishEl.dataset.id,plusClicked:!1});if(!app.hydrateMenuDish&&!dishEl.classList.contains('ddish--observed')){dishEl.click()}} 806PubSub.subscribe('showTopping',(e,params)=>{show(params);if(params.dish){PubSub.publish('gtmNotify',{event:'view_item',item:params.dish})}});setTimeout(()=>{tryToOpenDishAfterReload()},300)});app.tpShellComponent={components:{'tp-info':app.tpInfoComponent,'tp-sizes':app.tpSizesComponent,'tp-params':app.tpParamsComponent,'tp-modifier':app.tpModifierComponent,'tp-submit':app.tpSubmitComponent,'tp-image':app.tpImageComponent,'overlap-indicator':app.overlapIndicatorComponent,},props:['dish','allModifiers','recalc','callWaiter','submitText','hideCounter'],provide:function(){var mods=this.allModifiers||[];var sizes=mods[0]||{options:[{pos:0,price:0}],selected:0};if(sizes.selected===undefined){sizes.selected=0} 807var regular=[];for(var i=1;i<mods.length;i++){if(mods[i].type!=='combo'){regular.push(mods[i])}} 808var company=this.$store.state.company;var store={isAppearanceTiles:company&&company.toppingAppearance==='tiles',isAppearanceInput:company&&company.toppingCounterAppearance==='input',dish:this.dish};var loc=this.$store.state.loc;this._tpSizes=sizes;this._tpRegularModifiers=regular;this._tpStore=store;this._tpLoc=loc;return{store:store,loc:loc}},data:function(){return{isOverlap:!1}},computed:Object.assign({isDesktopVersion:function(){return this.isKiosk||!this.mobile},sizes:function(){return this._tpSizes},regularModifiers:function(){return this._tpRegularModifiers||[]},tpStore:function(){return this._tpStore},tpLoc:function(){return this._tpLoc},pointsCart:function(){return app.tpSizesAvailability.hasPointsMinSum(!1,this.dish)?this.cart:null}},Vuex.mapState(['mobile','isKiosk','company','cart','userHasToSubscribe'])),methods:{isAddressOk:function(){return!0},onSubmit:function(selected){this.recalc(selected.dishPos,selected.count,selected.addWeight)},onAlert:function(e){app.tpSiteAlert(e)}},store:app.store,template:` 809 <div class="tp"> 810 811 <template v-if="isDesktopVersion"> 812 <tp-image class="tp__image"/> 813 </template> 814 815 <div class="tp__data"> 816 817 <!-- ЧеÑвеÑÑинок Ñ ÑаÑÑи комбо Ð½ÐµÑ --> 818 <tp-info :isApp="false" 819 :isDesktopVersion="isDesktopVersion" 820 :dish="dish" 821 :sizes="sizes" 822 :isQuarterActive="false" 823 :loc="tpLoc" 824 :company="company"/> 825 826 <div class="tp__content"> 827 828 <tp-sizes :isApp="false" 829 :isDesktopVersion="isDesktopVersion" 830 :dish="dish" 831 :sizes="sizes" 832 :loc="tpLoc" 833 :company="company"/> 834 835 <slot name="content"> 836 <tp-params :isApp="false" 837 :dish="dish" 838 :sizes="sizes"/> 839 840 <slot name="beforeModifiers"></slot> 841 842 <tp-modifier 843 v-for="modifier in regularModifiers" 844 :key="modifier.id || modifier.pos" 845 :isApp="false" 846 :modifier="modifier" 847 :sizes="sizes" 848 :loc="tpLoc" 849 :isAppearanceTiles="tpStore.isAppearanceTiles"/> 850 851 <slot name="afterModifiers"></slot> 852 853 <overlap-indicator 854 v-if="isDesktopVersion" 855 v-model="isOverlap"/> 856 </slot> 857 858 </div> 859 860 </div> 861 862 <slot name="submit"> 863 <tp-submit 864 :isApp="false" 865 :dish="dish" 866 :sizes="sizes" 867 :modifiers="regularModifiers" 868 :loc="tpLoc" 869 :company="company" 870 :cart="pointsCart" 871 :isAppearanceInput="tpStore.isAppearanceInput" 872 :isAddressOk="isAddressOk" 873 :userHasToSubscribe="userHasToSubscribe" 874 :shadow="isOverlap" 875 :hideCount="hideCounter" 876 :submitText="submitText" 877 @submit="onSubmit" 878 @callWaiter="callWaiter()" 879 @alert="onAlert"/> 880 </slot> 881 882 </div> 883 `};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.