├── requirements.txt ├── awesome_avatar ├── models.py ├── __init__.py ├── static │ ├── imgareaselect │ │ ├── css │ │ │ ├── border-h.gif │ │ │ ├── border-v.gif │ │ │ ├── border-anim-h.gif │ │ │ ├── border-anim-v.gif │ │ │ ├── imgareaselect-deprecated.css │ │ │ ├── imgareaselect-default.css │ │ │ └── imgareaselect-animated.css │ │ ├── MIT-LICENSE.txt │ │ ├── scripts │ │ │ ├── jquery.imgareaselect.pack.js │ │ │ ├── jquery.imgareaselect.min.js │ │ │ ├── jquery.imgareaselect.js │ │ │ └── jquery.min.js │ │ └── GPL-LICENSE.txt │ └── awesome_avatar │ │ ├── awesome-avatar.css │ │ └── awesome-avatar.js ├── settings.py ├── forms.py ├── widgets.py ├── templates │ └── awesome_avatar │ │ └── widget.html └── fields.py ├── .gitignore ├── setup.py └── README.rst /requirements.txt: -------------------------------------------------------------------------------- 1 | Django -------------------------------------------------------------------------------- /awesome_avatar/models.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /awesome_avatar/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'dimka' 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.egg-info/ 2 | *.pyc 3 | 4 | .idea/ 5 | build/ 6 | dist/ 7 | MANIFEST 8 | -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/css/border-h.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voronind/django-awesome-avatar/HEAD/awesome_avatar/static/imgareaselect/css/border-h.gif -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/css/border-v.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voronind/django-awesome-avatar/HEAD/awesome_avatar/static/imgareaselect/css/border-v.gif -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/css/border-anim-h.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voronind/django-awesome-avatar/HEAD/awesome_avatar/static/imgareaselect/css/border-anim-h.gif -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/css/border-anim-v.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voronind/django-awesome-avatar/HEAD/awesome_avatar/static/imgareaselect/css/border-anim-v.gif -------------------------------------------------------------------------------- /awesome_avatar/static/awesome_avatar/awesome-avatar.css: -------------------------------------------------------------------------------- 1 | 2 | .awesome-avatar-select-area { 3 | border: 1px solid #ddd; 4 | box-sizing: content-box; 5 | display: table-cell; 6 | vertical-align: middle; 7 | text-align: center; 8 | } 9 | 10 | .awesome-avatar-input { 11 | width: 100%; 12 | margin-top: 6px; 13 | } 14 | 15 | .awesome-avatar-preview { 16 | margin-right: 20px; 17 | border: 1px solid #ddd; 18 | box-sizing: content-box; 19 | overflow: hidden; 20 | } -------------------------------------------------------------------------------- /awesome_avatar/settings.py: -------------------------------------------------------------------------------- 1 | 2 | from django.conf import settings 3 | 4 | 5 | class config(object): 6 | width = 100 7 | height = 100 8 | 9 | upload_to = 'avatars' 10 | save_format = 'png' 11 | save_quality = 90 12 | 13 | select_area_width = 400 14 | select_area_height = 250 15 | 16 | 17 | settings_config = getattr(settings, 'AWESOME_AVATAR', {}) 18 | 19 | for key, value in settings_config.items(): 20 | if key in config.__dict__: 21 | setattr(config, key, value) 22 | else: 23 | raise KeyError('Incorect option name of AWESOME_AVATAR in settings.py ({})'.format(key)) -------------------------------------------------------------------------------- /awesome_avatar/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | from awesome_avatar.settings import config 4 | from awesome_avatar.widgets import AvatarWidget 5 | 6 | 7 | class AvatarField(forms.ImageField): 8 | widget = AvatarWidget 9 | 10 | def __init__(self, **defaults): 11 | self.width = defaults.pop('width', config.width) 12 | self.height = defaults.pop('height', config.height) 13 | super(AvatarField, self).__init__(**defaults) 14 | 15 | def to_python(self, data): 16 | super(AvatarField, self).to_python(data['file']) 17 | return data 18 | 19 | def widget_attrs(self, widget): 20 | return {'width': self.width, 'height': self.height} -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/css/imgareaselect-deprecated.css: -------------------------------------------------------------------------------- 1 | /* 2 | * imgAreaSelect style to be used with deprecated options 3 | */ 4 | 5 | .imgareaselect-border1, .imgareaselect-border2, 6 | .imgareaselect-border3, .imgareaselect-border4 { 7 | filter: alpha(opacity=50); 8 | opacity: 0.5; 9 | } 10 | 11 | .imgareaselect-border1 { 12 | border: solid 1px #000; 13 | } 14 | 15 | .imgareaselect-border2 { 16 | border: dashed 1px #fff; 17 | } 18 | 19 | .imgareaselect-handle { 20 | background-color: #fff; 21 | border: solid 1px #000; 22 | filter: alpha(opacity=50); 23 | opacity: 0.5; 24 | } 25 | 26 | .imgareaselect-outer { 27 | background-color: #000; 28 | filter: alpha(opacity=40); 29 | opacity: 0.4; 30 | } 31 | 32 | .imgareaselect-selection { 33 | background-color: #fff; 34 | filter: alpha(opacity=0); 35 | opacity: 0; 36 | } 37 | -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/css/imgareaselect-default.css: -------------------------------------------------------------------------------- 1 | /* 2 | * imgAreaSelect default style 3 | */ 4 | 5 | .imgareaselect-border1 { 6 | background: url(border-v.gif) repeat-y left top; 7 | } 8 | 9 | .imgareaselect-border2 { 10 | background: url(border-h.gif) repeat-x left top; 11 | } 12 | 13 | .imgareaselect-border3 { 14 | background: url(border-v.gif) repeat-y right top; 15 | } 16 | 17 | .imgareaselect-border4 { 18 | background: url(border-h.gif) repeat-x left bottom; 19 | } 20 | 21 | .imgareaselect-border1, .imgareaselect-border2, 22 | .imgareaselect-border3, .imgareaselect-border4 { 23 | filter: alpha(opacity=50); 24 | opacity: 0.5; 25 | } 26 | 27 | .imgareaselect-handle { 28 | background-color: #fff; 29 | border: solid 1px #000; 30 | filter: alpha(opacity=50); 31 | opacity: 0.5; 32 | } 33 | 34 | .imgareaselect-outer { 35 | background-color: #000; 36 | filter: alpha(opacity=50); 37 | opacity: 0.5; 38 | } 39 | 40 | .imgareaselect-selection { 41 | } -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/css/imgareaselect-animated.css: -------------------------------------------------------------------------------- 1 | /* 2 | * imgAreaSelect animated border style 3 | */ 4 | 5 | .imgareaselect-border1 { 6 | background: url(border-anim-v.gif) repeat-y left top; 7 | } 8 | 9 | .imgareaselect-border2 { 10 | background: url(border-anim-h.gif) repeat-x left top; 11 | } 12 | 13 | .imgareaselect-border3 { 14 | background: url(border-anim-v.gif) repeat-y right top; 15 | } 16 | 17 | .imgareaselect-border4 { 18 | background: url(border-anim-h.gif) repeat-x left bottom; 19 | } 20 | 21 | .imgareaselect-border1, .imgareaselect-border2, 22 | .imgareaselect-border3, .imgareaselect-border4 { 23 | filter: alpha(opacity=50); 24 | opacity: 0.5; 25 | } 26 | 27 | .imgareaselect-handle { 28 | background-color: #fff; 29 | border: solid 1px #000; 30 | filter: alpha(opacity=50); 31 | opacity: 0.5; 32 | } 33 | 34 | .imgareaselect-outer { 35 | background-color: #000; 36 | filter: alpha(opacity=50); 37 | opacity: 0.5; 38 | } 39 | 40 | .imgareaselect-selection { 41 | } -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2013 Michal Wojciechowski, http://odyniec.net/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | import os 3 | 4 | name = 'django-awesome-avatar' 5 | package = 'awesome_avatar' 6 | version = '1.1.3' 7 | 8 | url = 'https://github.com/dimka665/django-awesome-avatar' 9 | author = 'Dmitry Voronin' 10 | author_email = 'dimka665@gmail.com' 11 | license_ = 'BSD' 12 | description = 'Django Avatar field' 13 | long_description = open('README.rst').read() 14 | 15 | 16 | def get_packages(package): 17 | """ 18 | Return root package and all sub-packages. 19 | """ 20 | return [dirpath for dirpath, dirnames, filenames in os.walk(package) 21 | if os.path.exists(os.path.join(dirpath, '__init__.py'))] 22 | 23 | 24 | def get_package_data(package): 25 | """ 26 | Return all files under the root package, that are not in a 27 | package themselves. 28 | """ 29 | walk = [(dirpath.replace(package + os.sep, '', 1), filenames) 30 | for dirpath, dirnames, filenames in os.walk(package) 31 | if not os.path.exists(os.path.join(dirpath, '__init__.py'))] 32 | 33 | filepaths = [] 34 | for base, filenames in walk: 35 | filepaths.extend([os.path.join(base, filename) 36 | for filename in filenames]) 37 | return {package: filepaths} 38 | 39 | 40 | setup( 41 | name=name, 42 | version=version, 43 | url=url, 44 | license=license_, 45 | description=description, 46 | long_description=long_description, 47 | author=author, 48 | author_email=author_email, 49 | packages=get_packages(package), 50 | package_data=get_package_data(package), 51 | ) 52 | 53 | 54 | -------------------------------------------------------------------------------- /awesome_avatar/widgets.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.forms import FileInput 3 | from django.template.loader import render_to_string 4 | 5 | from awesome_avatar.settings import config 6 | 7 | 8 | class AvatarWidget(FileInput): 9 | 10 | def value_from_datadict(self, data, files, name): 11 | value = {} 12 | value['file'] = super(AvatarWidget, self).value_from_datadict(data, files, name) 13 | 14 | x1 = data.get(name + '-x1', 0) 15 | y1 = data.get(name + '-y1', 0) 16 | x2 = data.get(name + '-x2', x1) 17 | y2 = data.get(name + '-y2', y1) 18 | ratio = data.get(name + '-ratio', 1) 19 | ratio = float(1 if not ratio else ratio) 20 | 21 | box_raw = [x1, y1, x2, y2] 22 | box = [] 23 | 24 | for coord in box_raw: 25 | try: 26 | coord = int(coord) 27 | except ValueError: 28 | coord = 0 29 | 30 | if ratio > 1: 31 | coord = int(coord * ratio) 32 | box.append(coord) 33 | 34 | value['box'] = box 35 | return value 36 | 37 | def render(self, name, value, attrs=None): 38 | 39 | config.height = self.attrs['height'] 40 | config.width = self.attrs['width'] 41 | 42 | context = {} 43 | context['name'] = name 44 | context['config'] = config 45 | 46 | context['avatar_url'] = value.url if value else '/static/awesome_avatar/default.png' 47 | context['id'] = attrs.get('id', 'id_' + name) 48 | # todo fix HACK 49 | context['STATIC_URL'] = settings.STATIC_URL 50 | return render_to_string('awesome_avatar/widget.html', context) 51 | -------------------------------------------------------------------------------- /awesome_avatar/templates/awesome_avatar/widget.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 24 | 31 | 32 |
19 |
21 | 22 |
23 |
25 |
27 | 28 |
29 | 30 |
33 | 41 |
42 | -------------------------------------------------------------------------------- /awesome_avatar/fields.py: -------------------------------------------------------------------------------- 1 | import os 2 | from awesome_avatar.settings import config 3 | from django.core.files.uploadedfile import InMemoryUploadedFile 4 | from django.db import models 5 | from awesome_avatar import forms 6 | 7 | try: 8 | from cStringIO import StringIO 9 | except ImportError: 10 | from StringIO import StringIO 11 | 12 | try: 13 | from PIL import Image 14 | except ImportError: 15 | import Image 16 | 17 | try: 18 | from south.modelsinspector import add_introspection_rules 19 | add_introspection_rules([], ['^awesome_avatar\.fields\.AvatarField']) 20 | except ImportError: 21 | pass 22 | 23 | 24 | class AvatarField(models.ImageField): 25 | def __init__(self, *args, **kwargs): 26 | 27 | self.width = kwargs.pop('width', config.width) 28 | self.height = kwargs.pop('height', config.height) 29 | 30 | kwargs['upload_to'] = kwargs.get('upload_to', config.upload_to) 31 | 32 | super(AvatarField, self).__init__(*args, **kwargs) 33 | 34 | def formfield(self, **kwargs): 35 | defaults = {'form_class': forms.AvatarField} 36 | defaults['width'] = self.width 37 | defaults['height'] = self.height 38 | defaults.update(kwargs) 39 | return super(AvatarField, self).formfield(**defaults) 40 | 41 | def save_form_data(self, instance, data): 42 | # if data and self.width and self.height: 43 | file_ = data['file'] 44 | if file_: 45 | 46 | image = Image.open(StringIO(file_.read())) 47 | image = image.crop(data['box']) 48 | image = image.resize((self.width, self.height), Image.ANTIALIAS) 49 | 50 | content = StringIO() 51 | image.save(content, config.save_format, quality=config.save_quality) 52 | 53 | file_name = u'{}.{}'.format(os.path.splitext(file_.name)[0], config.save_format) 54 | 55 | # new_data = SimpleUploadedFile(file.name, content.getvalue(), content_type='image/' + config.save_format) 56 | new_data = InMemoryUploadedFile(content, None, file_name, 'image/' + config.save_format, len(content.getvalue()), None) 57 | super(AvatarField, self).save_form_data(instance, new_data) 58 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | django-awesome-avatar 3 | ===================== 4 | 5 | Django-awesome-avatar is a reusable application providing Avatar model field. 6 | It allows crop selected area before saving image. 7 | 8 | Purpose 9 | ======= 10 | 11 | | Unlike django-avatar_ and django-upload-avatar_ 12 | | django-awesome-avatar_ uses: 13 | 14 | - field in profile model instead creating model for saving images 15 | - HTML5 File API instead hidden iframe AJAX for image preview 16 | - easy customizable presence (any view and widget templates) 17 | 18 | Install 19 | ======= 20 | 21 | To integrate ``django-awesome-avatar`` with your site, there are few things 22 | that are required: 23 | 24 | #. Installing:: 25 | 26 | pip install django-awesome-avatar 27 | 28 | #. List this application in the ``INSTALLED_APPS`` portion of your settings file. 29 | Your settings file will look something like:: 30 | 31 | INSTALLED_APPS = ( 32 | ... 33 | 'awesome_avatar', 34 | ) 35 | 36 | Usage examples 37 | ============== 38 | 39 | with ModelForm 40 | -------------- 41 | 42 | Add the ``AvatarField`` to your user or profile model:: 43 | 44 | from awesome_avatar.fields import AvatarField 45 | 46 | class Profile(Model): 47 | user = OneToOneField(User, related_name='profile') 48 | ... 49 | avatar = AvatarField(upload_to='avatars', width=100, height=100) 50 | 51 | Use model form usually way:: 52 | 53 | class AvatarChangeForm(ModelForm): 54 | class Meta: 55 | model = Profile 56 | fields = ['avatar'] 57 | 58 | def change_avatar(request): 59 | if request.method == 'POST': 60 | form = AvatarChangeForm(request.POST, request.FILES, 61 | instance=request.user.profile) 62 | if form.is_valid(): 63 | form.save() 64 | return HttpResponseRedirect('/profile/') 65 | else: 66 | form = AvatarChangeForm(instance=request.user.profile) 67 | 68 | return render(request, 'template.html', {'form': form}) 69 | 70 | with Form 71 | --------- 72 | 73 | Define some model for saving images:: 74 | 75 | class Images(Model): 76 | image = ImageField(upload_to='images') 77 | 78 | Use form field for cropping image:: 79 | 80 | from awesome_avatar import forms as avatar_forms 81 | 82 | class UploadAndCropImageForm(Form): 83 | image = avatar_forms.AvatarField() 84 | 85 | def upload_and_crop_image(request): 86 | if request.method == 'POST': 87 | form = UploadAndCropImageForm(request.POST) 88 | 89 | if form.is_valid(): 90 | Images(image=form.image).save() 91 | return HttpResponseRedirect('/any/') 92 | else: 93 | form = UploadAndCropImageForm() 94 | 95 | return render(request, 'template.html', {'form': form}) 96 | 97 | 98 | Global Settings 99 | =============== 100 | 101 | Django's ``settings.py``:: 102 | 103 | AWESOME_AVATAR = { 104 | 'width': 100, 105 | 'height': 100, 106 | 107 | 'select_area_width': 400, 108 | 'select_area_height': 300, 109 | 110 | 'save_quality': 90, 111 | 'save_format': 'png', 112 | ... 113 | } 114 | 115 | .. _django-avatar: https://github.com/jezdez/django-avatar 116 | .. _django-upload-avatar: https://github.com/yueyoum/django-upload-avatar 117 | .. _django-awesome-avatar: https://github.com/dimka665/django-awesome-avatar 118 | -------------------------------------------------------------------------------- /awesome_avatar/static/awesome_avatar/awesome-avatar.js: -------------------------------------------------------------------------------- 1 | (function($){ 2 | bind_on_change_input_file = function(selector, config) { 3 | 4 | $(selector).change(function() { 5 | if($(this).val() == '') { 6 | return; 7 | } 8 | 9 | // if selection, remove 10 | var $last_img = $(selector + '-select-area img'); 11 | if ($last_img.length) { 12 | var img_obj = $last_img.imgAreaSelect({instance: true}); 13 | img_obj.remove(); 14 | } 15 | 16 | $(selector + '-select-area').empty(); 17 | // $(selector + '-select-area img').hide(); 18 | // $(selector + '-preview').empty(); 19 | $(selector + '-preview img').hide(); 20 | 21 | var p = new RegExp(/\.(jpg|jpeg|png|gif)$/); 22 | var fileanme = $(this).val().toLowerCase().replace(/^\s+|\s+$/g, ''); 23 | if(!p.test(fileanme)){ 24 | alert('{% trans "Неверный формат. Выберите изображение" %}'); 25 | return ; 26 | } 27 | 28 | var file = this.files[0]; 29 | if (!file.type.match(/image.*/)) { 30 | return; 31 | } 32 | var reader = new FileReader(); 33 | reader.onload = bind_preview.bind(null, selector, config); 34 | reader.readAsDataURL(file); 35 | }); 36 | }; 37 | 38 | bind_preview = function(selector, config, e) { 39 | var image_data = e.target.result; 40 | // $(selector + '-preview').empty(); 41 | // $(selector + '-preview').append(''); 42 | $(selector + '-preview img').show(); 43 | $(selector + '-preview img').css('max-width', 'none'); 44 | $(selector + '-preview img').attr('src', image_data); 45 | 46 | $(selector + '-select-area').empty(); 47 | $(selector + '-select-area').append(''); 48 | // $(selector + '-select-area img').show(); 49 | $(selector + '-select-area img').attr('src', image_data).load(function(){ 50 | $(this).unbind('load'); 51 | 52 | var img_width = $(this).width(); 53 | var img_height = $(this).height(); 54 | 55 | var ratio_x = img_width / config.select_area_width; 56 | var ratio_y = img_height / config.select_area_height; 57 | 58 | if (ratio_x > 1 || ratio_y > 1) { 59 | if (ratio_x > ratio_y) { 60 | $(this).css('width', config.select_area_width + 'px'); 61 | $(selector + '-ratio').val(ratio_x); 62 | } 63 | else { 64 | $(this).css('height', config.select_area_height + 'px'); 65 | $(selector + '-ratio').val(ratio_y); 66 | } 67 | } else { 68 | $(selector + '-ratio').val(1); 69 | } 70 | 71 | img_width = $(this).width(); 72 | img_height = $(this).height(); 73 | 74 | $(selector + '-width').val(ratio_x); 75 | $(selector + '-height').val(ratio_y); 76 | 77 | var sel = {}; 78 | sel['x1'] = Math.round(img_width/2-25 > 0 ? img_width/2-25 : 0), 79 | sel['y1'] = Math.round(img_height/2-25 > 0 ? img_height/2-25 : 0), 80 | sel['x2'] = Math.round(img_width/2+25 > img_width ? img_width : img_width/2+25), 81 | sel['y2'] = Math.round(img_height/2+25 > img_height ? img_height : img_height/2+25), 82 | sel['width'] = 50; 83 | 84 | $(this).imgAreaSelect({ 85 | // handles: true, 86 | aspectRatio: config.width + ":" + config.height, 87 | fadeSpeed: 100, 88 | // minHeight: 50, 89 | // minWidth: 50, 90 | x1: sel.x1, 91 | y1: sel.y1, 92 | x2: sel.x2, 93 | y2: sel.y2, 94 | onSelectChange: update_coors.bind(null, selector, config) 95 | }); 96 | 97 | update_coors(selector, config, {'width': img_width}, sel); 98 | })(); 99 | }; 100 | 101 | update_coors = function(selector, config, img, selection) { 102 | $(selector + "-x1").val(selection.x1); 103 | $(selector + "-y1").val(selection.y1); 104 | $(selector + "-x2").val(selection.x2); 105 | $(selector + "-y2").val(selection.y2); 106 | 107 | if (parseInt(selection.width) > 0) { 108 | var ratiox = config.width / (selection.width || 1); 109 | var ratioy = config.height / (selection.height || 1); 110 | 111 | $(selector + '-preview img').css({ 112 | width: Math.round(ratiox * img.width) + 'px', 113 | height: Math.round(ratioy * img.height) + 'px', 114 | marginLeft: '-' + Math.round(ratiox * selection.x1) + 'px', 115 | marginTop: '-' + Math.round(ratiox * selection.y1) + 'px' 116 | }); 117 | } 118 | }; 119 | })(typeof(jQuery) != 'undefined' ? jQuery : django.jQuery); -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/scripts/jquery.imgareaselect.pack.js: -------------------------------------------------------------------------------- 1 | eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(q($){1a V=2m.V,G=2m.G,H=2m.H,A=2m.A;q W(){J $(\'\')}$.P=q(v,9){1a $v=$(v),1W,$F=W(),$1m=W(),$I=W().B(W()).B(W()).B(W()),$C=W().B(W()).B(W()).B(W()),$D=$([]),$1V,m,l,16={m:0,l:0},R,N,$Z,1e={m:0,l:0},S=0,11=\'1U\',2c,28,1y,1A,E,1k,1j,1R,1Q,12,1P,b,c,j,g,f={b:0,c:0,j:0,g:0,K:0,O:0},2n=T.4f,1X=4a.3Q,$p,d,i,o,w,h,2b;q 1l(x){J x+16.m-1e.m}q 1n(y){J y+16.l-1e.l}q 18(x){J x-16.m+1e.m}q 19(y){J y-16.l+1e.l}q 1p(u){J u.3L-1e.m}q 1B(u){J u.3K-1e.l}q 14(1w){1a 1i=1w||1y,1f=1w||1A;J{b:A(f.b*1i),c:A(f.c*1f),j:A(f.j*1i),g:A(f.g*1f),K:A(f.j*1i)-A(f.b*1i),O:A(f.g*1f)-A(f.c*1f)}}q 1D(b,c,j,g,1w){1a 1i=1w||1y,1f=1w||1A;f={b:A(b/1i||0),c:A(c/1f||0),j:A(j/1i||0),g:A(g/1f||0)};f.K=f.j-f.b;f.O=f.g-f.c}q 1h(){a(!1W||!$v.K())J;16={m:A($v.2g().m),l:A($v.2g().l)};R=$v.2p();N=$v.3k();16.l+=($v.2A()-N)>>1;16.m+=($v.1Z()-R)>>1;1k=A(9.1k/1y)||0;1j=A(9.1j/1A)||0;1R=A(H(9.1R/1y||1<<24,R));1Q=A(H(9.1Q/1A||1<<24,N));a($().3w==\'1.3.2\'&&11==\'2i\'&&!2n[\'3q\']){16.l+=G(T.1z.1Y,2n.1Y);16.m+=G(T.1z.2h,2n.2h)}1e=/1U|3r/.1g($Z.r(\'11\'))?{m:A($Z.2g().m)-$Z.2h(),l:A($Z.2g().l)-$Z.1Y()}:11==\'2i\'?{m:$(T).2h(),l:$(T).1Y()}:{m:0,l:0};m=1l(0);l=1n(0);a(f.j>R||f.g>N)1M()}q 1x(2l){a(!1P)J;$F.r({m:1l(f.b),l:1n(f.c)}).B($1m).K(w=f.K).O(h=f.O);$1m.B($I).B($D).r({m:0,l:0});$I.K(G(w-$I.1Z()+$I.2p(),0)).O(G(h-$I.2A()+$I.3k(),0));$($C[0]).r({m:m,l:l,K:f.b,O:N});$($C[1]).r({m:m+f.b,l:l,K:w,O:f.c});$($C[2]).r({m:m+f.j,l:l,K:R-f.j,O:N});$($C[3]).r({m:m+f.b,l:l+f.g,K:w,O:N-f.g});w-=$D.1Z();h-=$D.2A();2L($D.3c){17 8:$($D[4]).r({m:w>>1});$($D[5]).r({m:w,l:h>>1});$($D[6]).r({m:w>>1,l:h});$($D[7]).r({l:h>>1});17 4:$D.2Q(1,3).r({m:w});$D.2Q(2,4).r({l:h})}a(2l!==X){a($.P.2C!=2D)$(T).U($.P.2F,$.P.2C);a(9.1F)$(T)[$.P.2F]($.P.2C=2D)}a(1b&&$I.1Z()-$I.2p()==2){$I.r(\'34\',0);33(q(){$I.r(\'34\',\'3s\')},0)}}q 27(2l){1h();1x(2l);b=1l(f.b);c=1n(f.c);j=1l(f.j);g=1n(f.g)}q 15($1I,2v){9.1J?$1I.48(9.1J,2v):$1I.15()}q 1c(u){1a x=18(1p(u))-f.b,y=19(1B(u))-f.c;a(!2b){1h();2b=13;$F.1N(\'3I\',q(){2b=X})}E=\'\';a(9.2E){a(y<=9.1O)E=\'n\';Y a(y>=f.O-9.1O)E=\'s\';a(x<=9.1O)E+=\'w\';Y a(x>=f.K-9.1O)E+=\'e\'}$F.r(\'2M\',E?E+\'-E\':9.23?\'3U\':\'\');a($1V)$1V.3H()}q 2r(u){$(\'1z\').r(\'2M\',\'\');a(9.3F||f.K*f.O==0)15($F.B($C),q(){$(M).15()});$(T).U(\'Q\',29);$F.Q(1c);9.2a(v,14())}q 2w(u){a(u.2X!=1)J X;1h();a(E){$(\'1z\').r(\'2M\',E+\'-E\');b=1l(f[/w/.1g(E)?\'j\':\'b\']);c=1n(f[/n/.1g(E)?\'g\':\'c\']);$(T).Q(29).1N(\'1u\',2r);$F.U(\'Q\',1c)}Y a(9.23){2c=m+f.b-1p(u);28=l+f.c-1B(u);$F.U(\'Q\',1c);$(T).Q(2y).1N(\'1u\',q(){9.2a(v,14());$(T).U(\'Q\',2y);$F.Q(1c)})}Y $v.1T(u);J X}q 1t(2W){a(12)a(2W){j=G(m,H(m+R,b+V(g-c)*12*(j>b||-1)));g=A(G(l,H(l+N,c+V(j-b)/12*(g>c||-1))));j=A(j)}Y{g=G(l,H(l+N,c+V(j-b)/12*(g>c||-1)));j=A(G(m,H(m+R,b+V(g-c)*12*(j>b||-1))));g=A(g)}}q 1M(){b=H(b,m+R);c=H(c,l+N);a(V(j-b)<1k){j=b-1k*(jm+R)b=m+R-1k}a(V(g-c)<1j){g=c-1j*(gl+N)c=l+N-1j}j=G(m,H(j,m+R));g=G(l,H(g,l+N));1t(V(j-b)1R){j=b-1R*(j1Q){g=c-1Q*(g=0)$D.K(5).O(5);a(o=9.2o)$D.r({2o:o,2u:\'3d\'});1K($D,{3e:\'I-2d\',3f:\'2t-2d\',3g:\'1d\'})}1y=9.3z/R||1;1A=9.3A/N||1;a(L.b!=36){1D(L.b,L.c,L.j,L.g);L.2G=!L.15}a(L.1F)9.1F=$.2j({22:1,25:\'E\'},L.1F);$C.20(9.1C+\'-C\');$1m.20(9.1C+\'-f\');32(i=0;i++<4;)$($I[i-1]).20(9.1C+\'-I\'+i);1K($1m,{3B:\'2t-2d\',3C:\'1d\'});1K($I,{3g:\'1d\',2o:\'I-K\'});1K($C,{3D:\'2t-2d\',3E:\'1d\'});a(o=9.3e)$($I[0]).r({2u:\'3d\',3h:o});a(o=9.3f)$($I[1]).r({2u:\'3G\',3h:o});$F.2x($1m.B($I).B($1V)).2x($D);a(1b){a(o=($C.r(\'3i\')||\'\').3j(/1d=(\\d+)/))$C.r(\'1d\',o[1]/2e);a(o=($I.r(\'3i\')||\'\').3j(/1d=(\\d+)/))$I.r(\'1d\',o[1]/2e)}a(L.15)15($F.B($C));Y a(L.2G&&1W){1P=13;$F.B($C).2K(9.1J||0);27()}12=(d=(9.12||\'\').3J(/:/))[0]/d[1];$v.B($C).U(\'1T\',2O);a(9.1E||9.1G===X){$F.U(\'Q\',1c).U(\'1T\',2w);$(3l).U(\'E\',2P)}Y{a(9.1G||9.1E===X){a(9.2E||9.23)$F.Q(1c).1T(2w);$(3l).E(2P)}a(!9.3N)$v.B($C).1T(2O)}9.1G=9.1E=1H}M.1s=q(){1v({1E:13});$F.B($C).1s()};M.3O=q(){J 9};M.1v=1v;M.14=14;M.1D=1D;M.1r=1r;M.1x=27;1a 1b=(/1b ([\\w.]+)/i.3P(1X)||[])[1],2z=/2z/i.1g(1X),3m=/3S/i.1g(1X)&&!/3T/i.1g(1X);$p=$v;3a($p.3c){S=G(S,!1S($p.r(\'z-3n\'))?$p.r(\'z-3n\'):S);a($p.r(\'11\')==\'2i\')11=\'2i\';$p=$p.Z(\':3W(1z)\')}S=9.S||S;a(1b)$v.3X(\'3Y\',\'3Z\');$.P.2F=1b||3m?\'41\':\'42\';a(2z)$1V=W().r({K:\'2e%\',O:\'2e%\',11:\'1U\',S:S+2||2});$F.B($C).r({2T:\'3o\',11:11,44:\'3o\',S:S||\'0\'});$F.r({S:S+2||2});$1m.B($I).r({11:\'1U\',3b:0});v.3p||v.46==\'3p\'||!$v.2I(\'v\')?2N():$v.1N(\'47\',2N);a(!1W&&1b&&1b>=7)v.2R=v.2R};$.2v.P=q(9){9=9||{};M.49(q(){a($(M).1L(\'P\')){a(9.1s){$(M).1L(\'P\').1s();$(M).4b(\'P\')}Y $(M).1L(\'P\').1v(9)}Y a(!9.1s){a(9.1G===1H&&9.1E===1H)9.1G=13;$(M).1L(\'P\',4c $.P(M,9))}});a(9.4d)J $(M).1L(\'P\');J M}})(4e(2H)!=\'1H\'?2H:4g.2H);',62,265,'|||||||||options|if|x1|y1|||selection|y2|||x2||top|left||||function|css|||event|img|||||round|add|outer|handles|resize|box|max|min|border|return|width|newOptions|this|imgHeight|height|imgAreaSelect|mousemove|imgWidth|zIndex|document|unbind|abs|div|false|else|parent||position|aspectRatio|true|getSelection|hide|imgOfs|case|selX|selY|var|msie|areaMouseMove|opacity|parOfs|sy|test|adjust|sx|minHeight|minWidth|viewX|area|viewY|break|evX|doMove|cancelSelection|remove|fixAspectRatio|mouseup|setOptions|noScale|update|scaleX|body|scaleY|evY|classPrefix|setSelection|disable|keys|enable|undefined|elem|fadeSpeed|styleOptions|data|doResize|one|resizeMargin|shown|maxHeight|maxWidth|isNaN|mousedown|absolute|areaOpera|imgLoaded|ua|scrollTop|outerWidth|addClass|option|shift|movable||ctrl|altKey|doUpdate|startY|selectingMouseMove|onSelectEnd|adjusted|startX|color|100|onSelectChange|offset|scrollLeft|fixed|extend|startSelection|resetKeyPress|Math|docElem|borderWidth|innerWidth|props|docMouseUp|alt|background|borderStyle|fn|areaMouseDown|append|movingMouseMove|opera|outerHeight|key|onKeyPress|docKeyPress|resizable|keyPress|show|jQuery|is|arrows|fadeIn|switch|cursor|imgLoad|imgMouseDown|windowResize|slice|src|onInit|visibility|newY1|newX1|xFirst|which|originalEvent|ctrlKey|shiftKey|default|for|setTimeout|margin|onSelectStart|null||||while|fontSize|length|solid|borderColor1|borderColor2|borderOpacity|borderColor|filter|match|innerHeight|window|safari|index|hidden|complete|getBoundingClientRect|relative|auto|imgareaselect|instanceof|keyCode|jquery|in|preventDefault|imageWidth|imageHeight|selectionColor|selectionOpacity|outerColor|outerOpacity|autoHide|dashed|toggle|mouseout|split|pageY|pageX|corners|persistent|getOptions|exec|userAgent|animated|webkit|chrome|move|handle|not|attr|unselectable|on||keydown|keypress|visible|overflow|parseInt|readyState|load|fadeOut|each|navigator|removeData|new|instance|typeof|documentElement|django'.split('|'),0,{})) -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/scripts/jquery.imgareaselect.min.js: -------------------------------------------------------------------------------- 1 | (function($){var abs=Math.abs,max=Math.max,min=Math.min,round=Math.round;function div(){return $('
')}$.imgAreaSelect=function(img,options){var $img=$(img),imgLoaded,$box=div(),$area=div(),$border=div().add(div()).add(div()).add(div()),$outer=div().add(div()).add(div()).add(div()),$handles=$([]),$areaOpera,left,top,imgOfs={left:0,top:0},imgWidth,imgHeight,$parent,parOfs={left:0,top:0},zIndex=0,position='absolute',startX,startY,scaleX,scaleY,resize,minWidth,minHeight,maxWidth,maxHeight,aspectRatio,shown,x1,y1,x2,y2,selection={x1:0,y1:0,x2:0,y2:0,width:0,height:0},docElem=document.documentElement,ua=navigator.userAgent,$p,d,i,o,w,h,adjusted;function viewX(x){return x+imgOfs.left-parOfs.left}function viewY(y){return y+imgOfs.top-parOfs.top}function selX(x){return x-imgOfs.left+parOfs.left}function selY(y){return y-imgOfs.top+parOfs.top}function evX(event){return event.pageX-parOfs.left}function evY(event){return event.pageY-parOfs.top}function getSelection(noScale){var sx=noScale||scaleX,sy=noScale||scaleY;return{x1:round(selection.x1*sx),y1:round(selection.y1*sy),x2:round(selection.x2*sx),y2:round(selection.y2*sy),width:round(selection.x2*sx)-round(selection.x1*sx),height:round(selection.y2*sy)-round(selection.y1*sy)}}function setSelection(x1,y1,x2,y2,noScale){var sx=noScale||scaleX,sy=noScale||scaleY;selection={x1:round(x1/sx||0),y1:round(y1/sy||0),x2:round(x2/sx||0),y2:round(y2/sy||0)};selection.width=selection.x2-selection.x1;selection.height=selection.y2-selection.y1}function adjust(){if(!imgLoaded||!$img.width())return;imgOfs={left:round($img.offset().left),top:round($img.offset().top)};imgWidth=$img.innerWidth();imgHeight=$img.innerHeight();imgOfs.top+=($img.outerHeight()-imgHeight)>>1;imgOfs.left+=($img.outerWidth()-imgWidth)>>1;minWidth=round(options.minWidth/scaleX)||0;minHeight=round(options.minHeight/scaleY)||0;maxWidth=round(min(options.maxWidth/scaleX||1<<24,imgWidth));maxHeight=round(min(options.maxHeight/scaleY||1<<24,imgHeight));if($().jquery=='1.3.2'&&position=='fixed'&&!docElem['getBoundingClientRect']){imgOfs.top+=max(document.body.scrollTop,docElem.scrollTop);imgOfs.left+=max(document.body.scrollLeft,docElem.scrollLeft)}parOfs=/absolute|relative/.test($parent.css('position'))?{left:round($parent.offset().left)-$parent.scrollLeft(),top:round($parent.offset().top)-$parent.scrollTop()}:position=='fixed'?{left:$(document).scrollLeft(),top:$(document).scrollTop()}:{left:0,top:0};left=viewX(0);top=viewY(0);if(selection.x2>imgWidth||selection.y2>imgHeight)doResize()}function update(resetKeyPress){if(!shown)return;$box.css({left:viewX(selection.x1),top:viewY(selection.y1)}).add($area).width(w=selection.width).height(h=selection.height);$area.add($border).add($handles).css({left:0,top:0});$border.width(max(w-$border.outerWidth()+$border.innerWidth(),0)).height(max(h-$border.outerHeight()+$border.innerHeight(),0));$($outer[0]).css({left:left,top:top,width:selection.x1,height:imgHeight});$($outer[1]).css({left:left+selection.x1,top:top,width:w,height:selection.y1});$($outer[2]).css({left:left+selection.x2,top:top,width:imgWidth-selection.x2,height:imgHeight});$($outer[3]).css({left:left+selection.x1,top:top+selection.y2,width:w,height:imgHeight-selection.y2});w-=$handles.outerWidth();h-=$handles.outerHeight();switch($handles.length){case 8:$($handles[4]).css({left:w>>1});$($handles[5]).css({left:w,top:h>>1});$($handles[6]).css({left:w>>1,top:h});$($handles[7]).css({top:h>>1});case 4:$handles.slice(1,3).css({left:w});$handles.slice(2,4).css({top:h})}if(resetKeyPress!==false){if($.imgAreaSelect.onKeyPress!=docKeyPress)$(document).unbind($.imgAreaSelect.keyPress,$.imgAreaSelect.onKeyPress);if(options.keys)$(document)[$.imgAreaSelect.keyPress]($.imgAreaSelect.onKeyPress=docKeyPress)}if(msie&&$border.outerWidth()-$border.innerWidth()==2){$border.css('margin',0);setTimeout(function(){$border.css('margin','auto')},0)}}function doUpdate(resetKeyPress){adjust();update(resetKeyPress);x1=viewX(selection.x1);y1=viewY(selection.y1);x2=viewX(selection.x2);y2=viewY(selection.y2)}function hide($elem,fn){options.fadeSpeed?$elem.fadeOut(options.fadeSpeed,fn):$elem.hide()}function areaMouseMove(event){var x=selX(evX(event))-selection.x1,y=selY(evY(event))-selection.y1;if(!adjusted){adjust();adjusted=true;$box.one('mouseout',function(){adjusted=false})}resize='';if(options.resizable){if(y<=options.resizeMargin)resize='n';else if(y>=selection.height-options.resizeMargin)resize='s';if(x<=options.resizeMargin)resize+='w';else if(x>=selection.width-options.resizeMargin)resize+='e'}$box.css('cursor',resize?resize+'-resize':options.movable?'move':'');if($areaOpera)$areaOpera.toggle()}function docMouseUp(event){$('body').css('cursor','');if(options.autoHide||selection.width*selection.height==0)hide($box.add($outer),function(){$(this).hide()});$(document).unbind('mousemove',selectingMouseMove);$box.mousemove(areaMouseMove);options.onSelectEnd(img,getSelection())}function areaMouseDown(event){if(event.which!=1)return false;adjust();if(resize){$('body').css('cursor',resize+'-resize');x1=viewX(selection[/w/.test(resize)?'x2':'x1']);y1=viewY(selection[/n/.test(resize)?'y2':'y1']);$(document).mousemove(selectingMouseMove).one('mouseup',docMouseUp);$box.unbind('mousemove',areaMouseMove)}else if(options.movable){startX=left+selection.x1-evX(event);startY=top+selection.y1-evY(event);$box.unbind('mousemove',areaMouseMove);$(document).mousemove(movingMouseMove).one('mouseup',function(){options.onSelectEnd(img,getSelection());$(document).unbind('mousemove',movingMouseMove);$box.mousemove(areaMouseMove)})}else $img.mousedown(event);return false}function fixAspectRatio(xFirst){if(aspectRatio)if(xFirst){x2=max(left,min(left+imgWidth,x1+abs(y2-y1)*aspectRatio*(x2>x1||-1)));y2=round(max(top,min(top+imgHeight,y1+abs(x2-x1)/aspectRatio*(y2>y1||-1))));x2=round(x2)}else{y2=max(top,min(top+imgHeight,y1+abs(x2-x1)/aspectRatio*(y2>y1||-1)));x2=round(max(left,min(left+imgWidth,x1+abs(y2-y1)*aspectRatio*(x2>x1||-1))));y2=round(y2)}}function doResize(){x1=min(x1,left+imgWidth);y1=min(y1,top+imgHeight);if(abs(x2-x1)left+imgWidth)x1=left+imgWidth-minWidth}if(abs(y2-y1)top+imgHeight)y1=top+imgHeight-minHeight}x2=max(left,min(x2,left+imgWidth));y2=max(top,min(y2,top+imgHeight));fixAspectRatio(abs(x2-x1)maxWidth){x2=x1-maxWidth*(x2maxHeight){y2=y1-maxHeight*(y2=0)$handles.width(5).height(5);if(o=options.borderWidth)$handles.css({borderWidth:o,borderStyle:'solid'});styleOptions($handles,{borderColor1:'border-color',borderColor2:'background-color',borderOpacity:'opacity'})}scaleX=options.imageWidth/imgWidth||1;scaleY=options.imageHeight/imgHeight||1;if(newOptions.x1!=null){setSelection(newOptions.x1,newOptions.y1,newOptions.x2,newOptions.y2);newOptions.show=!newOptions.hide}if(newOptions.keys)options.keys=$.extend({shift:1,ctrl:'resize'},newOptions.keys);$outer.addClass(options.classPrefix+'-outer');$area.addClass(options.classPrefix+'-selection');for(i=0;i++<4;)$($border[i-1]).addClass(options.classPrefix+'-border'+i);styleOptions($area,{selectionColor:'background-color',selectionOpacity:'opacity'});styleOptions($border,{borderOpacity:'opacity',borderWidth:'border-width'});styleOptions($outer,{outerColor:'background-color',outerOpacity:'opacity'});if(o=options.borderColor1)$($border[0]).css({borderStyle:'solid',borderColor:o});if(o=options.borderColor2)$($border[1]).css({borderStyle:'dashed',borderColor:o});$box.append($area.add($border).add($areaOpera)).append($handles);if(msie){if(o=($outer.css('filter')||'').match(/opacity=(\d+)/))$outer.css('opacity',o[1]/100);if(o=($border.css('filter')||'').match(/opacity=(\d+)/))$border.css('opacity',o[1]/100)}if(newOptions.hide)hide($box.add($outer));else if(newOptions.show&&imgLoaded){shown=true;$box.add($outer).fadeIn(options.fadeSpeed||0);doUpdate()}aspectRatio=(d=(options.aspectRatio||'').split(/:/))[0]/d[1];$img.add($outer).unbind('mousedown',imgMouseDown);if(options.disable||options.enable===false){$box.unbind('mousemove',areaMouseMove).unbind('mousedown',areaMouseDown);$(window).unbind('resize',windowResize)}else{if(options.enable||options.disable===false){if(options.resizable||options.movable)$box.mousemove(areaMouseMove).mousedown(areaMouseDown);$(window).resize(windowResize)}if(!options.persistent)$img.add($outer).mousedown(imgMouseDown)}options.enable=options.disable=undefined}this.remove=function(){setOptions({disable:true});$box.add($outer).remove()};this.getOptions=function(){return options};this.setOptions=setOptions;this.getSelection=getSelection;this.setSelection=setSelection;this.cancelSelection=cancelSelection;this.update=doUpdate;var msie=(/msie ([\w.]+)/i.exec(ua)||[])[1],opera=/opera/i.test(ua),safari=/webkit/i.test(ua)&&!/chrome/i.test(ua);$p=$img;while($p.length){zIndex=max(zIndex,!isNaN($p.css('z-index'))?$p.css('z-index'):zIndex);if($p.css('position')=='fixed')position='fixed';$p=$p.parent(':not(body)')}zIndex=options.zIndex||zIndex;if(msie)$img.attr('unselectable','on');$.imgAreaSelect.keyPress=msie||safari?'keydown':'keypress';if(opera)$areaOpera=div().css({width:'100%',height:'100%',position:'absolute',zIndex:zIndex+2||2});$box.add($outer).css({visibility:'hidden',position:position,overflow:'hidden',zIndex:zIndex||'0'});$box.css({zIndex:zIndex+2||2});$area.add($border).css({position:'absolute',fontSize:0});img.complete||img.readyState=='complete'||!$img.is('img')?imgLoad():$img.one('load',imgLoad);if(!imgLoaded&&msie&&msie>=7)img.src=img.src};$.fn.imgAreaSelect=function(options){options=options||{};this.each(function(){if($(this).data('imgAreaSelect')){if(options.remove){$(this).data('imgAreaSelect').remove();$(this).removeData('imgAreaSelect')}else $(this).data('imgAreaSelect').setOptions(options)}else if(!options.remove){if(options.enable===undefined&&options.disable===undefined)options.enable=true;$(this).data('imgAreaSelect',new $.imgAreaSelect(this,options))}});if(options.instance)return $(this).data('imgAreaSelect');return this}})(typeof(jQuery)!='undefined'?jQuery:django.jQuery); -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/GPL-LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/scripts/jquery.imgareaselect.js: -------------------------------------------------------------------------------- 1 | /* 2 | * imgAreaSelect jQuery plugin 3 | * version 0.9.10 4 | * 5 | * Copyright (c) 2008-2013 Michal Wojciechowski (odyniec.net) 6 | * 7 | * Dual licensed under the MIT (MIT-LICENSE.txt) 8 | * and GPL (GPL-LICENSE.txt) licenses. 9 | * 10 | * http://odyniec.net/projects/imgareaselect/ 11 | * 12 | */ 13 | 14 | (function($) { 15 | 16 | var abs = Math.abs, 17 | max = Math.max, 18 | min = Math.min, 19 | round = Math.round; 20 | 21 | function div() { 22 | return $('
'); 23 | } 24 | 25 | $.imgAreaSelect = function (img, options) { 26 | var 27 | 28 | $img = $(img), 29 | 30 | imgLoaded, 31 | 32 | $box = div(), 33 | $area = div(), 34 | $border = div().add(div()).add(div()).add(div()), 35 | $outer = div().add(div()).add(div()).add(div()), 36 | $handles = $([]), 37 | 38 | $areaOpera, 39 | 40 | left, top, 41 | 42 | imgOfs = { left: 0, top: 0 }, 43 | 44 | imgWidth, imgHeight, 45 | 46 | $parent, 47 | 48 | parOfs = { left: 0, top: 0 }, 49 | 50 | zIndex = 0, 51 | 52 | position = 'absolute', 53 | 54 | startX, startY, 55 | 56 | scaleX, scaleY, 57 | 58 | resize, 59 | 60 | minWidth, minHeight, maxWidth, maxHeight, 61 | 62 | aspectRatio, 63 | 64 | shown, 65 | 66 | x1, y1, x2, y2, 67 | 68 | selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 }, 69 | 70 | docElem = document.documentElement, 71 | 72 | ua = navigator.userAgent, 73 | 74 | $p, d, i, o, w, h, adjusted; 75 | 76 | function viewX(x) { 77 | return x + imgOfs.left - parOfs.left; 78 | } 79 | 80 | function viewY(y) { 81 | return y + imgOfs.top - parOfs.top; 82 | } 83 | 84 | function selX(x) { 85 | return x - imgOfs.left + parOfs.left; 86 | } 87 | 88 | function selY(y) { 89 | return y - imgOfs.top + parOfs.top; 90 | } 91 | 92 | function evX(event) { 93 | return event.pageX - parOfs.left; 94 | } 95 | 96 | function evY(event) { 97 | return event.pageY - parOfs.top; 98 | } 99 | 100 | function getSelection(noScale) { 101 | var sx = noScale || scaleX, sy = noScale || scaleY; 102 | 103 | return { x1: round(selection.x1 * sx), 104 | y1: round(selection.y1 * sy), 105 | x2: round(selection.x2 * sx), 106 | y2: round(selection.y2 * sy), 107 | width: round(selection.x2 * sx) - round(selection.x1 * sx), 108 | height: round(selection.y2 * sy) - round(selection.y1 * sy) }; 109 | } 110 | 111 | function setSelection(x1, y1, x2, y2, noScale) { 112 | var sx = noScale || scaleX, sy = noScale || scaleY; 113 | 114 | selection = { 115 | x1: round(x1 / sx || 0), 116 | y1: round(y1 / sy || 0), 117 | x2: round(x2 / sx || 0), 118 | y2: round(y2 / sy || 0) 119 | }; 120 | 121 | selection.width = selection.x2 - selection.x1; 122 | selection.height = selection.y2 - selection.y1; 123 | } 124 | 125 | function adjust() { 126 | if (!imgLoaded || !$img.width()) 127 | return; 128 | 129 | imgOfs = { left: round($img.offset().left), top: round($img.offset().top) }; 130 | 131 | imgWidth = $img.innerWidth(); 132 | imgHeight = $img.innerHeight(); 133 | 134 | imgOfs.top += ($img.outerHeight() - imgHeight) >> 1; 135 | imgOfs.left += ($img.outerWidth() - imgWidth) >> 1; 136 | 137 | minWidth = round(options.minWidth / scaleX) || 0; 138 | minHeight = round(options.minHeight / scaleY) || 0; 139 | maxWidth = round(min(options.maxWidth / scaleX || 1<<24, imgWidth)); 140 | maxHeight = round(min(options.maxHeight / scaleY || 1<<24, imgHeight)); 141 | 142 | if ($().jquery == '1.3.2' && position == 'fixed' && 143 | !docElem['getBoundingClientRect']) 144 | { 145 | imgOfs.top += max(document.body.scrollTop, docElem.scrollTop); 146 | imgOfs.left += max(document.body.scrollLeft, docElem.scrollLeft); 147 | } 148 | 149 | parOfs = /absolute|relative/.test($parent.css('position')) ? 150 | { left: round($parent.offset().left) - $parent.scrollLeft(), 151 | top: round($parent.offset().top) - $parent.scrollTop() } : 152 | position == 'fixed' ? 153 | { left: $(document).scrollLeft(), top: $(document).scrollTop() } : 154 | { left: 0, top: 0 }; 155 | 156 | left = viewX(0); 157 | top = viewY(0); 158 | 159 | if (selection.x2 > imgWidth || selection.y2 > imgHeight) 160 | doResize(); 161 | } 162 | 163 | function update(resetKeyPress) { 164 | if (!shown) return; 165 | 166 | $box.css({ left: viewX(selection.x1), top: viewY(selection.y1) }) 167 | .add($area).width(w = selection.width).height(h = selection.height); 168 | 169 | $area.add($border).add($handles).css({ left: 0, top: 0 }); 170 | 171 | $border 172 | .width(max(w - $border.outerWidth() + $border.innerWidth(), 0)) 173 | .height(max(h - $border.outerHeight() + $border.innerHeight(), 0)); 174 | 175 | $($outer[0]).css({ left: left, top: top, 176 | width: selection.x1, height: imgHeight }); 177 | $($outer[1]).css({ left: left + selection.x1, top: top, 178 | width: w, height: selection.y1 }); 179 | $($outer[2]).css({ left: left + selection.x2, top: top, 180 | width: imgWidth - selection.x2, height: imgHeight }); 181 | $($outer[3]).css({ left: left + selection.x1, top: top + selection.y2, 182 | width: w, height: imgHeight - selection.y2 }); 183 | 184 | w -= $handles.outerWidth(); 185 | h -= $handles.outerHeight(); 186 | 187 | switch ($handles.length) { 188 | case 8: 189 | $($handles[4]).css({ left: w >> 1 }); 190 | $($handles[5]).css({ left: w, top: h >> 1 }); 191 | $($handles[6]).css({ left: w >> 1, top: h }); 192 | $($handles[7]).css({ top: h >> 1 }); 193 | case 4: 194 | $handles.slice(1,3).css({ left: w }); 195 | $handles.slice(2,4).css({ top: h }); 196 | } 197 | 198 | if (resetKeyPress !== false) { 199 | if ($.imgAreaSelect.onKeyPress != docKeyPress) 200 | $(document).unbind($.imgAreaSelect.keyPress, 201 | $.imgAreaSelect.onKeyPress); 202 | 203 | if (options.keys) 204 | $(document)[$.imgAreaSelect.keyPress]( 205 | $.imgAreaSelect.onKeyPress = docKeyPress); 206 | } 207 | 208 | if (msie && $border.outerWidth() - $border.innerWidth() == 2) { 209 | $border.css('margin', 0); 210 | setTimeout(function () { $border.css('margin', 'auto'); }, 0); 211 | } 212 | } 213 | 214 | function doUpdate(resetKeyPress) { 215 | adjust(); 216 | update(resetKeyPress); 217 | x1 = viewX(selection.x1); y1 = viewY(selection.y1); 218 | x2 = viewX(selection.x2); y2 = viewY(selection.y2); 219 | } 220 | 221 | function hide($elem, fn) { 222 | options.fadeSpeed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide(); 223 | 224 | } 225 | 226 | function areaMouseMove(event) { 227 | var x = selX(evX(event)) - selection.x1, 228 | y = selY(evY(event)) - selection.y1; 229 | 230 | if (!adjusted) { 231 | adjust(); 232 | adjusted = true; 233 | 234 | $box.one('mouseout', function () { adjusted = false; }); 235 | } 236 | 237 | resize = ''; 238 | 239 | if (options.resizable) { 240 | if (y <= options.resizeMargin) 241 | resize = 'n'; 242 | else if (y >= selection.height - options.resizeMargin) 243 | resize = 's'; 244 | if (x <= options.resizeMargin) 245 | resize += 'w'; 246 | else if (x >= selection.width - options.resizeMargin) 247 | resize += 'e'; 248 | } 249 | 250 | $box.css('cursor', resize ? resize + '-resize' : 251 | options.movable ? 'move' : ''); 252 | if ($areaOpera) 253 | $areaOpera.toggle(); 254 | } 255 | 256 | function docMouseUp(event) { 257 | $('body').css('cursor', ''); 258 | if (options.autoHide || selection.width * selection.height == 0) 259 | hide($box.add($outer), function () { $(this).hide(); }); 260 | 261 | $(document).unbind('mousemove', selectingMouseMove); 262 | $box.mousemove(areaMouseMove); 263 | 264 | options.onSelectEnd(img, getSelection()); 265 | } 266 | 267 | function areaMouseDown(event) { 268 | if (event.which != 1) return false; 269 | 270 | adjust(); 271 | 272 | if (resize) { 273 | $('body').css('cursor', resize + '-resize'); 274 | 275 | x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']); 276 | y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']); 277 | 278 | $(document).mousemove(selectingMouseMove) 279 | .one('mouseup', docMouseUp); 280 | $box.unbind('mousemove', areaMouseMove); 281 | } 282 | else if (options.movable) { 283 | startX = left + selection.x1 - evX(event); 284 | startY = top + selection.y1 - evY(event); 285 | 286 | $box.unbind('mousemove', areaMouseMove); 287 | 288 | $(document).mousemove(movingMouseMove) 289 | .one('mouseup', function () { 290 | options.onSelectEnd(img, getSelection()); 291 | 292 | $(document).unbind('mousemove', movingMouseMove); 293 | $box.mousemove(areaMouseMove); 294 | }); 295 | } 296 | else 297 | $img.mousedown(event); 298 | 299 | return false; 300 | } 301 | 302 | function fixAspectRatio(xFirst) { 303 | if (aspectRatio) 304 | if (xFirst) { 305 | x2 = max(left, min(left + imgWidth, 306 | x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))); 307 | 308 | y2 = round(max(top, min(top + imgHeight, 309 | y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1)))); 310 | x2 = round(x2); 311 | } 312 | else { 313 | y2 = max(top, min(top + imgHeight, 314 | y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1))); 315 | x2 = round(max(left, min(left + imgWidth, 316 | x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1)))); 317 | y2 = round(y2); 318 | } 319 | } 320 | 321 | function doResize() { 322 | x1 = min(x1, left + imgWidth); 323 | y1 = min(y1, top + imgHeight); 324 | 325 | if (abs(x2 - x1) < minWidth) { 326 | x2 = x1 - minWidth * (x2 < x1 || -1); 327 | 328 | if (x2 < left) 329 | x1 = left + minWidth; 330 | else if (x2 > left + imgWidth) 331 | x1 = left + imgWidth - minWidth; 332 | } 333 | 334 | if (abs(y2 - y1) < minHeight) { 335 | y2 = y1 - minHeight * (y2 < y1 || -1); 336 | 337 | if (y2 < top) 338 | y1 = top + minHeight; 339 | else if (y2 > top + imgHeight) 340 | y1 = top + imgHeight - minHeight; 341 | } 342 | 343 | x2 = max(left, min(x2, left + imgWidth)); 344 | y2 = max(top, min(y2, top + imgHeight)); 345 | 346 | fixAspectRatio(abs(x2 - x1) < abs(y2 - y1) * aspectRatio); 347 | 348 | if (abs(x2 - x1) > maxWidth) { 349 | x2 = x1 - maxWidth * (x2 < x1 || -1); 350 | fixAspectRatio(); 351 | } 352 | 353 | if (abs(y2 - y1) > maxHeight) { 354 | y2 = y1 - maxHeight * (y2 < y1 || -1); 355 | fixAspectRatio(true); 356 | } 357 | 358 | selection = { x1: selX(min(x1, x2)), x2: selX(max(x1, x2)), 359 | y1: selY(min(y1, y2)), y2: selY(max(y1, y2)), 360 | width: abs(x2 - x1), height: abs(y2 - y1) }; 361 | 362 | update(); 363 | 364 | options.onSelectChange(img, getSelection()); 365 | } 366 | 367 | function selectingMouseMove(event) { 368 | x2 = /w|e|^$/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2); 369 | y2 = /n|s|^$/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2); 370 | 371 | doResize(); 372 | 373 | return false; 374 | 375 | } 376 | 377 | function doMove(newX1, newY1) { 378 | x2 = (x1 = newX1) + selection.width; 379 | y2 = (y1 = newY1) + selection.height; 380 | 381 | $.extend(selection, { x1: selX(x1), y1: selY(y1), x2: selX(x2), 382 | y2: selY(y2) }); 383 | 384 | update(); 385 | 386 | options.onSelectChange(img, getSelection()); 387 | } 388 | 389 | function movingMouseMove(event) { 390 | x1 = max(left, min(startX + evX(event), left + imgWidth - selection.width)); 391 | y1 = max(top, min(startY + evY(event), top + imgHeight - selection.height)); 392 | 393 | doMove(x1, y1); 394 | 395 | event.preventDefault(); 396 | 397 | return false; 398 | } 399 | 400 | function startSelection() { 401 | $(document).unbind('mousemove', startSelection); 402 | adjust(); 403 | 404 | x2 = x1; 405 | y2 = y1; 406 | 407 | doResize(); 408 | 409 | resize = ''; 410 | 411 | if (!$outer.is(':visible')) 412 | $box.add($outer).hide().fadeIn(options.fadeSpeed||0); 413 | 414 | shown = true; 415 | 416 | $(document).unbind('mouseup', cancelSelection) 417 | .mousemove(selectingMouseMove).one('mouseup', docMouseUp); 418 | $box.unbind('mousemove', areaMouseMove); 419 | 420 | options.onSelectStart(img, getSelection()); 421 | } 422 | 423 | function cancelSelection() { 424 | $(document).unbind('mousemove', startSelection) 425 | .unbind('mouseup', cancelSelection); 426 | hide($box.add($outer)); 427 | 428 | setSelection(selX(x1), selY(y1), selX(x1), selY(y1)); 429 | 430 | if (!(this instanceof $.imgAreaSelect)) { 431 | options.onSelectChange(img, getSelection()); 432 | options.onSelectEnd(img, getSelection()); 433 | } 434 | } 435 | 436 | function imgMouseDown(event) { 437 | if (event.which != 1 || $outer.is(':animated')) return false; 438 | 439 | adjust(); 440 | startX = x1 = evX(event); 441 | startY = y1 = evY(event); 442 | 443 | $(document).mousemove(startSelection).mouseup(cancelSelection); 444 | 445 | return false; 446 | } 447 | 448 | function windowResize() { 449 | doUpdate(false); 450 | } 451 | 452 | function imgLoad() { 453 | imgLoaded = true; 454 | 455 | setOptions(options = $.extend({ 456 | classPrefix: 'imgareaselect', 457 | movable: true, 458 | parent: 'body', 459 | resizable: true, 460 | resizeMargin: 10, 461 | onInit: function () {}, 462 | onSelectStart: function () {}, 463 | onSelectChange: function () {}, 464 | onSelectEnd: function () {} 465 | }, options)); 466 | 467 | $box.add($outer).css({ visibility: '' }); 468 | 469 | if (options.show) { 470 | shown = true; 471 | adjust(); 472 | update(); 473 | $box.add($outer).hide().fadeIn(options.fadeSpeed||0); 474 | } 475 | 476 | setTimeout(function () { options.onInit(img, getSelection()); }, 0); 477 | } 478 | 479 | var docKeyPress = function(event) { 480 | var k = options.keys, d, t, key = event.keyCode; 481 | 482 | d = !isNaN(k.alt) && (event.altKey || event.originalEvent.altKey) ? k.alt : 483 | !isNaN(k.ctrl) && event.ctrlKey ? k.ctrl : 484 | !isNaN(k.shift) && event.shiftKey ? k.shift : 485 | !isNaN(k.arrows) ? k.arrows : 10; 486 | 487 | if (k.arrows == 'resize' || (k.shift == 'resize' && event.shiftKey) || 488 | (k.ctrl == 'resize' && event.ctrlKey) || 489 | (k.alt == 'resize' && (event.altKey || event.originalEvent.altKey))) 490 | { 491 | switch (key) { 492 | case 37: 493 | d = -d; 494 | case 39: 495 | t = max(x1, x2); 496 | x1 = min(x1, x2); 497 | x2 = max(t + d, x1); 498 | fixAspectRatio(); 499 | break; 500 | case 38: 501 | d = -d; 502 | case 40: 503 | t = max(y1, y2); 504 | y1 = min(y1, y2); 505 | y2 = max(t + d, y1); 506 | fixAspectRatio(true); 507 | break; 508 | default: 509 | return; 510 | } 511 | 512 | doResize(); 513 | } 514 | else { 515 | x1 = min(x1, x2); 516 | y1 = min(y1, y2); 517 | 518 | switch (key) { 519 | case 37: 520 | doMove(max(x1 - d, left), y1); 521 | break; 522 | case 38: 523 | doMove(x1, max(y1 - d, top)); 524 | break; 525 | case 39: 526 | doMove(x1 + min(d, imgWidth - selX(x2)), y1); 527 | break; 528 | case 40: 529 | doMove(x1, y1 + min(d, imgHeight - selY(y2))); 530 | break; 531 | default: 532 | return; 533 | } 534 | } 535 | 536 | return false; 537 | }; 538 | 539 | function styleOptions($elem, props) { 540 | for (var option in props) 541 | if (options[option] !== undefined) 542 | $elem.css(props[option], options[option]); 543 | } 544 | 545 | function setOptions(newOptions) { 546 | if (newOptions.parent) 547 | ($parent = $(newOptions.parent)).append($box.add($outer)); 548 | 549 | $.extend(options, newOptions); 550 | 551 | adjust(); 552 | 553 | if (newOptions.handles != null) { 554 | $handles.remove(); 555 | $handles = $([]); 556 | 557 | i = newOptions.handles ? newOptions.handles == 'corners' ? 4 : 8 : 0; 558 | 559 | while (i--) 560 | $handles = $handles.add(div()); 561 | 562 | $handles.addClass(options.classPrefix + '-handle').css({ 563 | position: 'absolute', 564 | fontSize: 0, 565 | zIndex: zIndex + 1 || 1 566 | }); 567 | 568 | if (!parseInt($handles.css('width')) >= 0) 569 | $handles.width(5).height(5); 570 | 571 | if (o = options.borderWidth) 572 | $handles.css({ borderWidth: o, borderStyle: 'solid' }); 573 | 574 | styleOptions($handles, { borderColor1: 'border-color', 575 | borderColor2: 'background-color', 576 | borderOpacity: 'opacity' }); 577 | } 578 | 579 | scaleX = options.imageWidth / imgWidth || 1; 580 | scaleY = options.imageHeight / imgHeight || 1; 581 | 582 | if (newOptions.x1 != null) { 583 | setSelection(newOptions.x1, newOptions.y1, newOptions.x2, 584 | newOptions.y2); 585 | newOptions.show = !newOptions.hide; 586 | } 587 | 588 | if (newOptions.keys) 589 | options.keys = $.extend({ shift: 1, ctrl: 'resize' }, 590 | newOptions.keys); 591 | 592 | $outer.addClass(options.classPrefix + '-outer'); 593 | $area.addClass(options.classPrefix + '-selection'); 594 | for (i = 0; i++ < 4;) 595 | $($border[i-1]).addClass(options.classPrefix + '-border' + i); 596 | 597 | styleOptions($area, { selectionColor: 'background-color', 598 | selectionOpacity: 'opacity' }); 599 | styleOptions($border, { borderOpacity: 'opacity', 600 | borderWidth: 'border-width' }); 601 | styleOptions($outer, { outerColor: 'background-color', 602 | outerOpacity: 'opacity' }); 603 | if (o = options.borderColor1) 604 | $($border[0]).css({ borderStyle: 'solid', borderColor: o }); 605 | if (o = options.borderColor2) 606 | $($border[1]).css({ borderStyle: 'dashed', borderColor: o }); 607 | 608 | $box.append($area.add($border).add($areaOpera)).append($handles); 609 | 610 | if (msie) { 611 | if (o = ($outer.css('filter')||'').match(/opacity=(\d+)/)) 612 | $outer.css('opacity', o[1]/100); 613 | if (o = ($border.css('filter')||'').match(/opacity=(\d+)/)) 614 | $border.css('opacity', o[1]/100); 615 | } 616 | 617 | if (newOptions.hide) 618 | hide($box.add($outer)); 619 | else if (newOptions.show && imgLoaded) { 620 | shown = true; 621 | $box.add($outer).fadeIn(options.fadeSpeed||0); 622 | doUpdate(); 623 | } 624 | 625 | aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1]; 626 | 627 | $img.add($outer).unbind('mousedown', imgMouseDown); 628 | 629 | if (options.disable || options.enable === false) { 630 | $box.unbind('mousemove', areaMouseMove).unbind('mousedown', areaMouseDown); 631 | $(window).unbind('resize', windowResize); 632 | } 633 | else { 634 | if (options.enable || options.disable === false) { 635 | if (options.resizable || options.movable) 636 | $box.mousemove(areaMouseMove).mousedown(areaMouseDown); 637 | 638 | $(window).resize(windowResize); 639 | } 640 | 641 | if (!options.persistent) 642 | $img.add($outer).mousedown(imgMouseDown); 643 | } 644 | 645 | options.enable = options.disable = undefined; 646 | } 647 | 648 | this.remove = function () { 649 | setOptions({ disable: true }); 650 | $box.add($outer).remove(); 651 | }; 652 | 653 | this.getOptions = function () { return options; }; 654 | 655 | this.setOptions = setOptions; 656 | 657 | this.getSelection = getSelection; 658 | 659 | this.setSelection = setSelection; 660 | 661 | this.cancelSelection = cancelSelection; 662 | 663 | this.update = doUpdate; 664 | 665 | var msie = (/msie ([\w.]+)/i.exec(ua)||[])[1], 666 | opera = /opera/i.test(ua), 667 | safari = /webkit/i.test(ua) && !/chrome/i.test(ua); 668 | 669 | $p = $img; 670 | 671 | while ($p.length) { 672 | zIndex = max(zIndex, 673 | !isNaN($p.css('z-index')) ? $p.css('z-index') : zIndex); 674 | if ($p.css('position') == 'fixed') 675 | position = 'fixed'; 676 | 677 | $p = $p.parent(':not(body)'); 678 | } 679 | 680 | zIndex = options.zIndex || zIndex; 681 | 682 | if (msie) 683 | $img.attr('unselectable', 'on'); 684 | 685 | $.imgAreaSelect.keyPress = msie || safari ? 'keydown' : 'keypress'; 686 | 687 | if (opera) 688 | 689 | $areaOpera = div().css({ width: '100%', height: '100%', 690 | position: 'absolute', zIndex: zIndex + 2 || 2 }); 691 | 692 | $box.add($outer).css({ visibility: 'hidden', position: position, 693 | overflow: 'hidden', zIndex: zIndex || '0' }); 694 | $box.css({ zIndex: zIndex + 2 || 2 }); 695 | $area.add($border).css({ position: 'absolute', fontSize: 0 }); 696 | 697 | img.complete || img.readyState == 'complete' || !$img.is('img') ? 698 | imgLoad() : $img.one('load', imgLoad); 699 | 700 | if (!imgLoaded && msie && msie >= 7) 701 | img.src = img.src; 702 | }; 703 | 704 | $.fn.imgAreaSelect = function (options) { 705 | options = options || {}; 706 | 707 | this.each(function () { 708 | if ($(this).data('imgAreaSelect')) { 709 | if (options.remove) { 710 | $(this).data('imgAreaSelect').remove(); 711 | $(this).removeData('imgAreaSelect'); 712 | } 713 | else 714 | $(this).data('imgAreaSelect').setOptions(options); 715 | } 716 | else if (!options.remove) { 717 | if (options.enable === undefined && options.disable === undefined) 718 | options.enable = true; 719 | 720 | $(this).data('imgAreaSelect', new $.imgAreaSelect(this, options)); 721 | } 722 | }); 723 | 724 | if (options.instance) 725 | return $(this).data('imgAreaSelect'); 726 | 727 | return this; 728 | }; 729 | 730 | })(typeof(jQuery) != 'undefined' ? jQuery : django.jQuery); 731 | -------------------------------------------------------------------------------- /awesome_avatar/static/imgareaselect/scripts/jquery.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v1.9.0 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license */(function(e,t){"use strict";function n(e){var t=e.length,n=st.type(e);return st.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}function r(e){var t=Tt[e]={};return st.each(e.match(lt)||[],function(e,n){t[n]=!0}),t}function i(e,n,r,i){if(st.acceptData(e)){var o,a,s=st.expando,u="string"==typeof n,l=e.nodeType,c=l?st.cache:e,f=l?e[s]:e[s]&&s;if(f&&c[f]&&(i||c[f].data)||!u||r!==t)return f||(l?e[s]=f=K.pop()||st.guid++:f=s),c[f]||(c[f]={},l||(c[f].toJSON=st.noop)),("object"==typeof n||"function"==typeof n)&&(i?c[f]=st.extend(c[f],n):c[f].data=st.extend(c[f].data,n)),o=c[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[st.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[st.camelCase(n)])):a=o,a}}function o(e,t,n){if(st.acceptData(e)){var r,i,o,a=e.nodeType,u=a?st.cache:e,l=a?e[st.expando]:st.expando;if(u[l]){if(t&&(r=n?u[l]:u[l].data)){st.isArray(t)?t=t.concat(st.map(t,st.camelCase)):t in r?t=[t]:(t=st.camelCase(t),t=t in r?[t]:t.split(" "));for(i=0,o=t.length;o>i;i++)delete r[t[i]];if(!(n?s:st.isEmptyObject)(r))return}(n||(delete u[l].data,s(u[l])))&&(a?st.cleanData([e],!0):st.support.deleteExpando||u!=u.window?delete u[l]:u[l]=null)}}}function a(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(Nt,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:wt.test(r)?st.parseJSON(r):r}catch(o){}st.data(e,n,r)}else r=t}return r}function s(e){var t;for(t in e)if(("data"!==t||!st.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function u(){return!0}function l(){return!1}function c(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function f(e,t,n){if(t=t||0,st.isFunction(t))return st.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return st.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=st.grep(e,function(e){return 1===e.nodeType});if(Wt.test(t))return st.filter(t,r,!n);t=st.filter(t,r)}return st.grep(e,function(e){return st.inArray(e,t)>=0===n})}function p(e){var t=zt.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function d(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function h(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function g(e){var t=nn.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function m(e,t){for(var n,r=0;null!=(n=e[r]);r++)st._data(n,"globalEval",!t||st._data(t[r],"globalEval"))}function y(e,t){if(1===t.nodeType&&st.hasData(e)){var n,r,i,o=st._data(e),a=st._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)st.event.add(t,n,s[n][r])}a.data&&(a.data=st.extend({},a.data))}}function v(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!st.support.noCloneEvent&&t[st.expando]){r=st._data(t);for(i in r.events)st.removeEvent(t,i,r.handle);t.removeAttribute(st.expando)}"script"===n&&t.text!==e.text?(h(t).text=e.text,g(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),st.support.html5Clone&&e.innerHTML&&!st.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Zt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}function b(e,n){var r,i,o=0,a=e.getElementsByTagName!==t?e.getElementsByTagName(n||"*"):e.querySelectorAll!==t?e.querySelectorAll(n||"*"):t;if(!a)for(a=[],r=e.childNodes||e;null!=(i=r[o]);o++)!n||st.nodeName(i,n)?a.push(i):st.merge(a,b(i,n));return n===t||n&&st.nodeName(e,n)?st.merge([e],a):a}function x(e){Zt.test(e.type)&&(e.defaultChecked=e.checked)}function T(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Nn.length;i--;)if(t=Nn[i]+n,t in e)return t;return r}function w(e,t){return e=t||e,"none"===st.css(e,"display")||!st.contains(e.ownerDocument,e)}function N(e,t){for(var n,r=[],i=0,o=e.length;o>i;i++)n=e[i],n.style&&(r[i]=st._data(n,"olddisplay"),t?(r[i]||"none"!==n.style.display||(n.style.display=""),""===n.style.display&&w(n)&&(r[i]=st._data(n,"olddisplay",S(n.nodeName)))):r[i]||w(n)||st._data(n,"olddisplay",st.css(n,"display")));for(i=0;o>i;i++)n=e[i],n.style&&(t&&"none"!==n.style.display&&""!==n.style.display||(n.style.display=t?r[i]||"":"none"));return e}function C(e,t,n){var r=mn.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function k(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;4>o;o+=2)"margin"===n&&(a+=st.css(e,n+wn[o],!0,i)),r?("content"===n&&(a-=st.css(e,"padding"+wn[o],!0,i)),"margin"!==n&&(a-=st.css(e,"border"+wn[o]+"Width",!0,i))):(a+=st.css(e,"padding"+wn[o],!0,i),"padding"!==n&&(a+=st.css(e,"border"+wn[o]+"Width",!0,i)));return a}function E(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=ln(e),a=st.support.boxSizing&&"border-box"===st.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=un(e,t,o),(0>i||null==i)&&(i=e.style[t]),yn.test(i))return i;r=a&&(st.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+k(e,t,n||(a?"border":"content"),r,o)+"px"}function S(e){var t=V,n=bn[e];return n||(n=A(e,t),"none"!==n&&n||(cn=(cn||st("