(function() {
window.Studio || (window.Studio = {
routes: {},
assets: {}
});
_.extend(Studio, Backbone.Events, {
url: function() {
return new Studio.Url(window.location.href);
},
redirectTo: function(path) {
return Turbolinks.visit(path);
}
});
}).call(this);
var I18n = I18n || {};
I18n.translations = {"en":{"date":{"formats":{"default":"%Y-%m-%d","short":"%b %d","long":"%B %d, %Y"},"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"order":["year","month","day"]},"time":{"formats":{"default":"%a, %d %b %Y %H:%M:%S %z","short":"%d %b %H:%M","long":"%B %d, %Y %H:%M"},"am":"am","pm":"pm"},"support":{"array":{"words_connector":", ","two_words_connector":" and ","last_word_connector":", and "}},"number":{"format":{"separator":".","delimiter":",","precision":3,"significant":false,"strip_insignificant_zeros":false},"currency":{"format":{"format":"%u%n","unit":"$","separator":".","delimiter":",","precision":2,"significant":false,"strip_insignificant_zeros":false}},"percentage":{"format":{"delimiter":"","format":"%n%"}},"precision":{"format":{"delimiter":""}},"human":{"format":{"delimiter":"","precision":3,"significant":true,"strip_insignificant_zeros":true},"storage_units":{"format":"%n %u","units":{"byte":{"one":"Byte","other":"Bytes"},"kb":"KB","mb":"MB","gb":"GB","tb":"TB"}},"decimal_units":{"format":"%n %u","units":{"unit":"","thousand":"Thousand","million":"Million","billion":"Billion","trillion":"Trillion","quadrillion":"Quadrillion"}}}},"errors":{"format":"%{attribute} %{message}","messages":{"inclusion":"is not included in the list","exclusion":"is reserved","invalid":"is invalid","confirmation":"doesn't match %{attribute}","accepted":"must be accepted","empty":"can't be empty","blank":"Please provide a value","present":"must be blank","too_long":"is too long (maximum is %{count} characters)","too_short":"is too short (minimum is %{count} characters)","wrong_length":"is the wrong length (should be %{count} characters)","not_a_number":"is not a number","not_an_integer":"must be an integer","greater_than":"must be greater than %{count}","greater_than_or_equal_to":"must be greater than or equal to %{count}","equal_to":"must be equal to %{count}","less_than":"must be less than %{count}","less_than_or_equal_to":"must be less than or equal to %{count}","other_than":"must be other than %{count}","odd":"must be odd","even":"must be even","taken":"has already been taken","carrierwave_processing_error":"failed to be processed","carrierwave_integrity_error":"is not of an allowed file type","carrierwave_download_error":"could not be downloaded","extension_white_list_error":"You are not allowed to upload %{extension} files, allowed types: %{allowed_types}","extension_black_list_error":"You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}","rmagick_processing_error":"Failed to manipulate with rmagick, maybe it is not an image? Original Error: %{e}","mime_types_processing_error":"Failed to process file with MIME::Types, maybe not valid content-type? Original Error: %{e}","mini_magick_processing_error":"Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}","record_invalid":"The record is invalid"}},"activerecord":{"errors":{"messages":{"record_invalid":"Validation failed: %{errors}","restrict_dependent_destroy":{"one":"Cannot delete record because a dependent %{record} exists","many":"Cannot delete record because dependent %{record} exist"},"invalid":"is invalid","invalid_event":"cannot transition when %{state}","invalid_transition":"cannot transition via \"%{event}\""},"models":{"review":{"attributes":{"recommended":{"blank":"Please make a selection"},"story":{"blank":"Please enter your review"}}},"user/payout_detail":{"attributes":{"payment_service":{"unable_to_contact_payoneer":"Unable to contact Payoneer"}}},"timeline_event_attachment":{"size_too_big":"Your file should be less than %{file_size})"},"brief":{"attributes":{"description":{"blank":"Please enter your brief"},"terms_of_service":{"accepted":"Please accept our Terms to place an order"}}},"custom_job_proposal":{"attributes":{"description":{"blank":"Please enter a description"},"price":{"blank":"Please enter a price"},"turnaround":{"blank":"Please enter a turnaround"}}},"enquiry":{"attributes":{"body":{"blank":"Please enter your enquiry"}}},"enquiry_message":{"attributes":{"body":{"blank":"Please enter a comment"}}}}}},"datetime":{"distance_in_words":{"half_a_minute":"half a minute","less_than_x_seconds":{"one":"less than 1 second","other":"less than %{count} seconds"},"x_seconds":{"one":"1 second","other":"%{count} seconds"},"less_than_x_minutes":{"one":"less than a minute","other":"less than %{count} minutes"},"x_minutes":{"one":"1 minute","other":"%{count} minutes"},"about_x_hours":{"one":"1 hour","other":"%{count} hours"},"x_days":{"one":"1 day","other":"%{count} days"},"about_x_months":{"one":"1 month","other":"%{count} months"},"x_months":{"one":"1 month","other":"%{count} months"},"about_x_years":{"one":"about 1 year","other":"about %{count} years"},"over_x_years":{"one":"over 1 year","other":"over %{count} years"},"almost_x_years":{"one":"almost 1 year","other":"almost %{count} years"}},"prompts":{"year":"Year","month":"Month","day":"Day","hour":"Hour","minute":"Minute","second":"Seconds"}},"helpers":{"select":{"prompt":"Please select"},"submit":{"create":"Create %{model}","update":"Update %{model}","submit":"Save %{model}"},"page_entries_info":{"one_page":{"display_entries":{"zero":"No %{entry_name} found","one":"Displaying \u003cb\u003e1\u003c/b\u003e %{entry_name}","other":"Displaying \u003cb\u003eall %{count}\u003c/b\u003e %{entry_name}"}},"more_pages":{"display_entries":"Displaying %{entry_name} \u003cb\u003e%{first}\u0026nbsp;-\u0026nbsp;%{last}\u003c/b\u003e of \u003cb\u003e%{total}\u003c/b\u003e in total"}}},"activemodel":{"errors":{"messages":{"invalid":"is invalid","invalid_event":"cannot transition when %{state}","invalid_transition":"cannot transition via \"%{event}\""},"models":{"competition_feedback":{"attributes":{"story":{"blank":"Please provide feedback about your experience using Envato Studio in 100 words or less."},"accept_term_conditions":{"blank":"You need to accept the Terms and Conditions to enter the competition."}}},"service":{"attributes":{"name":{"blank":"Please enter a service title","too_long":"Service title should be no longer than 100 characters","invalid_characters":"Please don't include special characters within your service title.","invalid_references":"Don't reference your price, turnaround time or number of revisions in your service title. There are specific places for this info already","invalid_hype_words":"Service title should be a factual description of your service so avoid hype like \"awesome\" or \"best\". Check our \u003ca href=\"%{review_link}\"\u003ereview guide\u003c/a\u003e for examples","invalid_phrases":"Service title should be written in the form of a title, rather than a sentence. Check our \u003ca href=\"%{review_link}\"\u003ereview guide\u003c/a\u003e for examples","invalid_letter_case":"Service title should be written in title case. Check our \u003ca href=\"%{review_link}\"\u003ereview guide\u003c/a\u003e for examples"},"category":{"no_more_than_five":"You can't have more than five services in a single category. Please select another category or edit an existing service"},"description":{"blank":"Please enter a description","invalid_characters":"Please don't include special characters within your service description.","invalid_price_characters":"Please don't mention price in your description. Check our \u003ca href=\"%{review_link}\"\u003ereview guide\u003c/a\u003e for tips on what to include.","invalid_contact_reference":"Please don't include your contact details. All job-related communication should take place on the Envato Studio job timeline.","too_short":"Description must be at least %{count} characters"},"needs_from_buyer":{"blank":"Please enter your briefing guidelines","invalid_characters":"Please don't include special characters within your service briefing guidelines.","invalid_price_characters":"Please don't mention price in your briefing guidelines.","invalid_contact_reference":"Please don't include any external contact details. All job-related communication should take place on the Envato Studio job timeline."},"turnaround":{"blank":"Please select a turnaround time"},"revision_requests":{"blank":"Please select the target number of submissions"},"price":{"blank":"Please enter a price","step_mismatch":"Price must be a multiple of %{step}","range_overflow":"Price must be within the specified range","less_than_or_equal_to":"Price must be %{count} or less","greater_than_or_equal_to":"Price must be %{count} or more","requires_tax_information":"Prices $1000 or greater require tax information"},"microtube_attachments":{"must_be_images":"Please upload images only","not_enough_images":"Please upload a minimum of %{minimum} files","too_many_images":"Please upload a maximum of %{maximum} files"},"live_preview_url":{"blank":"Please enter a Demo","no_iframe_support":"That site doesn't allow its content to be displayed in our preview window. Please enter a different example of your work","competing_marketplace":"Please enter an example of your work, not a link to another marketplace","unsuccessful_response":"That URL is currently unavailable (Status: %{status_code}), please enter a different example of your work"}}},"tax_information":{"attributes":{"company_name":{"blank":"Company name is required for taxation purposes"},"company_address":{"blank":"Company address required for taxation purposes"},"tax_number":{"blank":"Tax number is required for taxation purposes"}}},"discount":{"attributes":{"coupon":{"blank":"Coupon code doesn't exist","expired":"Coupon code has expired","gateway_invalid":"Coupon code only works for %{payment_gateway}","already_been_used":"Coupon code has already been used","minimum_spend":"Coupon code can only be used for services that are $%{minimum_spend} or more","invalid_category":"Coupon code can only be used for categories (%{category_names})"}}},"credit_card":{"attributes":{"number":{"blank":"Please enter Card Number","invalid":"Please provide a valid credit card number"},"cardholder_name":{"blank":"Please enter Cardholder Name"},"expiration_month":{"blank":"Please enter Expiry Month"},"expiration_year":{"blank":"Please enter Expiry Year"},"cvv":{"blank":"Please enter CVV","invalid":"The CVV needs to be a 3-digit number"}}},"provider/withdrawal_validator":{"attributes":{"provider":{"disabled":"is disabled"},"earnings":{"below_threshold":"is below payout threshold of $%{threshold}"},"payment_service":{"not_supported":"of '%{service}' is not supported"}}},"review":{"attributes":{"story":{"too_long":"Please keep your review under %{count} characters"}}},"user/become_provider":{"confirmation":"Does not match other email address","attributes":{"terms_and_conditions":{"blank":"Please read and accept the Envato Studio terms","accepted":"Please read and accept the Envato Studio terms"},"payment_service":{"blank":"Please select a payment service"},"social_fields":{"blank":"Please fill in at least one social field"},"biography":{"blank":"Please provide information about you","too_short":"Please tell us more about you, use at least 100 characters"},"application_verification_links":{"blank":"Please provide examples of your work"},"paypal_email":{"blank":"Please provide a PayPal email"},"paypal_email_confirmation":{"blank":"Please confirm your PayPal email"},"moneybookers_email":{"blank":"Please provide a Moneybookers email"},"moneybookers_email_confirmation":{"blank":"Please confirm your Moneybookers email"},"country_code":{"blank":"Please select your location"},"avatar":{"blank":"Please provide an avatar"}}},"user/confirmation":{"attributes":{"terms_and_conditions":{"blank":"Please accept the Terms \u0026 Conditions","accepted":"Please accept the Terms \u0026 Conditions"},"city":{"blank":"Please enter your city"},"country_code":{"blank":"Please enter your country"}}},"state_event_factory":{"attributes":{"base":{"event_doesnt_exist":"You can't perform this action at the moment."}}},"job/event":{"message":{"blank":"Please enter a message."}},"user_confirmation":{"accepted":"You must accept the terms and conditions to continue."},"provider":{"attributes":{"provider":{"blank":"Please accept the Terms \u0026 Conditions"}}},"job/event_factory":{"attributes":{"message":{"blank":"You must include a message"}}},"custom_job/proposal":{"attributes":{"description":{"blank":"You must enter a description"},"price":{"blank":"Please enter price","not_an_integer":"Price must be a whole dollar amount","less_than_or_equal_to":"Price must be between $1 and $2500","greater_than_or_equal_to":"Price must be between $1 and $2500"},"turnaround":{"blank":"Please enter turnaround","not_an_integer":"Turnaround must be a whole number","less_than_or_equal_to":"Turnaround must be between 1 and 14 days","greater_than_or_equal_to":"Turnaround must be between 1 and 14 days"}}},"user_profile":{"attributes":{"city":{"blank":"Please enter your city"},"company_name":{"blank":"Required to sell services for $1000 or more"},"company_address":{"blank":"Required to sell services for $1000 or more"},"tax_number":{"blank":"Required to sell services for $1000 or more"},"country_code":{"blank":"Please enter your country"}}},"enquiry":{"attributes":{"enquiry":{"above_limit":"You have none left for today."}}},"payout_authorisation":{"attributes":{"withdrawal_ids":{"required":"requires at least one to be selected"}}},"approve":{"attributes":{"company_address":{"blank":"Please enter a Billing address"}}}}}},"views":{"pagination":{"first":"First","last":"Last","previous":"Prev","next":"Next","truncate":"\u0026hellip;"}},"flash":{"favorites":{"create":{"success":"Added service to favorites","error":"Unable to add service to favorites"},"destroy":{"success":"Removed service from favorites","error":"Unable to remove service from favorites"}},"providers":{"new":{"provider_already_applied":"Complete your application to start selling by submitting a service","provider_already_applied_with_service":"Complete your application to start selling by submitting your service","provider_suspended":"You are not allowed to become a provider at this stage. Please contact support if you believe this is a mistake"}},"profiles":{"update":{"success":"Successfully updated your account settings"}},"disabled_user":"Your Envato Studio account has been disabled. Please contact Envato Studio support if you have any questions","job_events":{"request_invoice":{"success":"%{provider} has been sent a request to generate an invoice","error":"Unable to send a request to generate an invoice because %{errors}"}},"service":{"create":{"success":{"automatic":"Thanks for your submission! Your service is now live and available for order","manual":"Thanks for your submission!"}}},"first_service":{"create":{"success":"Thanks for your submission! Give yourself the best chance of success on Envato Studio by completing your profile now"}},"custom_job_proposals":{"create":{"success":"Your proposal has been submitted"},"counter":{"success":"Your proposal has been submitted"},"accept":{"success":"The proposal has been accepted"}},"job_cancelation_requests":{"create":{"error":"You cannot request a job cancelation"}},"job_queue_limit":{"success":"Your job queue limit has been updated."},"disputes":{"permission_error":"You can't raise a dispute at this time\""}},"sorting":{"recent":"newest","price_asc":"low price","price_desc":"high price","turnaround_asc":"turnaround","recommended":"recommended","favorites_count":"favorited","most_delivered":"deliveries","relevance":"relevance"},"authentication":{"failed":"Failed to authenticate. Please use an alternative sign in method.","requires_sign_in":"You need to be signed in to view this page","requires_sign_in_xhr":"You need to be signed in to perform this action","needs_to_be_provider":"You need to be a provider to view this page","sign_in_methods":{"password":"Successfully signed in","captcha":"Successfully signed in","two_factor":"Successfully signed in","sign_up":"Successfully signed up","password_reset":"Successfully signed in","account_update":"Successfully updated your account","already_authenticated":"Successfully signed in","confirmation_email":"Successfully signed up"},"error":"Sorry, unable to sign you in: %{message}","sign_out":"You have signed out","assume_sign_in":"You are now signed in as %{display_name}. Please be careful","assume_sign_out":"You are no longer signed in as %{display_name}"},"dispute":{"reasons":{"unresponsive_buyer":"Unresponsive buyer","unpleasant_buyer":"Unpleasant buyer","unpleasant_provider":"Unpleasant provider","unresponsive_provider":"Unresponsive provider","quality":"Quality of work","turnaround":"Turnaround time","provider_cancel":"Cancel by provider","admin_dispute":"Disputed by admin (cleanup)","other":"Other"}},"cancelation":{"reasons":{"quality":"Quality concerns","unresponsive_buyer":"Unresponsive buyer","unresponsive_provider":"Unresponsive provider","change_of_mind":"Change of mind","incorrect_service":"Incorrect service","sickness":"Sickness","leave":"On Leave","custom_job":"Custom Job","beyond_scope":"Beyond scope of service","other":"Other"}},"simple_form":{"labels":{"custom_job_proposal":{"price":"Price (USD)"},"brief":{"description":"Instructions","new_description":"\u003cp\u003eBe comprehensive. Include information, examples, files and images that will help the provider to get started on your job.\u003c/p\u003e","terms_of_service":"Terms and Conditions"},"timeline_event":{"body":"Message"},"service":{"name":"Service title","price":"Price (USD)","revision_requests":"Revisions","live_preview_url":"Demo","needs_from_buyer":"Briefing guidelines","further_info_for_reviewer":"Comment"},"user_profile":{"biography":"About you","twitter_username":"Twitter","facebook_username":"Facebook","flickr_username":"Flickr","pinterest_username":"Pinterest","dribbble_username":"Dribbble","linkedin_url":"LinkedIn URL","graphicriver_username":"GraphicRiver","threedeeocean_username":"3DOcean","themeforest_username":"ThemeForest","codecanyon_username":"CodeCanyon","tax_details":"Tax Information","company_address":"Company address","country_code":"Country","behance_username":"Behance"},"user_become_provider":{"biography":"Tell us your story and inspire our community to work with you.","application_verification_links_html":"Include your website, portfolio and places that you're already selling your products and services. Failure to include links will see your application rejected by the review team. \u003cstrong\u003eAnything you add here will remain private.\u003c/strong\u003e"},"user_confirmation":{"country_code":"Country"}},"hints":{"brief":{"CVV":"The CVV is a 3-digit number located on the\u003cbr/\u003e back of MasterCard and Visa credit cards."},"service":{"name":"Be descriptive, use less than %{max} characters and use Title Case e.g. High Quality Logo Design","category_description":"%{description} \u003ca href='/explore/%{url}'\u003eView examples\u003c/a\u003e","price":"Between $%{min} and $%{max} in $%{step} increments.","turnaround":"Target number of days to complete the job.","revision_requests":"Target number of submissions for the job.","description":"Be clear about what you're offering and why someone should buy this service. Use at least 300 characters; please don't include pricing, revision or turnaround info.","needs_from_buyer":"Tell your buyers what you need to get started. Please don't include pricing, revision or turnaround info.","live_preview_url":"Link to a working example of what your buyers will get, such as: http://www.myservice.com/demo","tags":"Separate each tag with a comma."},"custom_job_proposal":{"turnaround":"Target number of days to complete the job."},"user_profile":{"tax_number":"This will be displayed on invoices.","company_address":"This will be displayed on invoices.","company_name":"This will be displayed on invoices."},"dispute":{"unresponsive_buyer":"the buyer has been slow to respond to messages","unresponsive_provider":"the provider has been slow to respond to messages","turnaround":"the job has taken much longer than expected","quality":"the quality or nature of the work doesn't meet expectations","unpleasant_buyer":"there have been difficulties working together effectively","unpleasant_provider":"there have been difficulties working together effectively","provider_cancel":"the provider has canceled the job","admin_dispute":"envato support support unfinished job cleanup effort","other":"a miscellaneous issue","none":"none specified"},"cancelation":{"quality":"The quality of delivered items does not match meet your expectations","unresponsive_buyer":"The buyer has not been consistently responsive","unresponsive_provider":"The Provider has not been consistently responsive","change_of_mind":"This service is no longer required","incorrect_service":"This service does not meet your required needs or was purchased incorrectly","sickness":"You are currently unwell and unable to continue with this work - (Please pause your service during this time)","leave":"You are currently on leave and unable to continue this work - (Please pause your service during this time)","custom_job":"This job is beyond the scope of the initial listing and a custom job will be required","beyond_scope":"The buyers expectations are beyond the scope of the service listing - (Consider a custom job instead?)","other":"Cancelling this service for reasons not listed here"}}},"job_started_time":{"less_than_x_minutes":"\u003cstrong class='job__turnaround__count'\u003e%{count}\u003c/strong\u003e\u003cp class='job__turnaround__label'\u003eminute or so since started\u003c/p\u003e","x_minutes":{"one":"\u003cstrong class='job__turnaround__count'\u003e%{count}\u003c/strong\u003e\u003cp class='job__turnaround__label'\u003eminute since started\u003c/p\u003e","other":"\u003cstrong class='job__turnaround__count'\u003e%{count}\u003c/strong\u003e\u003cp class='job__turnaround__label'\u003eminutes since started\u003c/p\u003e"},"about_x_hours":{"one":"\u003cstrong class='job__turnaround__count'\u003e%{count}\u003c/strong\u003e\u003cp class='job__turnaround__label'\u003ehour since started\u003c/p\u003e","other":"\u003cstrong class='job__turnaround__count'\u003e%{count}\u003c/strong\u003e\u003cp class='job__turnaround__label'\u003ehours since started\u003c/p\u003e"},"x_days":{"one":"\u003cstrong class='job__turnaround__count'\u003e%{count}\u003c/strong\u003e\u003cp class='job__turnaround__label'\u003eday since started\u003c/p\u003e","other":"\u003cstrong class='job__turnaround__count'\u003e%{count}\u003c/strong\u003e\u003cp class='job__turnaround__label'\u003edays since started\u003c/p\u003e"},"about_x_months":"\u003cstrong class='job__turnaround__count'\u003e%{count}\u003c/strong\u003e\u003cp class='job__turnaround__label'\u003emonth or so since started\u003c/p\u003e","x_months":{"one":"\u003cstrong class='job__turnaround__count'\u003e%{count}\u003c/strong\u003e\u003cp class='job__turnaround__label'\u003emonth since started\u003c/p\u003e","other":"\u003cstrong class='job__turnaround__count'\u003e%{count}\u003c/strong\u003e\u003cp class='job__turnaround__label'\u003emonths since started\u003c/p\u003e"}},"order":{"websites_name":"My website's name","websites_address":"My website's address","websites_hosting":"My hosting panel details","wordpress-installation":"Hey %{user},\n\nThis is an Express WordPress Installation job from Envato Market, so your buyer is expecting a result within 24 hours!\n\nAll you need to do is:\n - Install the latest version of WordPress on your buyer's server\n - Install and activate your buyer's theme\n - Import any demo content included with the theme\n - Add your buyer's website name and logo to the site\n\nLet your buyer know when you start working. Envato Studio will re-assign this job if there's been no activity after 12 hours.\n","logo-customization":"Hey %{user},\n\nThis is an Express Logo Customization job from Envato Market, so your buyer is expecting a result within 24 hours!\n\nReview the brief above and get started. Please also let the buyer know when you commence work.\n\nEnvato Studio will re-assign this job if there's been no activity after 12 hours.\n","print-templates":"Hey %{user},\n\nThis is an Express Print Template Customization job from Envato Market, so your buyer is expecting a result within 24 hours!\n\nReview the brief above and get started. Please also let the buyer know when you commence work.\n\nEnvato Studio will re-assign this job if there's been no activity after 12 hours.\n"},"enquiry":{"create":{"success":"The service provider has been notified of your enquiry."},"placeholder":{"service":{"body":"Ask %{provider} a question about their service \"%{service}\" ..."},"provider":{"body":"Ask %{provider} a question ..."}},"denied":{"reasons":{"owner":"You cannot enquire about your own service.","limit":"You have none left for today."}}},"settings":{"job_queue_limit":"This limit applies to New and Doing jobs for which you are the provider."},"competition_feedback":{"create":{"success":"Thanks for providing feedback and entering the competition.","error":"Please provide all required information to enter the competition."}},"review":{"create":{"success":"Thanks for reviewing '%{service}'"},"respond":{"success":"Thanks for responding to the review"},"recommended":{"true":"%{display_name} recommends this service","false":"%{display_name} does not recommend this service"},"purchases":{"one":"has ordered 1 job","other":"has ordered %{count} jobs"}},"message":{"create":{"error":"Please add a message or attachment"}},"brief":{"denied":{"reasons":{"paused":"This service is currently unavailable.","owner":"You can't order your own service.","beta":"This service is not available yet."}}},"job":{"invoice":{"generated":{"generated":"Re-generate Invoice","not_generated":"Generate Invoice"}},"days_since_started":{"one":"day since started","other":"days since started"},"dispute_button":{"pending":"You can't dispute a job until it has started.","canceled":"You can't dispute a job once it has been canceled.","rejected":"You can't dispute a job once it has been declined.","disputed":"You can't dispute a job that has already been disputed.","dispute_refunded":"You can't dispute a job that has already been refunded.","dispute_paid":"You can't dispute a job that has already been finalized due to dispute.","closed":"You can't dispute a job once it has been closed.","ordered":"You can't dispute a job until it has been started.","done":"You can't dispute a job once it has been done."},"event_buttons":{"message":"Submit Message","start":"Start Job","reject":"Decline Job","submit_for_review":"Submit for Approval","submit_revision":"Submit Work","request_another_revision":"Request Revision","approve_revision":"Approve Work","cancel":"Cancel Job","agree_cancel":"Agree to Cancel Job","complete":"Complete Job","dispute":"Dispute Job","accept":"Accept Job","approve":"Approve Job","request_reopen":"Request Re-open","request_cancelation":"Request Cancelation","reopen_from_dispute":"Re-open Job"},"states":{"default_middle_step_label":"Doing","default_final_step_label":"Delivered","canceled":{"state":"Canceled","since":"Canceled %{time_ago} ago.","middle_step_label":"Canceled","help":{"provider":"Your buyer has canceled the job.","buyer":"You canceled the job and you will be refunded."}},"fraud_cancel":{"state":"Canceled","since":"Canceled %{time_ago} ago."},"completed":{"state":"Completed","since":"Completed %{time_ago} ago."},"in_progress":{"state":"Started","since":"Started %{time_ago} ago."},"in_review":{"state":"Awaiting Approval","since":"Submitted %{time_ago} ago."},"pending":{"state":"Pending","since":"Submitted %{time_ago} ago."},"rejected":{"state":"Declined","since":"Declined","middle_step_label":"Declined","help":{"provider":"You declined the job.","buyer":"Your provider has declined the job and you will be refunded."}},"revision_requested":{"state":"Revision Requested","since":"Requested %{time_ago} ago."},"waiting_for_completion":{"state":"Approved","since":"Approved %{time_ago} ago."},"disputed":{"state":"Disputed","since":"Disputed %{time_ago} ago.","middle_step_label":"Disputed","help":{"provider":"Your job has been disputed because %{reason}. Envato Studio support will investigate.","buyer":"Your job has been disputed because %{reason}. Envato Studio support will investigate."}},"dispute_refunded":{"state":"Refunded","since":"Refunded","middle_step_label":"Refunded","help":{"provider":"Envato Studio has resolved the dispute by canceling this job. As a result, the buyer will be refunded in full.","buyer":"Envato Studio has resolved the dispute by canceling this job. As a result, you will be refunded in full."}},"dispute_paid":{"state":"Resolved","since":"Resolved","final_step_label":"Resolved","help":{"provider":"Envato Studio has resolved the dispute by finalizing this job. As a result, you will be paid in full and all submitted work belongs to your buyer.","buyer":"Envato Studio has resolved the dispute by finalizing this job. As a result, all submitted work belongs to you and your provider will be paid in full."}},"fraudulent":{"state":"Canceled","middle_step_label":"Canceled","help":{"provider":"Envato Studio has terminated this job due to suspicious activity.","buyer":"Envato Studio has terminated this job due to suspicious activity."}},"closed":{"state":"Closed","since":"Closed %{time_ago} ago."},"ordered":{"state":"Ordered","since":"Ordered %{time_ago} ago.","help":{"provider":"Review your buyer's brief. Let them know if you need more info.","buyer":"Your provider needs to accept your brief."}},"doing":{"state":"Doing","since":"Started %{time_ago} ago.","help":{"provider":"You've accepted the job. Keep the buyer regularly updated.","buyer":"Your provider's working on it. Stay tuned for their updates and approve once done."}},"doing_with_timeout":{"help":{"provider":"This job will be marked as delivered in %{delivery_timeout} unless your buyer has further feedback.","buyer":"Your provider has submitted work. This job will be marked as delivered in %{delivery_timeout} unless you give further feedback."}},"delivered":{"state":"Delivered","since":"Delivered %{time_ago} ago.","help":{"provider":"Your buyer has approved the job. Your earnings will be updated in %{finalize_timeout}.","buyer":"You've approved the job. The job will be finalized in %{finalize_timeout}, so make sure you've got all the files you need."}},"auto_delivered":{"help":{"provider":"This job has been automatically marked as delivered because your buyer did not provide further feedback. Your earnings will be updated in %{finalize_timeout}.","buyer":"This job has been delivered because you did not provide further feedback. The job will be finalized in %{finalize_timeout}, so make sure you've got all the files you need. If this job isn't done and you need more time, please contact support as soon as you can."}},"done":{"state":"Done","since":"Completed %{time_ago} ago.","final_step_label":"Done","help":{"provider":"Your earnings have been updated.","buyer":"Your provider will be paid for the job."}},"fraud_done":{"state":"Done","since":"Completed %{time_ago} ago.","final_step_label":"Done","help":{"provider":"Your earnings have been updated.","buyer":"Your provider will be paid for the job."}},"reassigned":{"state":"Re-assigned","middle_step_label":"Re-assigned","help":{"provider":"The work has been re-assigned to another provider","buyer":"The work has been re-assigned to another provider"}}},"events":{"order":"Ordered","purchase":"Job purchased %{time_ago} ago.","start":"Started","reject":"Declined","submit_for_review":"Job submitted for approval %{time_ago} ago.","request_another_revision":"Revision requested %{time_ago} ago.","approve_revision":"Job approved %{time_ago} ago.","cancel":"Canceled","complete":"Job completed %{time_ago} ago.","dispute":"Disputed","close":"Job closed %{time_ago} ago.","reopen":"Job reopened %{time_ago} ago.","reopen_from_dispute":"Job re-opened","resolve_for_buyer":"Canceled","resolve_for_provider":"Closed","refund_dispute":"Refunded by Envato Studio","pay_dispute":"Resolved by Envato Studio","fraud_cancel":"Job canceled %{time_ago} ago.","request_invoice":"Invoice requested %{time_ago} ago.","submit_revision":"Work submitted","accept":"Accepted","approve":"Approved","auto_approve":"Delivered","finalize":"Finalized","request_cancelation":"Cancelation request","request_reopen":"Re-open request","secret":{"info_to_recipient":"You have been emailed the link to view this secret message. View our \u003ca href=\"https://envatostudio.zendesk.com/hc/en-us/articles/201932194\"\u003eFAQ\u003c/a\u003e for more details.","info_to_sender":"You have sent a secret message. View our \u003ca href=\"https://envatostudio.zendesk.com/hc/en-us/articles/201932194\"\u003eFAQ\u003c/a\u003e for more details.","decryption_failed":"The secret message could not be retrieved. Please ensure you have the correct link."},"reassign":"Re-assigned"},"machine":{"disputes":{"reopen":"Envato Studio has resolved the dispute by re-opening this job. We encourage you to work together using the remaining revisions to fulfill the original brief.","reopen_from_dispute":"Envato Studio has resolved the dispute by opening this job. We encourage you to work together to fulfill the original brief.","resolve_for_buyer":"Envato Studio has resolved the dispute by canceling this job. As a result, the buyer will be refunded in full.","refund_dispute":"Envato Studio has resolved the dispute by canceling this job. As a result, the buyer will be refunded in full.","resolve_for_provider":"Envato Studio has resolved the dispute by finalizing this job. As a result, all submitted work belongs to the buyer and the service provider will be paid in full.","pay_dispute":"Envato Studio has resolved the dispute by finalizing this job. As a result all submitted work belongs to the buyer and the service provider will be paid in full."},"fraud":{"canceled":"This job has been terminated due to suspicious activity."}},"modals":{"start":{"header":"Start Job","message":"Are you ready to start this job?","note":"Make sure you've been given an adequate brief first.","buttons":{"proceed":"Start Job","proceeding":"Starting Job. Please wait...","halt":"Cancel"}},"reject":{"header":"Decline Job","message":"Are you sure you want to decline this job?","note":"Job will be canceled and the buyer refunded.","buttons":{"proceed":"Decline Job","proceeding":"Declining Job. Please wait...","halt":"Cancel"}},"approve_revision":{"header":"Approve Work","message":"Do you want to approve the Provider's work?","note":"The Provider may still need to finalize the job with you.","buttons":{"proceed":"Approve Work","proceeding":"Approving Job. Please wait...","halt":"Cancel"}},"cancel_buyer":{"header":"Cancel Job","message":"Are you sure you want to cancel this job?","note":"You'll receive a refund, but the job won't be worked on any further.","buttons":{"proceed":"Cancel Job","proceeding":"Canceling Job. Please wait...","halt":"Continue Job"}},"cancel_provider":{"header":"Cancel Job","message":"Are you sure you want to cancel this job?","note":"The buyer will receive a refund, and the job will require no further work.","buttons":{"proceed":"Cancel Job","proceeding":"Canceling Job. Please wait...","halt":"Continue Job"}},"complete":{"header":"Complete Job","message":"Is the job really done?","note":"Make sure you have attached any final deliverables.","buttons":{"proceed":"Complete Job","proceeding":"Completing Job. Please wait...","halt":"Cancel"}},"dispute_buyer":{"header":"Raise Dispute","message":"Are you sure you would like to raise a dispute for this job?","note":"A member of the Envato Studio Support Team will read through your comments and the job timeline and contact you as soon as possible.\n\nYou will be able to communicate with the service provider while the job is in dispute, and will be able to re-open the job during this time.","buttons":{"proceed":"Raise Dispute","proceeding":"Please wait...","halt":"Cancel"}},"dispute_provider":{"header":"Raise Dispute","message":"Are you sure you would like to raise a dispute for this job?","note":"A member of the Envato Studio Support Team will read through your comments and the job timeline and contact you as soon as possible.\n\nYou will be able to communicate with the buyer while the job is in dispute, and will be able to re-open the job during this time.","buttons":{"proceed":"Raise Dispute","proceeding":"Please wait...","halt":"Cancel"}},"approve":{"header":"Approve Job","message":"Approving the job will confirm that the work is completed and your provider will be paid.","message_line_2":"Make sure you have everything you need from the provider before you approve.","billing_address_message":"We also need to confirm some of your details so that your provider can invoice you properly.","note":"","buttons":{"proceed":"Approve Job","proceeding":"Approving Job. Please wait...","halt":"Cancel"}}}},"provider":{"admin":{"status":{"not_submitted":"totally not fussed about the whole \"becoming a provider\" thing","submitted":"awaiting review and can't be seen by others","rejected":"rejected and can't be seen by others","approved":"approved","suspended":"suspended","provider_disabled":"is disabled becuase its provider is disabled"},"event_buttons":{"reject":"Reject","approve":"Approve","suspend":"Suspend"}}},"service":{"form_title":"Share the details of your service! Be clear about what you're offering, your style and approach, and what your buyer will get. See the \u003ca href='%{review_guide_path}'\u003eEnvato Studio review guide\u003c/a\u003e for tips on creating services that sell.","event_buttons":{"reject":"Reject","approve":"Approve","soft_delete":"Delete","quality_reject":"Reject"},"events":{"pause":"%{service_name} has successfully been paused.","unpause":"%{service_name} has successfully been unpaused."},"admin":{"status":{"pending":"not ready to be reviewed","submitted":"awaiting review and can't be seen by others","rejected":"rejected","quality_rejected":"rejected","available":"available","paused":"paused","deleted":"deleted (this service can't be seen by anyone except admins)","provider_disabled":"is disabled becuase its provider is disabled","auto_paused":"auto paused","suspended":"suspended"}},"states":{"submitted":"submitted","deleted":"deleted","available":"available","rejected":"rejected","quality_rejected":"rejected","paused":"paused","pending":"pending","auto_paused":"auto paused","reassigned":"reassigned","suspended":"suspended"},"pause_actions":{"pause":"Pause Service","resume":"Resume Service"},"delivered":{"one":"Deliveries \u003cstrong\u003e1\u003c/strong\u003e","other":"Deliveries \u003cstrong\u003e%{count}\u003c/strong\u003e"},"favorites":{"one":"\u003cstrong\u003e1\u003c/strong\u003e Favorite","other":"\u003cstrong\u003e%{count}\u003c/strong\u003e Favorites"},"purchases":{"edit":{"steps":{"basic_information":{"name":"Edit Your Service","description_html":["You can change any aspect of your service here except for its category.","To ensure consistency across the site, services may only be edited once every 48 hours, ensure your revisions are correct.","Your changes will go live on the completion of all four steps."]},"attachments":{"name":"Edit Your Service Examples","description_html":["Upload the best visual examples to represent your service.","This is your opportunity to demonstrate your abilities.","You must upload either 4,6 or 8 images.","Avoid using annotation."]},"review":{"name":"Review Your Edits","description_html":["Carefully review the edits you have made to your service.","You will be unable to make further edits to the service for 48 hours."]},"confirmation":{"name":"Service Edit Confirmation","description_html":["Thank you for taking the time to update your service."]}}}}},"account":{"my_earnings":{"no_earnings":"You don't have any earnings from closed jobs."},"my_jobs":{"archived":{"no_jobs":"You do not have any archived enquiries or proposals."},"providing":{"new":{"no_jobs":"You don't have any new jobs yet."},"doing":{"no_jobs":"You aren't working on any jobs."},"disputed":{"no_jobs":"You don't have any disputed jobs."},"done":{"no_jobs":"You haven't finished any jobs yet."},"prospective":{"no_jobs":"You don't have any new enquiries or proposals."}},"buying":{"new":{"no_jobs":"You don't have any new jobs yet."},"doing":{"no_jobs":"You have no jobs in progress. Go forth and \u003ca href=\"%{explore_path} \"\u003eexplore\u003c/a\u003e the different services on Envato Studio."},"disputed":{"no_jobs":"You don't have any disputed jobs."},"done":{"no_jobs":"You haven't finished any jobs yet. Go forth and \u003ca href=\"%{explore_path} \"\u003eexplore\u003c/a\u003e the different services on Envato Studio."},"prospective":{"no_jobs":"You have not made any enquiries or proposals."}}},"my_services":{"no_services":"\u003cp\u003eWelcome to the Envato Studio Beta!\u003c/p\u003e \u003cp\u003eGet started by reading our \u003ca href=\"https://envatostudio.zendesk.com/hc/en-us\"\u003eFAQ's\u003c/a\u003e, then move on to \u003ca href=\"%{new_service_path}\"\u003esubmit your first service\u003c/a\u003e for review!\u003c/p\u003e"},"favorites":{"no_favorites":"You have no favorites"}},"profile":{"editable_on_sso":"You can update your basic details using your Envato Account, follow the link below.","internal_social_links":{"graphicriver":"GraphicRiver","threedeeocean":"3DOcean","themeforest":"ThemeForest","codecanyon":"CodeCanyon"}},"become_provider":{"payment_service_labels":{"paypal":"PayPal","moneybookers":"Moneybookers/Skrill","payoneer":"Payoneer","other":"Other"}},"preview_service":{"edit":"Back","submit":{"true":"Submit","false":"Submit"}},"refund_reasons":{"canceled":"the job was canceled by the buyer","rejected":"the job was declined by the provider","disputed":"a dispute was resolved in favor of the buyer","fraud":"fraudulent activity was detected on the job"},"admin":{"category":{"featured":"%{category_name} is now featured","featured_remove":"%{category_name} has been removed from the featured list","error":{"no_featured_services":"%{category_name} needs at least one featured service to feature this category."}}},"automatic_payouts":{"button":{"pause":"Pause Automatic Payouts","resume":"Resume Automatic Payouts"},"confirm":{"pause":"Are you sure you want to Pause Automatic Payouts?","resume":"Are you sure you want to Resume Automatic Payouts?"}},"payout_authorisation":{"success":"Payout was successfully authorised","failure":"Unauthorized Access. Cowardly refusing to do anything."},"express_service_subscription":{"pause_actions":{"pause":"Pause Express Service","resume":"Resume Express Service"},"states":{"paused":"paused","available":"available","auto_paused":"auto paused"}}}};
(function() {
var CONTAINER_ERROR_CLASSES, CONTAINER_SELECTOR, ERROR_SELECTOR, EXCLUDED_FIELDS_SELECTOR, FIELDS_SELECTOR;
ERROR_SELECTOR = 'span.error';
CONTAINER_SELECTOR = 'div.input, .form__input-block';
CONTAINER_ERROR_CLASSES = 'field_with_errors';
FIELDS_SELECTOR = 'input, textarea, select';
EXCLUDED_FIELDS_SELECTOR = ':disabled';
Studio.ClientSideValidation = (function() {
function ClientSideValidation() {}
ClientSideValidation.validate = function($element) {
return (new Studio.ClientSideValidation()).validate($element);
};
ClientSideValidation.addError = function(elements) {
var $parent, element, _i, _len, _results;
elements = _.toArray(elements);
_results = [];
for (_i = 0, _len = elements.length; _i < _len; _i++) {
element = elements[_i];
$parent = jQuery(element).parents(CONTAINER_SELECTOR);
_results.push($parent.addClass(CONTAINER_ERROR_CLASSES));
}
return _results;
};
ClientSideValidation.removeError = function(elements) {
var $parent, element, _i, _len, _results;
elements = _.toArray(elements);
_results = [];
for (_i = 0, _len = elements.length; _i < _len; _i++) {
element = elements[_i];
$parent = jQuery(element).parents(CONTAINER_SELECTOR);
$parent.removeClass(CONTAINER_ERROR_CLASSES);
_results.push($parent.find(ERROR_SELECTOR).remove());
}
return _results;
};
ClientSideValidation.validationEnabled = function($element) {
return $element.closest('form').hasClass('has-validation');
};
ClientSideValidation.prototype.ready = function() {
var $document;
this.parslify($('form'));
$document = jQuery(document);
$document.on("ajax:before", "form[data-remote=true]", (function(_this) {
return function(event) {
return _this.validate(jQuery(event.target));
};
})(this));
return $document.on("submit", "form[data-remote!=true]", (function(_this) {
return function(event) {
var e;
try {
if (!_this.validate(jQuery(event.target))) {
event.preventDefault();
return event.stopImmediatePropagation();
}
} catch (_error) {
e = _error;
event.preventDefault();
throw e;
}
};
})(this));
};
ClientSideValidation.prototype.validate = function($element) {
var $fieldsToValidate, $form, field, valid, _i, _len;
valid = true;
$form = $element.closest('form');
this.parslify($form);
$fieldsToValidate = $element.is('form') || $element.is(FIELDS_SELECTOR) ? $element : $element.find(FIELDS_SELECTOR).not(EXCLUDED_FIELDS_SELECTOR);
for (_i = 0, _len = $fieldsToValidate.length; _i < _len; _i++) {
field = $fieldsToValidate[_i];
if (jQuery(field).parsley('validate') === false) {
valid = false;
}
}
return valid;
};
ClientSideValidation.prototype.parslify = function($form) {
$form.parsley('destroy');
$form.parsley({
animate: false,
excluded: EXCLUDED_FIELDS_SELECTOR,
trigger: 'blur',
validators: {
multiple: function(val, multiple) {
return val % multiple === 0;
},
remote: function() {},
type: function() {}
},
errorMessage: (function(_this) {
return function(constraint, parsleyField) {
if (constraint.name === 'ajax_validator') {
return constraint.lastErrorMessage;
} else {
return _this.errorMessage(parsleyField.$element.first(), constraint.name);
}
};
})(this),
listeners: {
onFieldError: (function(_this) {
return function(element, constraints, parsleyField) {
return Studio.ClientSideValidation.addError(element);
};
})(this),
onFieldSuccess: (function(_this) {
return function(element, constraints, parsleyField) {
return Studio.ClientSideValidation.removeError(element);
};
})(this)
},
errors: {
errorsWrapper: "",
errorElem: ""
}
});
$form.off('submit.parsleyForm');
return $form.addClass('has-validation');
};
ClientSideValidation.prototype.errorMessage = function($element, errorName) {
var i18n, interpolations, key;
i18n = (function() {
switch (errorName) {
case "required":
return "blank";
case "luhn":
return "invalid";
case "equalto":
return "confirmation";
case "regexp":
return "invalid";
case "max":
return [
"less_than_or_equal_to", {
count: $element.attr('max')
}
];
case "min":
return [
"greater_than_or_equal_to", {
count: $element.attr('min')
}
];
case "maxlength":
return [
"too_long", {
count: $element.data('maxlength')
}
];
case "minlength":
return [
"too_short", {
count: $element.data('minlength')
}
];
case "multiple":
return [
"step_mismatch", {
step: $element.data('multiple')
}
];
case "integer_validator":
return "not_an_integer";
default:
throw "No Parsley I18n mapping for " + errorName;
}
})();
if (_.isArray(i18n)) {
key = i18n[0];
interpolations = i18n[1];
} else {
key = i18n;
}
return Studio.I18nValidationError.messageFromInput($element, key, interpolations);
};
return ClientSideValidation;
})();
}).call(this);
(function() {
Studio.ErrorTracker = (function() {
function ErrorTracker() {}
ErrorTracker.configure = function(config) {
this.config = config;
if (config.user != null) {
Raven.setUser(config.user);
}
Raven.config(config.raven, {
dataCallback: function(data) {
data['sentry.interfaces.Http'].env = {
'REMOTE_ADDR': config.ip
};
return data;
}
});
return this.configured = true;
};
ErrorTracker.notify = function(name, extra, tags) {
if (extra == null) {
extra = {};
}
if (tags == null) {
tags = {};
}
if (this.configured) {
tags = _.extend(tags, {
ip: this.config.ip
});
return Raven.captureMessage(name, {
extra: extra,
tags: tags
});
}
};
return ErrorTracker;
})();
}).call(this);
(function() {
Studio.FlashFileHandler = (function() {
FlashFileHandler.id = 0;
function FlashFileHandler(options) {
this.options = options;
this._queue = [];
this._uploading = false;
}
FlashFileHandler.prototype.cancel = function(file) {
return this.swfUpload.stopUpload(file.id);
};
FlashFileHandler.prototype.start = function(file, data) {
if (this._uploading) {
return this._queue.push({
file: file,
data: data
});
} else {
this._uploading = true;
return this._start(file, data);
}
};
FlashFileHandler.prototype._start = function(file, data) {
var key, value;
for (key in data) {
value = data[key];
this.swfUpload.addPostParam(key, value);
}
return this.swfUpload.startUpload(file.id);
};
FlashFileHandler.prototype._processQueue = function() {
var item;
if (this._queue.length) {
item = this._queue.pop();
return this.start(item.file, item.data);
}
};
FlashFileHandler.prototype.ready = function() {
var $button, id, multiple, text;
$button = jQuery(this.options.button);
id = $button.attr('id');
text = $button.data('flash-button-text') || 'Attach Files';
multiple = $button.find('input[type=file]').attr('multiple');
if (!id) {
id = "flash-button-" + (++Studio.FlashFileHandler.id);
$button.attr('id', id);
}
return this.swfUpload = new SWFUpload({
flash_url: this.options.flashUrl,
file_size_limit: "500 MB",
file_types: "*.*",
debug: false,
upload_url: this.options.endpoint,
button_placeholder_id: id,
button_text: text,
button_text_style: '.btn {font-family: sans-serif; font-size: 14px; color: #19aacf}',
button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
button_image_url: Studio.assets.swfuploadButton,
button_width: 85,
button_height: 18,
button_cursor: this._buttonCursor(),
button_action: this._buttonAction(multiple),
http_success: [201, 303, 200],
file_post_name: "file",
swfupload_load_failed_handler: (function(_this) {
return function() {
alert("File uploads are disabled because you don't have flash installed. Please install before proceeding.\n\nGo to Google, and search for \"install flash\" for instructions.");
return $button.hide();
};
})(this),
file_queued_handler: (function(_this) {
return function(file) {
return _this.trigger('queued', {
id: file.id,
name: file.name,
size: file.size
});
};
})(this),
upload_complete_handler: (function(_this) {
return function(file) {
_this._uploading = false;
return _this._processQueue();
};
})(this),
upload_success_handler: (function(_this) {
return function(file, data, response) {
return _this.trigger('finished', file.id, data);
};
})(this),
upload_error_handler: (function(_this) {
return function(file, errorCode, message) {
var errors;
errors = _.invert(SWFUpload.UPLOAD_ERROR);
return _this.trigger('error', file.id, "" + message + " (" + errors[errorCode] + ")");
};
})(this),
upload_progress_handler: (function(_this) {
return function(file, size, total) {
return _this.trigger('progress', file.id, Math.ceil((size / total) * 100));
};
})(this)
});
};
FlashFileHandler.prototype._buttonAction = function(multiple) {
if (multiple) {
return SWFUpload.BUTTON_ACTION.SELECT_FILES;
} else {
return SWFUpload.BUTTON_ACTION.SELECT_FILE;
}
};
FlashFileHandler.prototype._buttonCursor = function() {
return SWFUpload.CURSOR.HAND;
};
return FlashFileHandler;
})();
_.extend(Studio.FlashFileHandler.prototype, Backbone.Events);
}).call(this);
(function() {
Studio.HTML5FileHandler = (function() {
function HTML5FileHandler(options) {
this.options = options;
this._files = {};
this._xhr = {};
}
HTML5FileHandler.prototype.ready = function() {
var dropzone;
dropzone = jQuery(this.options.dropzone);
dropzone.on({
'dragover': (function(_this) {
return function(e) {
_this.hovering = true;
return dropzone.addClass('file-hovering');
};
})(this),
'dragleave': (function(_this) {
return function(e) {
_this.hovering = false;
return setTimeout(function() {
if (_this.hovering === false) {
return dropzone.removeClass('file-hovering');
}
}, 10);
};
})(this),
'drop': (function(_this) {
return function(e) {
var file, _i, _len, _ref, _results;
dropzone.removeClass('file-hovering');
e.preventDefault();
e.stopPropagation();
_ref = e.originalEvent.dataTransfer.files;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
file = _ref[_i];
_results.push(_this.queue(file));
}
return _results;
};
})(this)
});
jQuery(document.body).on('drop', (function(_this) {
return function(e) {
return e.preventDefault();
};
})(this));
jQuery(document.body).on('dragover', (function(_this) {
return function(e) {
return e.preventDefault();
};
})(this));
return jQuery(this.options.button).find('input[type=file]').on('change', (function(_this) {
return function(e) {
var $fileInput, copyEvents, file, _i, _len, _ref;
$fileInput = jQuery(e.target);
_ref = $fileInput[0].files;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
file = _ref[_i];
_this.queue(file);
}
return $fileInput.replaceWith($fileInput.val('').clone(copyEvents = true));
};
})(this));
};
HTML5FileHandler.prototype.cancel = function(file) {
var xhr;
if (this._xhr[file.id] != null) {
xhr = this._xhr[file.id];
xhr.abort();
return this._cleanup(file);
}
};
HTML5FileHandler.prototype.start = function(file, data) {
var formData, key, value, xhr;
formData = new FormData();
formData.append('Filename', file.name);
for (key in data) {
value = data[key];
formData.append(key, value);
}
formData.append('file', this._files[file.id]);
this._xhr[file.id] = xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", (function(_this) {
return function(e) {
if (e.lengthComputable) {
return _this.trigger('progress', file.id, Math.floor((e.loaded / e.total) * 100));
}
};
})(this));
xhr.addEventListener("load", (function(_this) {
return function(e) {
var error, message;
if (xhr.status === 200 || xhr.status === 201) {
_this.trigger('finished', file.id, xhr.responseText);
} else {
message = (function() {
try {
return jQuery(xhr.responseText).find('Message').text();
} catch (_error) {
error = _error;
return "Upload failed. Try again or contact us.";
}
})();
_this.trigger('error', file.id, message, xhr);
}
return _this._cleanup(file);
};
})(this));
xhr.onerror = (function(_this) {
return function() {
return _this.trigger('error', file.id, "Upload failed. Try again or contact us.", xhr);
};
})(this);
xhr.open("POST", this.options.endpoint, true);
return xhr.send(formData);
};
HTML5FileHandler.prototype.queue = function(file) {
var attributes;
attributes = {
id: _.uniqueId(),
name: file.name,
size: file.size
};
this._files[attributes.id] = file;
if (/image\/(jpg|jpeg|png|gif)/i.test(file.type)) {
return setTimeout((function(_this) {
return function() {
return _this._readFile(file, function(preview) {
var img;
img = new Image;
img.onload = function() {
attributes.image = true;
attributes.width = img.width;
attributes.height = img.height;
return _this.trigger('queued', attributes);
};
img.onerror = function() {
attributes.image = true;
attributes.width = null;
attributes.height = null;
return _this.trigger('queued', attributes);
};
return img.src = preview;
});
};
})(this), 0);
} else {
return this.trigger('queued', attributes);
}
};
HTML5FileHandler.prototype._readFile = function(file, callback) {
var reader;
reader = new FileReader();
reader.onload = (function(_this) {
return function(e) {
return callback(e.target.result);
};
})(this);
return reader.readAsDataURL(file);
};
HTML5FileHandler.prototype._cleanup = function(file) {
return delete this._xhr[file.id];
};
return HTML5FileHandler;
})();
_.extend(Studio.HTML5FileHandler.prototype, Backbone.Events);
}).call(this);
(function() {
Studio.I18nValidationError = {
messageFromInput: function($element, key, interpolations) {
var $form, attr, attribute, attributes, model, name;
if (interpolations == null) {
interpolations = {};
}
$form = jQuery($element[0].form);
name = $element.attr('name');
model = $element.data('i18n-model') || $form.data('i18n-model') || (name && name.match(/^([^\[]*)/g));
attribute = $element.data('i18n-attribute');
if (!attribute && name) {
attributes = (function() {
var _i, _len, _ref, _results;
_ref = name.match(/\[([^\]]+)\]/g);
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
attr = _ref[_i];
_results.push(attr.replace(/(\[|\])/g, ''));
}
return _results;
})();
attribute = _.last(attributes);
}
if (!key) {
throw new Error("Can't find translation for `" + model + "/" + name + "/" + attribute + "/" + key + "`");
}
return this.lookupMessage(model, attribute, key, interpolations);
},
lookupMessage: function(model, attribute, error, interpolations) {
var found, message, scope, scopes, _i, _len;
if (interpolations == null) {
interpolations = {};
}
scopes = ["activemodel.errors.models." + model + ".attributes." + attribute + "." + error, "activemodel.errors.models." + model + "." + error, "activemodel.errors.messages." + error, "activerecord.errors.models." + model + ".attributes." + attribute + "." + error, "activerecord.errors.models." + model + "." + error, "activerecord.errors.messages." + error, "errors.attributes." + attribute + "." + error, "errors." + attribute + "." + error, "errors.messages." + error];
message = null;
for (_i = 0, _len = scopes.length; _i < _len; _i++) {
scope = scopes[_i];
if (found = I18n.lookup(scope)) {
message = I18n.interpolate(found, interpolations);
break;
}
}
return message;
}
};
}).call(this);
(function() {
Studio.LoadingBar = (function() {
function LoadingBar() {
$(document).on('page:fetch', function() {
return NProgress.start();
});
$(document).on('page:change', function() {
return NProgress.done();
});
$(document).on('page:restore', function() {
return NProgress.remove();
});
}
return LoadingBar;
})();
}).call(this);
(function() {
Studio.Module = (function() {
function Module() {}
Module.prototype.ready = function() {};
return Module;
})();
_.extend(Studio.Module.prototype, Backbone.Events);
}).call(this);
(function() {
Studio.Money = {
centsToDollars: function(cents) {
return cents / 100.0;
},
formatCentsInDollars: function(cents) {
var dollars;
dollars = this.centsToDollars(cents);
return I18n.toCurrency(dollars);
}
};
}).call(this);
(function() {
Studio.NullDispatcher = (function() {
function NullDispatcher() {}
NullDispatcher.prototype.subscribe = function(channel) {};
return NullDispatcher;
})();
}).call(this);
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Studio.ProxyView = (function(_super) {
__extends(ProxyView, _super);
ProxyView.prototype.requirements = [];
function ProxyView() {
Backbone.View.apply(this, arguments);
this._validateExistanceOfElement();
this._validateRequiredHTML();
}
ProxyView.prototype.ready = function() {};
ProxyView.prototype.$requirement = function(key) {
var value;
value = this._requirements()[key];
if (!value) {
throw "Unknown requirement `" + key + "` for proxy view `" + this.constructor.name + "`";
}
return this.$el.find(value);
};
ProxyView.toString = function() {
return this.name;
};
ProxyView.prototype._requirements = function() {
if (_.isFunction(this.requirements)) {
return this.requirements();
} else {
return this.requirements;
}
};
ProxyView.prototype._validateExistanceOfElement = function() {
if (this.$el.length === 0) {
throw "" + this.constructor.name + " - Could not find proxy view element. " + this.options.el;
}
};
ProxyView.prototype._validateRequiredHTML = function() {
var failed, selector, _i, _len, _ref;
failed = [];
_ref = _.values(this._requirements());
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
selector = _ref[_i];
if (this.$el.find(selector).length === 0) {
failed.push(selector);
}
}
if (failed.length) {
throw "" + this.constructor.name + " - Missing HTML elements: " + (failed.join(', '));
}
};
return ProxyView;
})(Backbone.View);
}).call(this);
(function() {
Studio.PusherMessageDispatcher = (function() {
function PusherMessageDispatcher() {
this.channels = [];
$(document).on('page:fetch', (function(_this) {
return function() {
return _this.unsubscribeAll();
};
})(this));
}
PusherMessageDispatcher.prototype.subscribe = function(channel) {
if (this._hasNoChannels()) {
this._connect();
}
this.channels.push(channel);
return this.socket.subscribe(channel);
};
PusherMessageDispatcher.prototype.unsubscribeAll = function() {
var channel, channels, _i, _len, _results;
channels = this.channels;
_results = [];
for (_i = 0, _len = channels.length; _i < _len; _i++) {
channel = channels[_i];
_results.push(this.unsubscribe(channel));
}
return _results;
};
PusherMessageDispatcher.prototype.unsubscribe = function(channel) {
this.socket.unsubscribe(channel);
this.channels.pop(channel);
if (this._hasNoChannels()) {
return this._disconnect();
}
};
PusherMessageDispatcher.prototype.isSubscribed = function(channel) {
return this.channels.indexOf(channel) > -1;
};
PusherMessageDispatcher.prototype._connect = function() {
this.socket = new Pusher(this._pusherKey());
return this.socket.bind_all(function(event, data) {
return Studio.trigger(event, data);
});
};
PusherMessageDispatcher.prototype._disconnect = function() {
if (this.socket != null) {
return this.socket.disconnect();
}
};
PusherMessageDispatcher.prototype._pusherKey = function() {
return $('meta[name="pusher-key"]').attr('content');
};
PusherMessageDispatcher.prototype._hasNoChannels = function() {
return this.channels.length === 0;
};
return PusherMessageDispatcher;
})();
}).call(this);
(function() {
Studio.TaxCalculator = (function() {
function TaxCalculator(options) {
this.options = options;
this.totalInCents = this.options.totalInCents;
this.taxPercentage = this.options.taxPercentage;
}
TaxCalculator.prototype.taxInCents = function() {
return Math.max(this.totalInCents - (this.totalInCents / (1 + this.taxPercentage / 100.0)), 0.0);
};
TaxCalculator.prototype.totalMinusTaxInCents = function() {
return Math.max(this.totalInCents - this.taxInCents(), 0.0);
};
return TaxCalculator;
})();
}).call(this);
(function() {
Studio.Url = (function() {
function Url(url) {
var parts, _ref;
this.url = url;
parts = this.url.split("?");
if (parts.length === 2) {
this.query = parts[1];
if (_.indexOf(this.query, "#") >= 0) {
_ref = this.query.split('#'), this.query = _ref[0], this.anchor = _ref[1];
}
}
}
Url.prototype.schema = function() {
var parts;
parts = this.url.match(/^(https?):\/\//);
if (parts != null) {
return parts[1];
}
};
Url.prototype.hostWithPort = function() {
var parts;
parts = this.url.match(/(https?:)?\/\/([^\/]+)\/?/);
if (parts != null) {
return parts[2];
}
};
Url.prototype.params = function() {
var key, obj, pair, value, _i, _len, _ref, _ref1;
obj = {};
if (this.query) {
_ref = this.query.split("&");
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
pair = _ref[_i];
_ref1 = pair.split("="), key = _ref1[0], value = _ref1[1];
if (value != null) {
obj[key] = this._decodeQueryStringValue(value);
}
}
}
return obj;
};
Url.prototype.encode = function() {
var filename, urlParts;
urlParts = this.url.split('/');
filename = urlParts[urlParts.length - 1];
urlParts[urlParts.length - 1] = encodeURIComponent(filename);
return urlParts.join('/');
};
Url.prototype._decodeQueryStringValue = function(value) {
var str;
str = decodeURIComponent(value.replace(/\+/g, " "));
if (str === "true") {
return true;
} else if (str === "false") {
return false;
} else {
return str;
}
};
return Url;
})();
}).call(this);
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Studio.Attachment = (function(_super) {
__extends(Attachment, _super);
function Attachment() {
return Attachment.__super__.constructor.apply(this, arguments);
}
Attachment.prototype.defaults = {
persisted: false,
progress: 0,
queued: false,
uploaded: false,
deleted: false,
processing: false,
extensions: []
};
Attachment.prototype.initialize = function() {
this.on('change', (function(_this) {
return function() {
if (_this.get('uploaded') === true) {
if (_this.attributes.remoteUrl && !_this.attributes.url) {
return _this.attributes.url = new Studio.Url(_this.attributes.remoteUrl).encode();
}
}
};
})(this));
return this.on('change:processing', (function(_this) {
return function(model, processing) {
if (processing) {
return $(document).trigger('upload:start');
} else {
return $(document).trigger('upload:complete');
}
};
})(this));
};
Attachment.prototype.valid = function() {
if (this.get('size') >= 524288000) {
this.set('error', "File too large!");
return false;
} else if (this.get('extensions').length > 0 && !this._validExtensionsRegex().test(this.get('name'))) {
this.set('error', "File type not allowed!");
return false;
} else {
return true;
}
};
Attachment.prototype._validExtensionsRegex = function() {
return new RegExp(".*\.(" + this.get('extensions').join('|') + ")$", "i");
};
return Attachment;
})(Backbone.Model);
}).call(this);
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Studio.BaseAsset = (function(_super) {
__extends(BaseAsset, _super);
function BaseAsset() {
return BaseAsset.__super__.constructor.apply(this, arguments);
}
BaseAsset.prototype.asset = function(variant) {
var variants;
variants = _.select(this.variants(), function(item) {
return item.name === variant;
});
return variants[0];
};
BaseAsset.prototype.valid = function() {
return this.variants().length > 0;
};
BaseAsset.prototype.variants = function() {
return this.get('variants') || [];
};
return BaseAsset;
})(Backbone.Model);
}).call(this);
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Studio.Category = (function(_super) {
__extends(Category, _super);
function Category() {
return Category.__super__.constructor.apply(this, arguments);
}
return Category;
})(Backbone.Model);
}).call(this);
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Studio.MessageAsset = (function(_super) {
__extends(MessageAsset, _super);
function MessageAsset() {
return MessageAsset.__super__.constructor.apply(this, arguments);
}
MessageAsset.prototype.originalAsset = function() {
return this.asset(':original');
};
MessageAsset.prototype.thumbnailAsset = function() {
return this.asset('thumbnail');
};
return MessageAsset;
})(Studio.BaseAsset);
}).call(this);
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Studio.ProviderGalleryAsset = (function(_super) {
__extends(ProviderGalleryAsset, _super);
function ProviderGalleryAsset() {
return ProviderGalleryAsset.__super__.constructor.apply(this, arguments);
}
ProviderGalleryAsset.prototype.originalAsset = function() {
return this.asset(':original');
};
ProviderGalleryAsset.prototype.largeAsset = function() {
return this.asset('large') || this.asset(':original');
};
ProviderGalleryAsset.prototype.serviceCardAsset = function() {
return this.asset('thumbnail') || this.asset(':original');
};
ProviderGalleryAsset.prototype.assetId = function() {
return this.get('id');
};
ProviderGalleryAsset.prototype.assetUrl = function() {
return this.serviceCardAsset().url;
};
ProviderGalleryAsset.prototype.assetLargeUrl = function() {
return this.largeAsset().url;
};
return ProviderGalleryAsset;
})(Studio.BaseAsset);
}).call(this);
(function() {
Handlebars.registerHelper("formatFileSize", function(size) {
if (typeof size !== 'number') {
return;
}
if (size >= 1000000000) {
return "" + ((size / 1000000000).toFixed(2)) + " GB";
} else if (size >= 1000000) {
return "" + ((size / 1000000).toFixed(2)) + " MB";
} else {
return "" + ((size / 1000).toFixed(2)) + " KB";
}
});
}).call(this);
(function() {
Studio.Utils = (function() {
function Utils() {}
Utils.getLink = function(name, links) {
var matchedLinks;
matchedLinks = _.select(links, function(item) {
return item.name === name;
});
return matchedLinks[0];
};
return Utils;
})();
}).call(this);
(function() {
Handlebars.registerHelper('pluralize', function(number, single, plural) {
if (number === 1) {
return single;
} else {
return plural;
}
});
}).call(this);
(function() {
Handlebars.registerHelper('simpleFormat', function(text) {
var carriage_returns, newline, paragraphs;
carriage_returns = /\r\n?/g;
paragraphs = /\n\n+/g;
newline = /([^\n]\n)(?=[^\n])/g;
text = text.replace(carriage_returns, "\n");
text = text.replace(paragraphs, "