diff --git a/app/build.gradle b/app/build.gradle index 93a67824e..a338e1fea 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,13 +3,13 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { - compileSdkVersion 26 - buildToolsVersion "26.0.2" + compileSdkVersion 27 + buildToolsVersion "27.0.1" defaultConfig { applicationId "com.simplemobiletools.calendar" minSdkVersion 16 - targetSdkVersion 26 + targetSdkVersion 27 versionCode 100 versionName "2.9.2" multiDexEnabled true @@ -40,16 +40,16 @@ android { } ext { - leakCanaryVersion = '1.5.2' + leakCanaryVersion = '1.5.4' } dependencies { - compile 'com.simplemobiletools:commons:2.36.2' - compile 'joda-time:joda-time:2.9.1' - compile 'com.facebook.stetho:stetho:1.4.1' + compile 'com.simplemobiletools:commons:2.37.1' + compile 'joda-time:joda-time:2.9.9' + compile 'com.facebook.stetho:stetho:1.5.0' compile 'com.bignerdranch.android:recyclerview-multiselect:0.2' - compile 'com.android.support:multidex:1.0.1' - compile 'com.google.code.gson:gson:2.8.0' + compile 'com.android.support:multidex:1.0.2' + compile 'com.google.code.gson:gson:2.8.2' compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" debugCompile "com.squareup.leakcanary:leakcanary-android:$leakCanaryVersion" diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/extensions/Context.kt index 7ec543b41..f13aa8abc 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/extensions/Context.kt @@ -14,7 +14,7 @@ import android.graphics.Color import android.graphics.PorterDuff import android.net.Uri import android.os.Build -import android.support.v7.app.NotificationCompat +import android.support.v4.app.NotificationCompat import android.view.Gravity import android.view.View import android.view.ViewGroup @@ -96,10 +96,11 @@ fun Context.scheduleEventIn(notifTS: Long, event: Event) { val pendingIntent = getNotificationIntent(applicationContext, event) val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager - if (isKitkatPlus()) + if (isKitkatPlus()) { alarmManager.setExact(AlarmManager.RTC_WAKEUP, notifTS, pendingIntent) - else + } else { alarmManager.set(AlarmManager.RTC_WAKEUP, notifTS, pendingIntent) + } } fun Context.cancelNotification(id: Int) { diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/DayFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/DayFragment.kt index 10e37b2d1..5504d9beb 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/DayFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/DayFragment.kt @@ -46,8 +46,8 @@ class DayFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEventsListen mRes = resources mHolder = view.day_holder - mDayCode = arguments.getString(DAY_CODE) - val day = Formatter.getDayTitle(activity.applicationContext, mDayCode) + mDayCode = arguments!!.getString(DAY_CODE) + val day = Formatter.getDayTitle(context!!, mDayCode) mHolder.top_value.apply { text = day setOnClickListener { pickDay() } @@ -64,7 +64,7 @@ class DayFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEventsListen } private fun setupButtons() { - mTextColor = context.config.textColor + mTextColor = context!!.config.textColor mHolder.apply { top_left_arrow.drawable.mutate().setColorFilter(mTextColor, PorterDuff.Mode.SRC_ATOP) @@ -83,14 +83,14 @@ class DayFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEventsListen } private fun pickDay() { - activity.setTheme(context.getAppropriateTheme()) - val view = getLayoutInflater(arguments).inflate(R.layout.date_picker, null) + activity!!.setTheme(context!!.getAppropriateTheme()) + val view = layoutInflater.inflate(R.layout.date_picker, null) val datePicker = view.findViewById(R.id.date_picker) val dateTime = Formatter.getDateTimeFromCode(mDayCode) datePicker.init(dateTime.year, dateTime.monthOfYear - 1, dateTime.dayOfMonth, null) - AlertDialog.Builder(context) + AlertDialog.Builder(context!!) .setNegativeButton(R.string.cancel, null) .setPositiveButton(R.string.ok) { dialog, which -> positivePressed(dateTime, datePicker) } .create().apply { @@ -109,7 +109,7 @@ class DayFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEventsListen fun checkEvents() { val startTS = Formatter.getDayStartTS(mDayCode) val endTS = Formatter.getDayEndTS(mDayCode) - DBHelper.newInstance(context, this).getEvents(startTS, endTS) { + DBHelper.newInstance(context!!, this).getEvents(startTS, endTS) { receivedEvents(it) } } @@ -121,7 +121,7 @@ class DayFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEventsListen } lastHash = newHash - val replaceDescription = context.config.replaceDescription + val replaceDescription = context!!.config.replaceDescription val sorted = ArrayList(events.sortedWith(compareBy({ it.startTS }, { it.endTS }, { it.title }, { if (replaceDescription) it.location else it.description }))) @@ -142,13 +142,13 @@ class DayFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEventsListen } mHolder.day_events.adapter = eventsAdapter DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply { - setDrawable(context.resources.getDrawable(R.drawable.divider)) + setDrawable(context!!.resources.getDrawable(R.drawable.divider)) mHolder.day_events.addItemDecoration(this) } } private fun editEvent(event: Event) { - Intent(activity.applicationContext, EventActivity::class.java).apply { + Intent(context, EventActivity::class.java).apply { putExtra(EVENT_ID, event.id) putExtra(EVENT_OCCURRENCE_TS, event.startTS) startActivity(this) @@ -157,12 +157,12 @@ class DayFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEventsListen override fun deleteItems(ids: ArrayList) { val eventIDs = Array(ids.size, { i -> (ids[i].toString()) }) - DBHelper.newInstance(activity.applicationContext, this).deleteEvents(eventIDs, true) + DBHelper.newInstance(context!!, this).deleteEvents(eventIDs, true) } override fun addEventRepeatException(parentIds: ArrayList, timestamps: ArrayList) { parentIds.forEachIndexed { index, value -> - context.dbHelper.addEventRepeatException(parentIds[index], timestamps[index]) + context!!.dbHelper.addEventRepeatException(parentIds[index], timestamps[index]) } (activity as DayActivity).recheckEvents() } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/EventListFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/EventListFragment.kt index d17857395..904a96f73 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/EventListFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/EventListFragment.kt @@ -35,8 +35,8 @@ class EventListFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEvents private var lastHash = 0 lateinit var mView: View - override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { - mView = inflater!!.inflate(R.layout.fragment_event_list, container, false) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + mView = inflater.inflate(R.layout.fragment_event_list, container, false) val placeholderText = String.format(getString(R.string.two_string_placeholder), "${getString(R.string.no_upcoming_events)}\n", getString(R.string.add_some_events)) mView.calendar_empty_list_placeholder.text = placeholderText return mView @@ -48,9 +48,9 @@ class EventListFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEvents } private fun checkEvents() { - val fromTS = DateTime().seconds() - context.config.displayPastEvents * 60 + val fromTS = DateTime().seconds() - context!!.config.displayPastEvents * 60 val toTS = DateTime().plusYears(1).seconds() - context.dbHelper.getEvents(fromTS, toTS) { + context!!.dbHelper.getEvents(fromTS, toTS) { receivedEvents(it) } } @@ -69,7 +69,7 @@ class EventListFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEvents } lastHash = newHash - val filtered = context.getFilteredEvents(events) + val filtered = context!!.getFilteredEvents(events) val hash = filtered.hashCode() if (prevEventsHash == hash) return @@ -77,14 +77,14 @@ class EventListFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEvents prevEventsHash = hash mEvents = filtered val listItems = ArrayList(mEvents.size) - val replaceDescription = context.config.replaceDescription + val replaceDescription = context!!.config.replaceDescription val sorted = mEvents.sortedWith(compareBy({ it.startTS }, { it.endTS }, { it.title }, { if (replaceDescription) it.location else it.description })) val sublist = sorted.subList(0, Math.min(sorted.size, 100)) var prevCode = "" sublist.forEach { val code = Formatter.getDayCodeFromTS(it.startTS) if (code != prevCode) { - val day = Formatter.getDayTitle(context, code) + val day = Formatter.getDayTitle(context!!, code) listItems.add(ListSection(day)) prevCode = code } @@ -106,11 +106,11 @@ class EventListFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEvents mView.calendar_empty_list_placeholder.beVisibleIf(mEvents.isEmpty()) mView.calendar_events_list.beGoneIf(mEvents.isEmpty()) if (activity != null) - mView.calendar_empty_list_placeholder.setTextColor(activity.config.textColor) + mView.calendar_empty_list_placeholder.setTextColor(activity!!.config.textColor) } private fun editEvent(event: ListEvent) { - Intent(activity.applicationContext, EventActivity::class.java).apply { + Intent(context, EventActivity::class.java).apply { putExtra(EVENT_ID, event.id) putExtra(EVENT_OCCURRENCE_TS, event.startTS) startActivity(this) @@ -119,12 +119,12 @@ class EventListFragment : Fragment(), DBHelper.EventUpdateListener, DeleteEvents override fun deleteItems(ids: ArrayList) { val eventIDs = Array(ids.size, { i -> (ids[i].toString()) }) - DBHelper.newInstance(activity.applicationContext, this).deleteEvents(eventIDs, true) + DBHelper.newInstance(context!!, this).deleteEvents(eventIDs, true) } override fun addEventRepeatException(parentIds: ArrayList, timestamps: ArrayList) { parentIds.forEachIndexed { index, value -> - context.dbHelper.addEventRepeatException(value, timestamps[index]) + context!!.dbHelper.addEventRepeatException(value, timestamps[index]) } checkEvents() } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/MonthFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/MonthFragment.kt index 811eb8a63..c9c7383cb 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/MonthFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/MonthFragment.kt @@ -48,20 +48,20 @@ class MonthFragment : Fragment(), MonthlyCalendar { lateinit var mConfig: Config lateinit var mCalendar: MonthlyCalendarImpl - override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { - val view = inflater!!.inflate(R.layout.fragment_month, container, false) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + val view = inflater.inflate(R.layout.fragment_month, container, false) mRes = resources - mPackageName = activity.packageName + mPackageName = activity!!.packageName mHolder = view.calendar_holder - mDayCode = arguments.getString(DAY_CODE) - mConfig = context.config + mDayCode = arguments!!.getString(DAY_CODE) + mConfig = context!!.config mSundayFirst = mConfig.isSundayFirst setupButtons() setupLabels() - mCalendar = MonthlyCalendarImpl(this, context) + mCalendar = MonthlyCalendarImpl(this, context!!) return view } @@ -125,15 +125,15 @@ class MonthFragment : Fragment(), MonthlyCalendar { } private fun showMonthDialog() { - activity.setTheme(context.getAppropriateTheme()) - val view = getLayoutInflater(arguments).inflate(R.layout.date_picker, null) + activity!!.setTheme(context!!.getAppropriateTheme()) + val view = layoutInflater.inflate(R.layout.date_picker, null) val datePicker = view.findViewById(R.id.date_picker) datePicker.findViewById(Resources.getSystem().getIdentifier("day", "id", "android")).beGone() val dateTime = DateTime(mCalendar.mTargetDate.toString()) datePicker.init(dateTime.year, dateTime.monthOfYear - 1, 1, null) - AlertDialog.Builder(context) + AlertDialog.Builder(context!!) .setNegativeButton(R.string.cancel, null) .setPositiveButton(R.string.ok) { dialog, which -> positivePressed(dateTime, datePicker) } .create().apply { diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/WeekFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/WeekFragment.kt index 0613a63df..37c163c94 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/WeekFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/WeekFragment.kt @@ -59,10 +59,10 @@ class WeekFragment : Fragment(), WeeklyCalendar { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { this.inflater = inflater - mRowHeight = (context.resources.getDimension(R.dimen.weekly_view_row_height)).toInt() - minScrollY = mRowHeight * context.config.startWeeklyAt - mWeekTimestamp = arguments.getInt(WEEK_START_TIMESTAMP) - primaryColor = context.config.primaryColor + mRowHeight = (context!!.resources.getDimension(R.dimen.weekly_view_row_height)).toInt() + minScrollY = mRowHeight * context!!.config.startWeeklyAt + mWeekTimestamp = arguments!!.getInt(WEEK_START_TIMESTAMP) + primaryColor = context!!.config.primaryColor mRes = resources allDayRows.add(HashSet()) @@ -84,7 +84,7 @@ class WeekFragment : Fragment(), WeeklyCalendar { (0..6).map { inflater.inflate(R.layout.stroke_vertical_divider, mView.week_vertical_grid_holder) } (0..23).map { inflater.inflate(R.layout.stroke_horizontal_divider, mView.week_horizontal_grid_holder) } - mCalendar = WeeklyCalendarImpl(this, context) + mCalendar = WeeklyCalendarImpl(this, context!!) wasFragmentInit = true return mView } @@ -114,8 +114,8 @@ class WeekFragment : Fragment(), WeeklyCalendar { return mView.week_events_scrollview.viewTreeObserver.removeOnGlobalLayoutListener(this) - minScrollY = mRowHeight * context.config.startWeeklyAt - maxScrollY = mRowHeight * context.config.endWeeklyAt + minScrollY = mRowHeight * context!!.config.startWeeklyAt + maxScrollY = mRowHeight * context!!.config.endWeeklyAt val bounds = Rect() week_events_holder.getGlobalVisibleRect(bounds) @@ -130,12 +130,12 @@ class WeekFragment : Fragment(), WeeklyCalendar { private fun setupDayLabels() { var curDay = Formatter.getDateTimeFromTS(mWeekTimestamp) - val textColor = context.config.textColor + val textColor = context!!.config.textColor val todayCode = Formatter.getDayCodeFromDateTime(DateTime()) for (i in 0..6) { val dayCode = Formatter.getDayCodeFromDateTime(curDay) val dayLetter = getDayLetter(curDay.dayOfWeek) - mView.findViewById(mRes.getIdentifier("week_day_label_$i", "id", context.packageName)).apply { + mView.findViewById(mRes.getIdentifier("week_day_label_$i", "id", context!!.packageName)).apply { text = "$dayLetter\n${curDay.dayOfMonth}" setTextColor(if (todayCode == dayCode) primaryColor else textColor) if (todayCode == dayCode) @@ -229,19 +229,19 @@ class WeekFragment : Fragment(), WeeklyCalendar { if (mWasDestroyed) return - activity.runOnUiThread { + activity!!.runOnUiThread { if (context != null && isAdded) addEvents() } } private fun addEvents() { - val filtered = context.getFilteredEvents(events) + val filtered = context!!.getFilteredEvents(events) initGrid() allDayHolders.clear() allDayRows.clear() - allDayRows.add(HashSet()) + allDayRows.add(HashSet()) week_all_day_holder?.removeAllViews() addNewLine() @@ -251,7 +251,7 @@ class WeekFragment : Fragment(), WeeklyCalendar { val minimalHeight = mRes.getDimension(R.dimen.weekly_view_minimal_event_height).toInt() var hadAllDayEvent = false - val replaceDescription = context.config.replaceDescription + val replaceDescription = context!!.config.replaceDescription val sorted = filtered.sortedWith(compareBy({ it.startTS }, { it.endTS }, { it.title }, { if (replaceDescription) it.location else it.description })) for (event in sorted) { if (event.getIsAllDay() || Formatter.getDayCodeFromTS(event.startTS) != Formatter.getDayCodeFromTS(event.endTS)) { @@ -260,7 +260,7 @@ class WeekFragment : Fragment(), WeeklyCalendar { } else { val startDateTime = Formatter.getDateTimeFromTS(event.startTS) val endDateTime = Formatter.getDateTimeFromTS(event.endTS) - val dayOfWeek = startDateTime.plusDays(if (context.config.isSundayFirst) 1 else 0).dayOfWeek - 1 + val dayOfWeek = startDateTime.plusDays(if (context!!.config.isSundayFirst) 1 else 0).dayOfWeek - 1 val layout = getColumnWithId(dayOfWeek) val startMinutes = startDateTime.minuteOfDay @@ -278,7 +278,7 @@ class WeekFragment : Fragment(), WeeklyCalendar { minHeight = if (event.startTS == event.endTS) minimalHeight else (duration * minuteHeight).toInt() - 1 } setOnClickListener { - Intent(activity.applicationContext, EventActivity::class.java).apply { + Intent(context, EventActivity::class.java).apply { putExtra(EVENT_ID, event.id) putExtra(EVENT_OCCURRENCE_TS, event.startTS) startActivity(this) @@ -394,7 +394,7 @@ class WeekFragment : Fragment(), WeeklyCalendar { calculateExtraHeight() setOnClickListener { - Intent(activity.applicationContext, EventActivity::class.java).apply { + Intent(context, EventActivity::class.java).apply { putExtra(EVENT_ID, event.id) putExtra(EVENT_OCCURRENCE_TS, event.startTS) startActivity(this) @@ -427,7 +427,7 @@ class WeekFragment : Fragment(), WeeklyCalendar { mWasDestroyed = true } - private fun getColumnWithId(id: Int) = mView.findViewById(mRes.getIdentifier("week_column_$id", "id", context.packageName)) + private fun getColumnWithId(id: Int) = mView.findViewById(mRes.getIdentifier("week_column_$id", "id", context!!.packageName)) fun updateScrollY(y: Int) { if (wasFragmentInit) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/YearFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/YearFragment.kt index 2d361fd32..1c2f5c37b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/YearFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/fragments/YearFragment.kt @@ -30,20 +30,20 @@ class YearFragment : Fragment(), YearlyCalendar { lateinit var mView: View lateinit var mCalendar: YearlyCalendarImpl - override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { - mView = inflater!!.inflate(R.layout.fragment_year, container, false) - mYear = arguments.getInt(YEAR_LABEL) - context.updateTextColors(mView.calendar_holder) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + mView = inflater.inflate(R.layout.fragment_year, container, false) + mYear = arguments!!.getInt(YEAR_LABEL) + context!!.updateTextColors(mView.calendar_holder) setupMonths() - mCalendar = YearlyCalendarImpl(this, context, mYear) + mCalendar = YearlyCalendarImpl(this, context!!, mYear) return mView } override fun onResume() { super.onResume() - val sundayFirst = context.config.isSundayFirst + val sundayFirst = context!!.config.isSundayFirst if (sundayFirst != mSundayFirst) { mSundayFirst = sundayFirst setupMonths() @@ -64,7 +64,7 @@ class YearFragment : Fragment(), YearlyCalendar { markCurrentMonth(res) for (i in 1..12) { - val monthView = mView.findViewById(res.getIdentifier("month_" + i, "id", activity.packageName)) + val monthView = mView.findViewById(res.getIdentifier("month_" + i, "id", context!!.packageName)) var dayOfWeek = dateTime.withMonthOfYear(i).dayOfWeek().get() if (!mSundayFirst) dayOfWeek-- @@ -79,10 +79,10 @@ class YearFragment : Fragment(), YearlyCalendar { private fun markCurrentMonth(res: Resources) { val now = DateTime() if (now.year == mYear) { - val monthLabel = mView.findViewById(res.getIdentifier("month_${now.monthOfYear}_label", "id", activity.packageName)) - monthLabel.setTextColor(context.config.primaryColor) + val monthLabel = mView.findViewById(res.getIdentifier("month_${now.monthOfYear}_label", "id", context!!.packageName)) + monthLabel.setTextColor(context!!.config.primaryColor) - val monthView = mView.findViewById(res.getIdentifier("month_${now.monthOfYear}", "id", activity.packageName)) + val monthView = mView.findViewById(res.getIdentifier("month_${now.monthOfYear}", "id", context!!.packageName)) monthView.todaysId = now.dayOfMonth } } @@ -97,7 +97,7 @@ class YearFragment : Fragment(), YearlyCalendar { lastHash = hashCode val res = resources for (i in 1..12) { - val monthView = mView.findViewById(res.getIdentifier("month_$i", "id", context.packageName)) + val monthView = mView.findViewById(res.getIdentifier("month_$i", "id", context!!.packageName)) monthView.setEvents(events.get(i)) } } diff --git a/build.gradle b/build.gradle index 633d20306..8c22f1119 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'com.android.tools.build:gradle:3.0.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0b485f97d..9cbc21bee 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Mar 03 23:10:59 CET 2017 +#Tue Nov 07 14:52:59 CET 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip