42 |
42 |
43 #include "prefapi.h" |
43 #include "prefapi.h" |
44 #include "prefread.h" |
44 #include "prefread.h" |
45 #include "prefapi_private_data.h" |
45 #include "prefapi_private_data.h" |
46 |
46 |
47 @@ -1167,16 +1168,34 @@ pref_LoadPrefsInDir(nsIFile* aDir, char |
47 @@ -1172,16 +1173,34 @@ pref_LoadPrefsInDir(nsIFile* aDir, char |
48 |
48 |
49 static nsresult pref_LoadPrefsInDirList(const char *listId) |
49 static nsresult pref_LoadPrefsInDirList(const char *listId) |
50 { |
50 { |
51 nsresult rv; |
51 nsresult rv; |
52 nsCOMPtr<nsIProperties> dirSvc(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); |
52 nsCOMPtr<nsIProperties> dirSvc(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); |
77 getter_AddRefs(list)); |
77 getter_AddRefs(list)); |
78 if (!list) |
78 if (!list) |
79 return NS_OK; |
79 return NS_OK; |
80 |
80 |
81 bool hasMore; |
81 bool hasMore; |
82 @@ -1192,17 +1211,17 @@ static nsresult pref_LoadPrefsInDirList( |
82 @@ -1197,17 +1216,17 @@ static nsresult pref_LoadPrefsInDirList( |
83 |
83 |
84 nsAutoCString leaf; |
84 nsAutoCString leaf; |
85 path->GetNativeLeafName(leaf); |
85 path->GetNativeLeafName(leaf); |
86 |
86 |
87 // Do we care if a file provided by this process fails to load? |
87 // Do we care if a file provided by this process fails to load? |
96 |
96 |
97 static nsresult pref_ReadPrefFromJar(nsZipArchive* jarReader, const char *name) |
97 static nsresult pref_ReadPrefFromJar(nsZipArchive* jarReader, const char *name) |
98 { |
98 { |
99 nsZipItemPtr<char> manifest(jarReader, name, true); |
99 nsZipItemPtr<char> manifest(jarReader, name, true); |
100 NS_ENSURE_TRUE(manifest.Buffer(), NS_ERROR_NOT_AVAILABLE); |
100 NS_ENSURE_TRUE(manifest.Buffer(), NS_ERROR_NOT_AVAILABLE); |
101 @@ -1296,26 +1315,38 @@ static nsresult pref_InitInitialObjects( |
101 @@ -1301,26 +1320,38 @@ static nsresult pref_InitInitialObjects( |
102 /* these pref file names should not be used: we process them after all other application pref files for backwards compatibility */ |
102 /* these pref file names should not be used: we process them after all other application pref files for backwards compatibility */ |
103 static const char* specialFiles[] = { |
103 static const char* specialFiles[] = { |
104 #if defined(XP_MACOSX) |
104 #if defined(XP_MACOSX) |
105 "macprefs.js" |
105 "macprefs.js" |
106 #elif defined(XP_WIN) |
106 #elif defined(XP_WIN) |
138 nsRefPtr<nsZipArchive> appJarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP); |
138 nsRefPtr<nsZipArchive> appJarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP); |
139 // GetReader(mozilla::Omnijar::APP) returns null when $app == $gre, in which |
139 // GetReader(mozilla::Omnijar::APP) returns null when $app == $gre, in which |
140 diff --git a/python/mozbuild/mozpack/chrome/flags.py b/python/mozbuild/mozpack/chrome/flags.py |
140 diff --git a/python/mozbuild/mozpack/chrome/flags.py b/python/mozbuild/mozpack/chrome/flags.py |
141 --- a/python/mozbuild/mozpack/chrome/flags.py |
141 --- a/python/mozbuild/mozpack/chrome/flags.py |
142 +++ b/python/mozbuild/mozpack/chrome/flags.py |
142 +++ b/python/mozbuild/mozpack/chrome/flags.py |
143 @@ -208,16 +208,17 @@ class Flags(OrderedDict): |
143 @@ -209,16 +209,17 @@ class Flags(OrderedDict): |
144 'platformversion': VersionFlag, |
|
145 'contentaccessible': Flag, |
144 'contentaccessible': Flag, |
146 'os': StringFlag, |
145 'os': StringFlag, |
147 'osversion': VersionFlag, |
146 'osversion': VersionFlag, |
148 'abi': StringFlag, |
147 'abi': StringFlag, |
149 'platform': Flag, |
148 'platform': Flag, |
150 'xpcnativewrappers': Flag, |
149 'xpcnativewrappers': Flag, |
151 'tablet': Flag, |
150 'tablet': Flag, |
152 + 'desktop': StringFlag, |
151 'process': StringFlag, |
|
152 + 'desktop': StringFlag, |
153 } |
153 } |
154 RE = re.compile(r'([!<>=]+)') |
154 RE = re.compile(r'([!<>=]+)') |
155 |
155 |
156 def __init__(self, *flags): |
156 def __init__(self, *flags): |
157 ''' |
157 ''' |
159 flags = Flags('contentaccessible=yes', 'appversion>=3.5') |
159 flags = Flags('contentaccessible=yes', 'appversion>=3.5') |
160 ''' |
160 ''' |
161 diff --git a/python/mozbuild/mozpack/chrome/manifest.py b/python/mozbuild/mozpack/chrome/manifest.py |
161 diff --git a/python/mozbuild/mozpack/chrome/manifest.py b/python/mozbuild/mozpack/chrome/manifest.py |
162 --- a/python/mozbuild/mozpack/chrome/manifest.py |
162 --- a/python/mozbuild/mozpack/chrome/manifest.py |
163 +++ b/python/mozbuild/mozpack/chrome/manifest.py |
163 +++ b/python/mozbuild/mozpack/chrome/manifest.py |
164 @@ -30,16 +30,17 @@ class ManifestEntry(object): |
164 @@ -31,16 +31,17 @@ class ManifestEntry(object): |
165 allowed_flags = [ |
|
166 'application', |
165 'application', |
167 'platformversion', |
166 'platformversion', |
168 'os', |
167 'os', |
169 'osversion', |
168 'osversion', |
170 'abi', |
169 'abi', |
171 'xpcnativewrappers', |
170 'xpcnativewrappers', |
172 'tablet', |
171 'tablet', |
173 + 'desktop', |
172 'process', |
|
173 + 'desktop', |
174 ] |
174 ] |
175 |
175 |
176 def __init__(self, base, *flags): |
176 def __init__(self, base, *flags): |
177 ''' |
177 ''' |
178 Initialize a manifest entry with the given base path and flags. |
178 Initialize a manifest entry with the given base path and flags. |
200 |
200 |
201 CXXFLAGS += CONFIG['TK_CFLAGS'] |
201 CXXFLAGS += CONFIG['TK_CFLAGS'] |
202 diff --git a/toolkit/components/downloads/nsDownloadManager.cpp b/toolkit/components/downloads/nsDownloadManager.cpp |
202 diff --git a/toolkit/components/downloads/nsDownloadManager.cpp b/toolkit/components/downloads/nsDownloadManager.cpp |
203 --- a/toolkit/components/downloads/nsDownloadManager.cpp |
203 --- a/toolkit/components/downloads/nsDownloadManager.cpp |
204 +++ b/toolkit/components/downloads/nsDownloadManager.cpp |
204 +++ b/toolkit/components/downloads/nsDownloadManager.cpp |
205 @@ -43,16 +43,20 @@ |
205 @@ -44,16 +44,20 @@ |
206 #ifdef XP_WIN |
206 #ifdef XP_WIN |
207 #include <shlobj.h> |
207 #include <shlobj.h> |
208 #include "nsWindowsHelpers.h" |
208 #include "nsWindowsHelpers.h" |
209 #ifdef DOWNLOAD_SCANNER |
209 #ifdef DOWNLOAD_SCANNER |
210 #include "nsDownloadScanner.h" |
210 #include "nsDownloadScanner.h" |
221 |
221 |
222 #ifdef MOZ_WIDGET_ANDROID |
222 #ifdef MOZ_WIDGET_ANDROID |
223 #include "AndroidBridge.h" |
223 #include "AndroidBridge.h" |
224 using namespace mozilla::widget::android; |
224 using namespace mozilla::widget::android; |
225 #endif |
225 #endif |
226 @@ -2711,16 +2715,25 @@ nsDownload::SetState(DownloadState aStat |
226 @@ -2712,16 +2716,25 @@ nsDownload::SetState(DownloadState aStat |
227 nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID)); |
227 nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID)); |
228 |
228 |
229 // Master pref to control this function. |
229 // Master pref to control this function. |
230 bool showTaskbarAlert = true; |
230 bool showTaskbarAlert = true; |
231 if (pref) |
231 if (pref) |
247 |
247 |
248 int64_t alertIntervalUSec = alertInterval * PR_USEC_PER_MSEC; |
248 int64_t alertIntervalUSec = alertInterval * PR_USEC_PER_MSEC; |
249 int64_t goat = PR_Now() - mStartTime; |
249 int64_t goat = PR_Now() - mStartTime; |
250 showTaskbarAlert = goat > alertIntervalUSec; |
250 showTaskbarAlert = goat > alertIntervalUSec; |
251 |
251 |
252 @@ -2751,16 +2764,17 @@ nsDownload::SetState(DownloadState aStat |
252 @@ -2752,16 +2765,17 @@ nsDownload::SetState(DownloadState aStat |
253 NS_LITERAL_STRING(DOWNLOAD_MANAGER_ALERT_ICON), title, |
253 NS_LITERAL_STRING(DOWNLOAD_MANAGER_ALERT_ICON), title, |
254 message, !removeWhenDone, |
254 message, !removeWhenDone, |
255 mPrivate ? NS_LITERAL_STRING("private") : NS_LITERAL_STRING("non-private"), |
255 mPrivate ? NS_LITERAL_STRING("private") : NS_LITERAL_STRING("non-private"), |
256 mDownloadManager, EmptyString(), NS_LITERAL_STRING("auto"), |
256 mDownloadManager, EmptyString(), NS_LITERAL_STRING("auto"), |
257 EmptyString(), EmptyString(), nullptr); |
257 EmptyString(), EmptyString(), nullptr); |
2628 + |
2628 + |
2629 +#endif // nsKDEUtils |
2629 +#endif // nsKDEUtils |
2630 diff --git a/uriloader/exthandler/moz.build b/uriloader/exthandler/moz.build |
2630 diff --git a/uriloader/exthandler/moz.build b/uriloader/exthandler/moz.build |
2631 --- a/uriloader/exthandler/moz.build |
2631 --- a/uriloader/exthandler/moz.build |
2632 +++ b/uriloader/exthandler/moz.build |
2632 +++ b/uriloader/exthandler/moz.build |
2633 @@ -75,17 +75,19 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco |
2633 @@ -68,17 +68,19 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco |
2634 else: |
2634 else: |
2635 # These files can't be built in unified mode because they force NSPR logging. |
2635 # These files can't be built in unified mode because they redefine LOG. |
2636 SOURCES += [ |
2636 SOURCES += [ |
2637 osdir + '/nsOSHelperAppService.cpp', |
2637 osdir + '/nsOSHelperAppService.cpp', |
2638 ] |
2638 ] |
2639 |
2639 |
2640 if CONFIG['MOZ_ENABLE_GTK']: |
2640 if CONFIG['MOZ_ENABLE_GTK']: |
2648 UNIFIED_SOURCES += [ |
2648 UNIFIED_SOURCES += [ |
2649 'android/nsAndroidHandlerApp.cpp', |
2649 'android/nsAndroidHandlerApp.cpp', |
2650 'android/nsExternalSharingAppService.cpp', |
2650 'android/nsExternalSharingAppService.cpp', |
2651 'android/nsExternalURLHandlerService.cpp', |
2651 'android/nsExternalURLHandlerService.cpp', |
2652 'android/nsMIMEInfoAndroid.cpp', |
2652 'android/nsMIMEInfoAndroid.cpp', |
2653 @@ -129,16 +131,17 @@ include('/ipc/chromium/chromium-config.m |
2653 @@ -121,16 +123,17 @@ include('/ipc/chromium/chromium-config.m |
2654 FINAL_LIBRARY = 'xul' |
2654 FINAL_LIBRARY = 'xul' |
2655 |
2655 |
2656 LOCAL_INCLUDES += [ |
2656 LOCAL_INCLUDES += [ |
2657 '/content/base/src', |
2657 '/content/base/src', |
2658 '/dom/base', |
2658 '/dom/base', |
3102 |
3102 |
3103 // Now look up our extensions |
3103 // Now look up our extensions |
3104 diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build |
3104 diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build |
3105 --- a/widget/gtk/moz.build |
3105 --- a/widget/gtk/moz.build |
3106 +++ b/widget/gtk/moz.build |
3106 +++ b/widget/gtk/moz.build |
3107 @@ -88,16 +88,17 @@ include('/ipc/chromium/chromium-config.m |
3107 @@ -81,16 +81,17 @@ include('/ipc/chromium/chromium-config.m |
3108 FINAL_LIBRARY = 'xul' |
3108 FINAL_LIBRARY = 'xul' |
3109 |
3109 |
3110 LOCAL_INCLUDES += [ |
3110 LOCAL_INCLUDES += [ |
3111 '../shared', |
3111 '../shared', |
3112 '../xpwidgets', |
3112 '../xpwidgets', |
3158 #define MAX_PREVIEW_SIZE 180 |
3158 #define MAX_PREVIEW_SIZE 180 |
3159 |
3159 |
3160 nsIFile *nsFilePicker::mPrevDisplayDirectory = nullptr; |
3160 nsIFile *nsFilePicker::mPrevDisplayDirectory = nullptr; |
3161 |
3161 |
3162 void |
3162 void |
3163 @@ -226,17 +228,19 @@ nsFilePicker::AppendFilters(int32_t aFil |
3163 @@ -224,17 +226,19 @@ nsFilePicker::AppendFilters(int32_t aFil |
3164 return nsBaseFilePicker::AppendFilters(aFilterMask); |
3164 return nsBaseFilePicker::AppendFilters(aFilterMask); |
3165 } |
3165 } |
3166 |
3166 |
3167 NS_IMETHODIMP |
3167 NS_IMETHODIMP |
3168 nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter) |
3168 nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter) |
3179 CopyUTF16toUTF8(aFilter, filter); |
3179 CopyUTF16toUTF8(aFilter, filter); |
3180 CopyUTF16toUTF8(aTitle, name); |
3180 CopyUTF16toUTF8(aTitle, name); |
3181 |
3181 |
3182 mFilters.AppendElement(filter); |
3182 mFilters.AppendElement(filter); |
3183 mFilterNames.AppendElement(name); |
3183 mFilterNames.AppendElement(name); |
3184 @@ -351,16 +355,32 @@ nsFilePicker::Show(int16_t *aReturn) |
3184 @@ -349,16 +353,32 @@ nsFilePicker::Show(int16_t *aReturn) |
3185 |
3185 |
3186 NS_IMETHODIMP |
3186 NS_IMETHODIMP |
3187 nsFilePicker::Open(nsIFilePickerShownCallback *aCallback) |
3187 nsFilePicker::Open(nsIFilePickerShownCallback *aCallback) |
3188 { |
3188 { |
3189 // Can't show two dialogs concurrently with the same filepicker |
3189 // Can't show two dialogs concurrently with the same filepicker |
3212 GtkWindow *parent_widget = |
3212 GtkWindow *parent_widget = |
3213 GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)); |
3213 GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)); |
3214 |
3214 |
3215 GtkFileChooserAction action = GetGtkFileChooserAction(mMode); |
3215 GtkFileChooserAction action = GetGtkFileChooserAction(mMode); |
3216 const gchar *accept_button = (action == GTK_FILE_CHOOSER_ACTION_SAVE) |
3216 const gchar *accept_button = (action == GTK_FILE_CHOOSER_ACTION_SAVE) |
3217 @@ -539,8 +559,235 @@ nsFilePicker::Done(GtkWidget* file_choos |
3217 @@ -537,8 +557,235 @@ nsFilePicker::Done(GtkWidget* file_choos |
3218 if (mCallback) { |
3218 if (mCallback) { |
3219 mCallback->Done(result); |
3219 mCallback->Done(result); |
3220 mCallback = nullptr; |
3220 mCallback = nullptr; |
3221 } else { |
3221 } else { |
3222 mResult = result; |
3222 mResult = result; |
3500 NS_NAMED_LITERAL_STRING(kGeckoVersion, "platformversion"); |
3500 NS_NAMED_LITERAL_STRING(kGeckoVersion, "platformversion"); |
3501 NS_NAMED_LITERAL_STRING(kOs, "os"); |
3501 NS_NAMED_LITERAL_STRING(kOs, "os"); |
3502 NS_NAMED_LITERAL_STRING(kOsVersion, "osversion"); |
3502 NS_NAMED_LITERAL_STRING(kOsVersion, "osversion"); |
3503 NS_NAMED_LITERAL_STRING(kABI, "abi"); |
3503 NS_NAMED_LITERAL_STRING(kABI, "abi"); |
3504 + NS_NAMED_LITERAL_STRING(kDesktop, "desktop"); |
3504 + NS_NAMED_LITERAL_STRING(kDesktop, "desktop"); |
|
3505 NS_NAMED_LITERAL_STRING(kProcess, "process"); |
3505 #if defined(MOZ_WIDGET_ANDROID) |
3506 #if defined(MOZ_WIDGET_ANDROID) |
3506 NS_NAMED_LITERAL_STRING(kTablet, "tablet"); |
3507 NS_NAMED_LITERAL_STRING(kTablet, "tablet"); |
3507 #endif |
3508 #endif |
3508 |
3509 |
3509 // Obsolete |
3510 NS_NAMED_LITERAL_STRING(kMain, "main"); |
3510 NS_NAMED_LITERAL_STRING(kXPCNativeWrappers, "xpcnativewrappers"); |
3511 NS_NAMED_LITERAL_STRING(kContent, "content"); |
3511 |
3512 |
3512 nsAutoString appID; |
3513 @@ -548,44 +550,49 @@ ParseManifest(NSLocationType aType, File |
3513 @@ -543,44 +545,49 @@ ParseManifest(NSLocationType aType, File |
|
3514 CopyUTF8toUTF16(s, abi); |
3514 CopyUTF8toUTF16(s, abi); |
3515 abi.Insert(char16_t('_'), 0); |
3515 abi.Insert(char16_t('_'), 0); |
3516 abi.Insert(osTarget, 0); |
3516 abi.Insert(osTarget, 0); |
3517 } |
3517 } |
3518 } |
3518 } |
3552 isTablet = mozilla::widget::android::GeckoAppShell::IsTablet(); |
3552 isTablet = mozilla::widget::android::GeckoAppShell::IsTablet(); |
3553 } |
3553 } |
3554 + desktop = NS_LITERAL_STRING("android"); |
3554 + desktop = NS_LITERAL_STRING("android"); |
3555 #endif |
3555 #endif |
3556 |
3556 |
3557 // Because contracts must be registered after CIDs, we save and process them |
3557 if (XRE_GetProcessType() == GeckoProcessType_Content) { |
3558 // at the end. |
3558 process = kContent; |
3559 nsTArray<CachedDirective> contracts; |
3559 } else { |
3560 |
3560 process = kMain; |
3561 char* token; |
3561 } |
3562 char* newline = aBuf; |
3562 |
3563 @@ -669,25 +676,27 @@ ParseManifest(NSLocationType aType, File |
3563 @@ -681,25 +688,27 @@ ParseManifest(NSLocationType aType, File |
3564 TriState stOsVersion = eUnspecified; |
|
3565 TriState stOs = eUnspecified; |
3564 TriState stOs = eUnspecified; |
3566 TriState stABI = eUnspecified; |
3565 TriState stABI = eUnspecified; |
|
3566 TriState stProcess = eUnspecified; |
3567 #if defined(MOZ_WIDGET_ANDROID) |
3567 #if defined(MOZ_WIDGET_ANDROID) |
3568 TriState stTablet = eUnspecified; |
3568 TriState stTablet = eUnspecified; |
3569 #endif |
3569 #endif |
3570 bool platform = false; |
3570 bool platform = false; |
3571 bool contentAccessible = false; |
3571 bool contentAccessible = false; |
3578 |
3578 |
3579 if (CheckStringFlag(kApplication, wtoken, appID, stApp) || |
3579 if (CheckStringFlag(kApplication, wtoken, appID, stApp) || |
3580 CheckStringFlag(kOs, wtoken, osTarget, stOs) || |
3580 CheckStringFlag(kOs, wtoken, osTarget, stOs) || |
3581 CheckStringFlag(kABI, wtoken, abi, stABI) || |
3581 CheckStringFlag(kABI, wtoken, abi, stABI) || |
3582 + CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) || |
3582 + CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) || |
|
3583 CheckStringFlag(kProcess, wtoken, process, stProcess) || |
3583 CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) || |
3584 CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) || |
3584 CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) || |
3585 CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) || |
3585 CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion)) { |
3586 CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion)) { |
3586 continue; |
3587 continue; |
3587 } |
3588 } |
3588 |
3589 |
3589 #if defined(MOZ_WIDGET_ANDROID) |
3590 #if defined(MOZ_WIDGET_ANDROID) |
3590 bool tablet = false; |
3591 @@ -731,16 +740,17 @@ ParseManifest(NSLocationType aType, File |
3591 @@ -718,16 +727,17 @@ ParseManifest(NSLocationType aType, File |
|
3592 } |
3592 } |
3593 |
3593 |
3594 if (!ok || |
3594 if (!ok || |
3595 stApp == eBad || |
3595 stApp == eBad || |
3596 stAppVersion == eBad || |
3596 stAppVersion == eBad || |
3599 stOsVersion == eBad || |
3599 stOsVersion == eBad || |
3600 + stDesktop == eBad || |
3600 + stDesktop == eBad || |
3601 #ifdef MOZ_WIDGET_ANDROID |
3601 #ifdef MOZ_WIDGET_ANDROID |
3602 stTablet == eBad || |
3602 stTablet == eBad || |
3603 #endif |
3603 #endif |
3604 stABI == eBad) { |
3604 stABI == eBad || |
|
3605 stProcess == eBad) { |
3605 continue; |
3606 continue; |
3606 } |
3607 } |
3607 |
3608 |
3608 #ifdef MOZ_B2G_LOADER |
|
3609 diff --git a/xpcom/components/moz.build b/xpcom/components/moz.build |
3609 diff --git a/xpcom/components/moz.build b/xpcom/components/moz.build |
3610 --- a/xpcom/components/moz.build |
3610 --- a/xpcom/components/moz.build |
3611 +++ b/xpcom/components/moz.build |
3611 +++ b/xpcom/components/moz.build |
3612 @@ -47,12 +47,13 @@ FINAL_LIBRARY = 'xul' |
3612 @@ -48,12 +48,13 @@ FINAL_LIBRARY = 'xul' |
3613 GENERATED_INCLUDES += ['..'] |
3613 GENERATED_INCLUDES += ['..'] |
3614 LOCAL_INCLUDES += [ |
3614 LOCAL_INCLUDES += [ |
3615 '../base', |
3615 '../base', |
3616 '../build', |
3616 '../build', |
3617 '../ds', |
3617 '../ds', |