Merge remote-tracking branch 'origin/dev' into dev

remotes/origin/hasaccess
Vitaly Baev 8 years ago
commit 96160898a5
  1. 45
      api/v1/serializers/config.py
  2. 19
      api/v1/views.py
  3. 4
      apps/auth/templates/auth/password_reset.html
  4. 2
      apps/auth/templates/auth/password_reset.txt
  5. 5
      apps/auth/views.py
  6. 0
      apps/config/__init__.py
  7. 5
      apps/config/admin.py
  8. 5
      apps/config/apps.py
  9. 27
      apps/config/migrations/0001_initial.py
  10. 18
      apps/config/migrations/0002_auto_20180326_1026.py
  11. 23
      apps/config/migrations/0003_auto_20180326_1027.py
  12. 18
      apps/config/migrations/0004_config_main_page_top_image.py
  13. 23
      apps/config/migrations/0005_auto_20180326_1314.py
  14. 0
      apps/config/migrations/__init__.py
  15. 39
      apps/config/models.py
  16. 3
      apps/config/tests.py
  17. 3
      apps/config/views.py
  18. 1
      apps/content/admin.py
  19. 6
      apps/content/tasks.py
  20. 4
      apps/course/templates/course/course.html
  21. 4
      apps/payment/models.py
  22. 7
      apps/user/models.py
  23. 2
      docker-compose.yml
  24. 5
      project/context_processors.py
  25. 14
      project/fields.py
  26. 78
      project/settings.py
  27. 13
      project/templates/lilcity/index.html
  28. 9
      project/templates/lilcity/main.html
  29. 9
      project/urls.py
  30. 1
      requirements.txt
  31. 1
      web/src/js/app.js
  32. 34
      web/src/js/modules/mixpanel.js
  33. 5679
      web/src/js/third_party/mixpanel-2-latest.js
  34. 17
      web/webpack.config.js
  35. 269
      web/yarn.lock

@ -1,40 +1,27 @@
from constance import config
from constance.admin import get_values, ConstanceForm
from rest_framework import serializers
from rest_framework.fields import SkipField
from collections import OrderedDict
from apps.config.models import Config
def _set_constance_value(key, value):
form = ConstanceForm(initial=get_values())
field = form.fields[key]
clean_value = field.clean(field.to_python(value))
setattr(config, key, clean_value)
class ConfigSerializer(serializers.Serializer):
class ConfigSerializer(serializers.ModelSerializer):
SERVICE_COMMISSION = serializers.IntegerField(required=False)
SERVICE_DISCOUNT_MIN_AMOUNT = serializers.IntegerField(required=False)
SERVICE_DISCOUNT = serializers.IntegerField(required=False)
INSTAGRAM_CLIENT_ACCESS_TOKEN = serializers.CharField(required=False)
INSTAGRAM_CLIENT_SECRET = serializers.CharField(required=False)
INSTAGRAM_PROFILE_URL = serializers.CharField(required=False)
# SCHOOL_LOGO_IMAGE = serializers.ImageField(required=False)
def to_representation(self, instance):
ret = OrderedDict()
fields = self._readable_fields
for field in fields:
attribute = instance.get(field.field_name)
ret[field.field_name] = field.to_representation(attribute)
return ret
def to_internal_value(self, data):
ret = OrderedDict(get_values())
for k, v in data.items():
ret[k] = v
return ret
SCHOOL_LOGO_IMAGE = serializers.ImageField(required=False, allow_null=True)
MAIN_PAGE_TOP_IMAGE = serializers.ImageField(required=False, allow_null=True)
def update(self, instance, validated_data):
for k, v in validated_data.items():
_set_constance_value(k, v)
class Meta:
model = Config
fields = (
'SERVICE_COMMISSION',
'SERVICE_DISCOUNT_MIN_AMOUNT',
'SERVICE_DISCOUNT',
'INSTAGRAM_CLIENT_ACCESS_TOKEN',
'INSTAGRAM_CLIENT_SECRET',
'INSTAGRAM_PROFILE_URL',
'SCHOOL_LOGO_IMAGE',
'MAIN_PAGE_TOP_IMAGE',
)

@ -1,10 +1,6 @@
from constance.admin import get_values
from django.contrib.auth import get_user_model
from rest_framework import status
from rest_framework import views, viewsets
from rest_framework import generics
from rest_framework import status, views, viewsets, generics
from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response
@ -43,6 +39,7 @@ from apps.course.models import (
Material, Lesson,
Like,
)
from apps.config.models import Config
from apps.content.models import (
Image, Text, ImageText, Video,
Gallery, GalleryImage, ImageObject,
@ -327,18 +324,12 @@ class SchoolScheduleViewSet(ExtendedModelViewSet):
class ConfigViewSet(generics.RetrieveUpdateAPIView):
queryset = Config.objects.all()
serializer_class = ConfigSerializer
permission_classes = (IsAdmin,)
def retrieve(self, request, *args, **kwargs):
serializer = ConfigSerializer(get_values())
return Response(serializer.data)
def patch(self, request, *args, **kwargs):
serializer = ConfigSerializer(data=request.data)
if serializer.is_valid():
serializer.update(get_values(), serializer.validated_data)
return Response(serializer.data)
def get_object(self):
return Config.load()
class CommentViewSet(ExtendedModelViewSet):

@ -3,8 +3,8 @@
{% block content %}
<p style="margin: 0 0 20px">Для восстановления пароля нажмите кнопку ниже.</p>
<div style="margin-bottom: 10px;">
<a href="{{ protocol}}://{{ domain }}{% url 'lilcity:password_reset_confirm' uidb64=uid token=token %}" style="text-decoration: none; position: relative; padding: 13px 24px 12px; background-image: linear-gradient(-225deg, #D1FF7F 0%, #56FFFD 100%); border-radius: 3px; font-size: 12px; color: #191919; text-transform: uppercase; letter-spacing: 2px; text-align: center; transition: all .2s; z-index: 2;">Нажмите для восстановления</a>
<a href="{{ domain }}{% url 'lilcity:password_reset_confirm' uidb64=uid token=token %}" style="text-decoration: none; position: relative; padding: 13px 24px 12px; background-image: linear-gradient(-225deg, #D1FF7F 0%, #56FFFD 100%); border-radius: 3px; font-size: 12px; color: #191919; text-transform: uppercase; letter-spacing: 2px; text-align: center; transition: all .2s; z-index: 2;">Нажмите для восстановления</a>
<p>Или скопируйте ссылку ниже, и вставьте её в адресную строку браузера.</p>
<p>{{ protocol}}://{{ domain }}{% url 'lilcity:password_reset_confirm' uidb64=uid token=token %}</p>
<p>{{ domain }}{% url 'lilcity:password_reset_confirm' uidb64=uid token=token %}</p>
</div>
{% endblock content %}

@ -1,2 +1,2 @@
Восстановление пароля для {{ email }}. Перейдите по ссылке ниже:
{{ protocol}}://{{ domain }}{% url 'lilcity:password_reset_confirm' uidb64=uid token=token %}
{{ domain }}{% url 'lilcity:password_reset_confirm' uidb64=uid token=token %}

@ -48,8 +48,9 @@ class LearnerRegistrationView(FormView):
# fixme: change email text
# fixme: async send email
refferer = self.request.META.get('HTTP_REFERER')
token = verification_email_token.make_token(user)
url = self.request.scheme + '://' + self.request.get_host() + str(reverse_lazy('lilcity:verification-email', args=[token]))
url = refferer + str(reverse_lazy('lilcity:verification-email', args=[token]))
send_email('Verification Email', email, "notification/email/verification_email.html", url=url)
return JsonResponse({"success": True}, status=201)
@ -106,7 +107,9 @@ class PasswordResetView(views.PasswordContextMixin, BaseFormView):
token_generator = views.default_token_generator
def form_valid(self, form):
refferer = self.request.META.get('HTTP_REFERER')
opts = {
'domain_override': refferer,
'use_https': self.request.is_secure(),
'token_generator': self.token_generator,
'from_email': self.from_email,

@ -0,0 +1,5 @@
from django.contrib import admin
from .models import Config
admin.site.register(Config)

@ -0,0 +1,5 @@
from django.apps import AppConfig
class ConfigConfig(AppConfig):
name = 'config'

@ -0,0 +1,27 @@
# Generated by Django 2.0.3 on 2018-03-26 10:25
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Config',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('INSTAGRAM_CLIENT_ACCESS_TOKEN', models.CharField(default='7145314808.f6fa114.6b737a5355534e0eb5cf7c40cb4998f6', max_length=51)),
('INSTAGRAM_CLIENT_SECRET', models.CharField(default='2334a921425140ccb180d145dcd35b25', max_length=32)),
('INSTAGRAM_PROFILE_URL', models.CharField(default='#', max_length=126)),
('SERVICE_COMMISSION', models.IntegerField(default=10)),
('SERVICE_DISCOUNT_MIN_AMOUNT', models.IntegerField(default=3500)),
('SERVICE_DISCOUNT', models.ImageField(default=1000, upload_to='')),
('SCHOOL_LOGO_IMAGE', models.ImageField(null=True, upload_to='')),
],
),
]

@ -0,0 +1,18 @@
# Generated by Django 2.0.3 on 2018-03-26 10:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('config', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='config',
name='SCHOOL_LOGO_IMAGE',
field=models.FileField(null=True, upload_to=''),
),
]

@ -0,0 +1,23 @@
# Generated by Django 2.0.3 on 2018-03-26 10:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('config', '0002_auto_20180326_1026'),
]
operations = [
migrations.AlterField(
model_name='config',
name='SCHOOL_LOGO_IMAGE',
field=models.ImageField(null=True, upload_to=''),
),
migrations.AlterField(
model_name='config',
name='SERVICE_DISCOUNT',
field=models.IntegerField(default=1000),
),
]

@ -0,0 +1,18 @@
# Generated by Django 2.0.3 on 2018-03-26 11:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('config', '0003_auto_20180326_1027'),
]
operations = [
migrations.AddField(
model_name='config',
name='MAIN_PAGE_TOP_IMAGE',
field=models.ImageField(null=True, upload_to=''),
),
]

@ -0,0 +1,23 @@
# Generated by Django 2.0.3 on 2018-03-26 13:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('config', '0004_config_main_page_top_image'),
]
operations = [
migrations.AlterField(
model_name='config',
name='MAIN_PAGE_TOP_IMAGE',
field=models.ImageField(blank=True, null=True, upload_to=''),
),
migrations.AlterField(
model_name='config',
name='SCHOOL_LOGO_IMAGE',
field=models.ImageField(blank=True, null=True, upload_to=''),
),
]

@ -0,0 +1,39 @@
from django.db import models
class Config(models.Model):
INSTAGRAM_CLIENT_ACCESS_TOKEN = models.CharField(
max_length=51, default='7145314808.f6fa114.6b737a5355534e0eb5cf7c40cb4998f6'
)
INSTAGRAM_CLIENT_SECRET = models.CharField(max_length=32, default='2334a921425140ccb180d145dcd35b25')
INSTAGRAM_PROFILE_URL = models.CharField(max_length=126, default='#')
SERVICE_COMMISSION = models.IntegerField(default=10)
SERVICE_DISCOUNT_MIN_AMOUNT = models.IntegerField(default=3500)
SERVICE_DISCOUNT = models.IntegerField(default=1000)
SCHOOL_LOGO_IMAGE = models.ImageField(null=True, blank=True)
MAIN_PAGE_TOP_IMAGE = models.ImageField(null=True, blank=True)
def save(self, *args, **kwargs):
self.pk = 1
super().save(*args, **kwargs)
def delete(self, *args, **kwargs):
pass
@classmethod
def load(cls):
try:
obj, created = cls.objects.get_or_create(pk=1)
except:
# This magic for migrate
obj = {
'INSTAGRAM_CLIENT_ACCESS_TOKEN': '',
'INSTAGRAM_CLIENT_SECRET': '',
'INSTAGRAM_PROFILE_URL': '',
'SERVICE_COMMISSION': '',
'SERVICE_DISCOUNT_MIN_AMOUNT': '',
'SERVICE_DISCOUNT': '',
'SCHOOL_LOGO_IMAGE': '',
'MAIN_PAGE_TOP_IMAGE': '',
}
return obj

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

@ -63,7 +63,6 @@ class ContentAdmin(PolymorphicParentModelAdmin):
Text,
ImageText,
Video,
# GalleryAdmin,
)

@ -3,22 +3,24 @@ import json
import requests
import shutil
from constance import config
from instagram.client import InstagramAPI
from project.celery import app
from time import sleep
from django.conf import settings
from apps.config.models import Config
@app.task
def retrieve_photos():
config = Config.load()
api = InstagramAPI(
access_token=config.INSTAGRAM_CLIENT_ACCESS_TOKEN,
client_secret=config.INSTAGRAM_CLIENT_SECRET,
)
recent_media, next_ = api.user_recent_media(user_id='self', count=20)
path = os.path.join(settings.BASE_DIR, config.INSTAGRAM_RESULTS_PATH)
path = os.path.join(settings.BASE_DIR, settings.INSTAGRAM_RESULTS_PATH)
for idx, media in enumerate(recent_media):
try:
fname = os.path.join(path, f'{idx}.jpg')

@ -14,7 +14,7 @@
{% block ogdescription %}{{ course.short_description }}{% endblock ogdescription %}
{% block content %}
<div class="section section_border">
<div class="section section_border course">
<div class="section__center center center_sm">
<div class="go">
<a class="go__item" href="{% if next %}{{next}}{% else %}{% url 'courses' %}{% endif %}">
@ -30,6 +30,7 @@
class="go__btn btn{% if pending %} btn_gray{% endif %} btn_md"
{% if user.is_authenticated %}
{% if not pending %}
data-course-buy
href="{% url 'course-checkout' course.id %}"
{% endif %}
{% else %}
@ -394,6 +395,7 @@
class="go__btn btn{% if pending %} btn_gray{% endif %} btn_md"
{% if user.is_authenticated %}
{% if not pending %}
data-course-buy
href="{% url 'course-checkout' course.id %}"
{% endif %}
{% else %}

@ -1,4 +1,3 @@
from constance import config
from paymentwall import Pingback
from polymorphic.models import PolymorphicModel
@ -9,9 +8,12 @@ from django.core.validators import RegexValidator
from django.utils.timezone import now
from apps.course.models import Course
from apps.config.models import Config
from apps.school.models import SchoolSchedule
from apps.notification.utils import send_email
config = Config.load()
User = get_user_model()
CREDIT_CARD_RE = r'^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\d{11})$'

@ -110,7 +110,12 @@ def send_user_info_to_mixpanel(sender, instance=None, created=False, **kwargs):
@receiver(post_save, sender=User)
def auto_create_subscription(sender, instance=None, created=False, **kwargs):
if not hasattr(instance, 'email_subscription'):
try:
es = EmailSubscription.objects.get(email=instance.email)
if not es.user:
es.user = instance
es.save()
except EmailSubscription.DoesNotExist:
instance.email_subscription = EmailSubscription.objects.create(
user=instance,
email=instance.email,

@ -22,7 +22,7 @@ services:
restart: always
volumes:
- .:/lilcity
command: bash -c "python manage.py migrate && python manage.py loaddata /lilcity/apps/*/fixtures/*.json && gunicorn --workers=4 project.wsgi --bind=0.0.0.0:8000 --worker-class=gthread --reload"
command: bash -c "python manage.py collectstatic --no-input && python manage.py migrate && python manage.py loaddata /lilcity/apps/*/fixtures/*.json && gunicorn --workers=4 project.wsgi --bind=0.0.0.0:8000 --worker-class=gthread --reload"
environment:
- DJANGO_SETTINGS_MODULE=project.settings
- DATABASE_SERVICE_HOST=db

@ -0,0 +1,5 @@
from apps.config.models import Config
def config(request):
return {"config": Config.load()}

@ -0,0 +1,14 @@
from django.forms import ImageField as BaseImageField
class ImageField(BaseImageField):
def to_internal_value(self, data):
# if data is None image field was not uploaded
if data:
file_object = super(ImageField, self).to_internal_value(data)
django_field = self._DjangoImageField()
django_field.error_messages = self.error_messages
django_field.to_python(file_object)
return file_object
return data

@ -17,7 +17,6 @@ from celery.schedules import crontab
from collections import OrderedDict
from datetime import timedelta
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@ -53,8 +52,6 @@ INSTALLED_APPS = [
'rest_framework.authtoken',
'drf_yasg',
'corsheaders',
'constance',
'constance.backends.database',
'sorl.thumbnail',
'raven.contrib.django.raven_compat',
] + [
@ -64,10 +61,9 @@ INSTALLED_APPS = [
'apps.payment',
'apps.course',
'apps.content',
'apps.config',
'apps.school',
]
if DEBUG:
INSTALLED_APPS += ['silk']
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
@ -80,8 +76,6 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'apps.auth.middleware.TokenAuthLoginMiddleware',
]
if DEBUG:
MIDDLEWARE += ['silk.middleware.SilkyMiddleware']
ROOT_URLCONF = 'project.urls'
@ -91,32 +85,26 @@ TEMPLATES = [
'DIRS': [
'project',
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'constance.context_processors.config',
'project.context_processors.config',
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
'loaders': [
('django.template.loaders.cached.Loader', [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
]),
],
},
},
]
WSGI_APPLICATION = 'project.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
@ -208,6 +196,7 @@ REST_FRAMEWORK = {
),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
# 'rest_framework.renderers.BrowsableAPIRenderer',
),
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
@ -227,51 +216,11 @@ CELERY_TASK_SERIALIZER = 'json'
CELERY_BEAT_SCHEDULE = {
'retrieve_photos_from_instagram': {
'task': 'apps.content.tasks.retrieve_photos',
'schedule': timedelta(minutes=2) if DEBUG else crontab(minute=0, hour=0),
'schedule': timedelta(minutes=5) if DEBUG else crontab(minute=0, hour=0),
'args': (),
},
}
# Dynamic settings
CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
CONSTANCE_ADDITIONAL_FIELDS = {
'image_field': ['django.forms.ImageField', {}]
}
CONSTANCE_CONFIG = OrderedDict((
('INSTAGRAM_CLIENT_ACCESS_TOKEN', ('7145314808.f6fa114.ce354a5d876041fc9d3db04b0045587d', '')),
('INSTAGRAM_CLIENT_SECRET', ('2334a921425140ccb180d145dcd35b25', '')),
('INSTAGRAM_PROFILE_URL', ('#', 'URL профиля Instagram.')),
('INSTAGRAM_RESULTS_TAG', ('#lil_акварель', 'Тэг результатов работ.')),
('INSTAGRAM_RESULTS_PATH', ('media/instagram/results/', 'Путь до результатов работ.')),
('SERVICE_COMMISSION', (10, 'Комиссия сервиса в процентах.')),
('SERVICE_DISCOUNT_MIN_AMOUNT', (3500, 'Минимальная сумма платежа для школы, после которой вычитывается скидка SERVICE_DISCOUNT.')),
('SERVICE_DISCOUNT', (1000, 'Комиссия сервиса при покупке всех дней.')),
# ('SCHOOL_LOGO_IMAGE', ('default.png', 'Изображение в диалоге покупки школы', 'image_field')),
))
CONSTANCE_CONFIG_FIELDSETS = OrderedDict({
'Service': (
'SERVICE_COMMISSION',
'SERVICE_DISCOUNT_MIN_AMOUNT',
'SERVICE_DISCOUNT',
# 'SCHOOL_LOGO_IMAGE',
),
'Instagram': (
'INSTAGRAM_CLIENT_ACCESS_TOKEN',
'INSTAGRAM_CLIENT_SECRET',
'INSTAGRAM_PROFILE_URL',
'INSTAGRAM_RESULTS_TAG',
'INSTAGRAM_RESULTS_PATH',
),
})
try:
from .local_settings import *
except ImportError:
pass
try:
from paymentwall import *
except ImportError:
@ -302,3 +251,10 @@ RAVEN_CONFIG = {
# release based on the git info.
'release': raven.fetch_git_sha(BASE_DIR),
}
INSTAGRAM_RESULTS_PATH = 'media/instagram/results/'
try:
from .local_settings import *
except ImportError:
pass

@ -47,12 +47,23 @@
viewportmeta.content = 'width=device-width, maximum-scale=1.6, initial-scale=1.0';
}
}
</script>
<script>
LIL_SERVER_TIME = "{% now 'U' %}";
LIL_SERVER_TIME_DIFF = Math.floor((new Date().getTime()) / 1000) - parseInt(LIL_SERVER_TIME);
USER_ID = "{{ request.user.id }}";
COURSE_ID = "{{ course.id }}";
MIXPANEL_CUSTOM_LIB_URL = "/static/mixpanel-2-latest.js";
</script>
{% block mixpanel %}
<!-- start Mixpanel -->
<script type="text/javascript">(function(e,a){if(!a.__SV){var b=window;try{var c,l,i,j=b.location,g=j.hash;c=function(a,b){return(l=a.match(RegExp(b+"=([^&]*)")))?l[1]:null};g&&c(g,"state")&&(i=JSON.parse(decodeURIComponent(c(g,"state"))),"mpeditor"===i.action&&(b.sessionStorage.setItem("_mpcehash",g),history.replaceState(i.desiredHash||"",e.title,j.pathname+j.search)))}catch(m){}var k,h;window.mixpanel=a;a._i=[];a.init=function(b,c,f){function e(b,a){var c=a.split(".");2==c.length&&(b=b[c[0]],a=c[1]);b[a]=function(){b.push([a].concat(Array.prototype.slice.call(arguments,
0)))}}var d=a;"undefined"!==typeof f?d=a[f]=[]:f="mixpanel";d.people=d.people||[];d.toString=function(b){var a="mixpanel";"mixpanel"!==f&&(a+="."+f);b||(a+=" (stub)");return a};d.people.toString=function(){return d.toString(1)+".people (stub)"};k="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config reset people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" ");
for(h=0;h<k.length;h++)e(d,k[h]);a._i.push([b,c,f])};a.__SV=1.2;b=e.createElement("script");b.type="text/javascript";b.async=!0;b.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?MIXPANEL_CUSTOM_LIB_URL:"file:"===e.location.protocol&&"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";c=e.getElementsByTagName("script")[0];c.parentNode.insertBefore(b,c)}})(document,window.mixpanel||[]);
mixpanel.init("79bd6bfd98667ed977737e6810b8abcd");
</script>
<!-- end Mixpanel -->
{% endblock mixpanel %}
</head>
<body>

@ -2,7 +2,14 @@
{% block title %}School LIL.CITY{% endblock title %}
{% block content %}
<div class="main" style="background-image: url({% static 'img/bg-1.jpg' %});">
<div
class="main"
{% if config.MAIN_PAGE_TOP_IMAGE %}
style="background-image: url({{ config.MAIN_PAGE_TOP_IMAGE.url }});"
{% else %}
style="background-image: url({% static 'img/bg-1.jpg' %});"
{% endif %}
>
<div class="main__center center">
<div class="main__title">Первая онлайн-школа креативного мышления для детей! 5+</div>
<a

@ -13,10 +13,11 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView
from django.conf import settings
from django.urls import path, include
from apps.course.views import (
CoursesView, likes, coursecomment,
@ -82,6 +83,8 @@ if settings.DEBUG:
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += [path('silk/', include('silk.urls', namespace='silk'))]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns()
if 'silk' in settings.INSTALLED_APPS:
urlpatterns += [path('silk/', include('silk.urls', namespace='silk'))]

@ -5,7 +5,6 @@ Django==2.0.3
django-active-link==0.1.2
django-anymail[mailgun]==2.0
django-cors-headers==2.2.0
django-constance[database]==2.1.0
django-filter==2.0.0.dev1
django-mptt==0.9.0
django-silk==2.0.0

@ -13,5 +13,6 @@ import "./modules/courses";
import "./modules/comments";
import "./modules/password-show";
import "./modules/profile";
import "./modules/mixpanel";
import "../sass/app.sass";

@ -0,0 +1,34 @@
import $ from 'jquery';
$(document).ready(function (e) {
mixpanel.identify(USER_ID);
let body = $('body'),
cource = $('.course');
if (cource.length) {
mixpanel.track(
'Open course',
{ 'course_id': COURSE_ID }
);
};
body.on('click', '[data-popup]', function (e) {
let data = $(this).data('popup');
if (data === '.js-popup-buy') {
mixpanel.track(
'Open school buy popup'
);
}
});
body.on('click', '[data-course-buy]', function (e) {
e.preventDefault();
let href = $(this).attr('href');
let t = mixpanel.track(
'Click course buy button',
{ 'course_id': COURSE_ID },
function () {
window.location = href;
}
);
});
});

File diff suppressed because it is too large Load Diff

@ -6,7 +6,8 @@ const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: {
app: "./src/js/app.js",
courseRedactor: "./src/js/course-redactor.js"
courseRedactor: "./src/js/course-redactor.js",
mixpanel: "./src/js/third_party/mixpanel-2-latest.js"
},
output: {
path: path.join(__dirname, "build"),
@ -20,7 +21,7 @@ module.exports = {
loaders: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
exclude: /(node_modules|bower_components|third_party)/,
use: {
loader: 'babel-loader',
options: {
@ -28,6 +29,16 @@ module.exports = {
}
}
},
{
test: /third_party\/.*\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'file-loader',
options: {
name: "[name].[ext]"
}
}
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
@ -97,4 +108,4 @@ if (NODE_ENV === 'production') {
}
})
);
}
}

@ -168,7 +168,7 @@ anymatch@^1.3.0:
micromatch "^2.1.5"
normalize-path "^2.0.0"
aproba@^1.0.3:
aproba@^1.0.3, aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@ -260,7 +260,7 @@ arraybuffer.slice@~0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
arrify@^1.0.0:
arrify@^1.0.0, arrify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
@ -961,7 +961,7 @@ block-stream@*:
dependencies:
inherits "~2.0.0"
bluebird@^3.0.5, bluebird@^3.1.1:
bluebird@^3.0.5, bluebird@^3.1.1, bluebird@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
@ -1139,6 +1139,10 @@ bs-recipes@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/bs-recipes/-/bs-recipes-1.3.4.tgz#0d2d4d48a718c8c044769fdc4f89592dc8b69585"
buffer-from@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531"
buffer-xor@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
@ -1165,6 +1169,24 @@ builtin-status-codes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
cacache@^10.0.4:
version "10.0.4"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460"
dependencies:
bluebird "^3.5.1"
chownr "^1.0.1"
glob "^7.1.2"
graceful-fs "^4.1.11"
lru-cache "^4.1.1"
mississippi "^2.0.0"
mkdirp "^0.5.1"
move-concurrently "^1.0.1"
promise-inflight "^1.0.1"
rimraf "^2.6.2"
ssri "^5.2.4"
unique-filename "^1.1.0"
y18n "^4.0.0"
cache-base@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
@ -1323,6 +1345,10 @@ chokidar@1.7.0, chokidar@^1.7.0:
optionalDependencies:
fsevents "^1.0.0"
chownr@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@ -1503,6 +1529,15 @@ concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
concat-stream@^1.5.0:
version "1.6.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
dependencies:
buffer-from "^1.0.0"
inherits "^2.0.3"
readable-stream "^2.2.2"
typedarray "^0.0.6"
config-chain@~1.1.5:
version "1.1.11"
resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.11.tgz#aba09747dfbe4c3e70e766a6e41586e1859fc6f2"
@ -1562,10 +1597,34 @@ cookie@0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
copy-concurrently@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
dependencies:
aproba "^1.1.1"
fs-write-stream-atomic "^1.0.8"
iferr "^0.1.5"
mkdirp "^0.5.1"
rimraf "^2.5.4"
run-queue "^1.0.0"
copy-descriptor@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
copy-webpack-plugin@^4.5.1:
version "4.5.1"
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.5.1.tgz#fc4f68f4add837cc5e13d111b20715793225d29c"
dependencies:
cacache "^10.0.4"
find-cache-dir "^1.0.0"
globby "^7.1.1"
is-glob "^4.0.0"
loader-utils "^1.1.0"
minimatch "^3.0.4"
p-limit "^1.0.0"
serialize-javascript "^1.4.0"
core-js@^2.4.0, core-js@^2.5.0:
version "2.5.3"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
@ -1770,6 +1829,10 @@ currently-unhandled@^0.4.1:
dependencies:
array-find-index "^1.0.1"
cyclist@~0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
d@1:
version "1.0.0"
resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
@ -1946,6 +2009,13 @@ diffie-hellman@^5.0.0:
miller-rabin "^4.0.0"
randombytes "^2.0.0"
dir-glob@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034"
dependencies:
arrify "^1.0.1"
path-type "^3.0.0"
doctypes@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9"
@ -1999,6 +2069,15 @@ duplexer@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
duplexify@^3.4.2, duplexify@^3.5.3:
version "3.5.4"
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4"
dependencies:
end-of-stream "^1.0.0"
inherits "^2.0.1"
readable-stream "^2.0.0"
stream-shift "^1.0.0"
duplexify@^3.5.0:
version "3.5.3"
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e"
@ -2068,7 +2147,7 @@ encodeurl@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
end-of-stream@^1.0.0:
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
dependencies:
@ -2495,6 +2574,13 @@ flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
flush-write-stream@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd"
dependencies:
inherits "^2.0.1"
readable-stream "^2.0.4"
follow-redirects@^1.2.5:
version "1.4.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.4.1.tgz#d8120f4518190f55aac65bb6fc7b85fcd666d6aa"
@ -2559,6 +2645,13 @@ fresh@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
from2@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
dependencies:
inherits "^2.0.1"
readable-stream "^2.0.0"
from@~0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
@ -2577,6 +2670,15 @@ fs-extra@3.0.1:
jsonfile "^3.0.0"
universalify "^0.1.0"
fs-write-stream-atomic@^1.0.8:
version "1.0.10"
resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
dependencies:
graceful-fs "^4.1.2"
iferr "^0.1.5"
imurmurhash "^0.1.4"
readable-stream "1 || 2"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@ -2711,7 +2813,7 @@ glob@^5.0.12:
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@~7.1.1:
glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@~7.1.1:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
@ -2763,6 +2865,17 @@ globby@^5.0.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
globby@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680"
dependencies:
array-union "^1.0.1"
dir-glob "^2.0.0"
glob "^7.1.2"
ignore "^3.3.5"
pify "^3.0.0"
slash "^1.0.0"
globule@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09"
@ -2785,7 +2898,7 @@ glogg@^1.0.0:
dependencies:
sparkles "^1.0.0"
graceful-fs@4.X, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
graceful-fs@4.X, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
@ -3294,6 +3407,14 @@ ieee754@^1.1.4:
version "1.1.8"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
iferr@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
ignore@^3.3.5:
version "3.3.7"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021"
ilyabirman-likely@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/ilyabirman-likely/-/ilyabirman-likely-2.3.0.tgz#4462becc5dedeb36b74bf4ba339a0ceab820785f"
@ -3302,6 +3423,10 @@ immutable@3.8.2, immutable@^3.7.6:
version "3.8.2"
resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3"
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
in-publish@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51"
@ -3474,7 +3599,7 @@ is-extglob@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
is-extglob@^2.1.0:
is-extglob@^2.1.0, is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@ -3506,6 +3631,12 @@ is-glob@^3.1.0:
dependencies:
is-extglob "^2.1.0"
is-glob@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0"
dependencies:
is-extglob "^2.1.1"
is-number-like@^1.0.3:
version "1.0.8"
resolved "https://registry.yarnpkg.com/is-number-like/-/is-number-like-1.0.8.tgz#2e129620b50891042e44e9bbbb30593e75cfbbe3"
@ -4411,6 +4542,21 @@ minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
mississippi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f"
dependencies:
concat-stream "^1.5.0"
duplexify "^3.4.2"
end-of-stream "^1.1.0"
flush-write-stream "^1.0.0"
from2 "^2.1.0"
parallel-transform "^1.1.0"
pump "^2.0.1"
pumpify "^1.3.3"
stream-each "^1.1.0"
through2 "^2.0.0"
mixin-deep@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.0.tgz#47a8732ba97799457c8c1eca28f95132d7e8150a"
@ -4435,6 +4581,17 @@ moment@^2.20.1:
version "2.20.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd"
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
dependencies:
aproba "^1.1.1"
copy-concurrently "^1.0.0"
fs-write-stream-atomic "^1.0.8"
mkdirp "^0.5.1"
rimraf "^2.5.4"
run-queue "^1.0.3"
ms@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
@ -4744,7 +4901,7 @@ on-finished@~2.3.0:
dependencies:
ee-first "1.1.1"
once@^1.3.0, once@^1.3.3, once@^1.4.0:
once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
@ -4822,7 +4979,7 @@ p-finally@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
p-limit@^1.1.0:
p-limit@^1.0.0, p-limit@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c"
dependencies:
@ -4842,6 +4999,14 @@ pako@~1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
parallel-transform@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06"
dependencies:
cyclist "~0.2.2"
inherits "^2.0.3"
readable-stream "^2.1.5"
parse-asn1@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712"
@ -4953,6 +5118,12 @@ path-type@^2.0.0:
dependencies:
pify "^2.0.0"
path-type@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
dependencies:
pify "^3.0.0"
pause-stream@0.0.11:
version "0.0.11"
resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
@ -5324,10 +5495,18 @@ process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
process@^0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
promise-inflight@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
promise@^7.0.1:
version "7.3.1"
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
@ -5449,6 +5628,21 @@ pug-walk@^1.1.5:
pug-runtime "^2.0.3"
pug-strip-comments "^1.0.2"
pump@^2.0.0, pump@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
pumpify@^1.3.3:
version "1.4.0"
resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb"
dependencies:
duplexify "^3.5.3"
inherits "^2.0.3"
pump "^2.0.0"
punycode@1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
@ -5551,6 +5745,18 @@ read-pkg@^2.0.0:
normalize-package-data "^2.3.2"
path-type "^2.0.0"
"readable-stream@1 || 2", readable-stream@^2.0.4, readable-stream@^2.2.2:
version "2.3.5"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.0.3"
util-deprecate "~1.0.1"
"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.17:
version "1.0.34"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
@ -5811,7 +6017,7 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1:
rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
@ -5824,6 +6030,12 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
hash-base "^2.0.0"
inherits "^2.0.1"
run-queue@^1.0.0, run-queue@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
dependencies:
aproba "^1.1.1"
run-sequence@^1.1.5:
version "1.2.2"
resolved "https://registry.yarnpkg.com/run-sequence/-/run-sequence-1.2.2.tgz#5095a0bebe98733b0140bd08dd80ec030ddacdeb"
@ -5916,6 +6128,10 @@ sequencify@~0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c"
serialize-javascript@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005"
serve-index@1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.8.0.tgz#7c5d96c13fb131101f93c1c5774f8516a1e78d3b"
@ -6226,6 +6442,12 @@ sshpk@^1.7.0:
jsbn "~0.1.0"
tweetnacl "~0.14.0"
ssri@^5.2.4:
version "5.3.0"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06"
dependencies:
safe-buffer "^5.1.1"
static-extend@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
@ -6258,6 +6480,13 @@ stream-consume@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f"
stream-each@^1.1.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd"
dependencies:
end-of-stream "^1.1.0"
stream-shift "^1.0.0"
stream-http@^2.7.2:
version "2.8.0"
resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.0.tgz#fd86546dac9b1c91aff8fc5d287b98fafb41bc10"
@ -6563,6 +6792,10 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
ua-parser-js@0.7.12:
version "0.7.12"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb"
@ -6623,6 +6856,18 @@ uniqs@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02"
unique-filename@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3"
dependencies:
unique-slug "^2.0.0"
unique-slug@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab"
dependencies:
imurmurhash "^0.1.4"
unique-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b"
@ -6988,6 +7233,10 @@ y18n@^3.2.0, y18n@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
y18n@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"

Loading…
Cancel
Save