Skip to content

Commit 2f4c559

Browse files
committed
Updating project for Xcode 7
Changes: - Updated README - Updated code for Swift 2 compatibility - Unit tests now use at-testable - Updated project settings - Refactored out some cruft - Fixed configuration so project now properly runs in full-screen mode on all phones
1 parent 8a920ec commit 2f4c559

18 files changed

Lines changed: 234 additions & 318 deletions

File tree

README.md

Lines changed: 10 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,31 @@
11
swift-2048
22
==========
33

4-
A port of [iOS-2048](https://github.com/austinzheng/iOS-2048) to Apple's new Swift language. The game is present and working, but a number of auxiliary features haven't yet been implemented.
4+
A working port of [iOS-2048](https://github.com/austinzheng/iOS-2048) to Apple's new Swift language.
55

66
Like the original Objective-C version, swift-2048 does not rely upon SpriteKit. See the description for iOS-2048 for more information.
77

8+
I'm not actively working on this, except to fix bugs and maintain compatibility with latest versions. Pull requests are welcome, though. Note that Swift was very different back when I first wrote this code, caveat emptor.
9+
10+
11+
If you want to check out a more advanced Swift project, please take a look at **[Lambdatron](https://github.com/austinzheng/Lambdatron)**, my Clojure interpreter.
12+
813
Instructions
914
------------
1015

11-
You will need the Xcode 6 Developer Preview to build and run the project. However, it should run under either iOS 7 or iOS 8 (on the simulator).
16+
You will need Xcode 7 to run the project. Run it in the simulator or on an actual device.
1217

1318
Tap the button to play the game. Swipe to move the tiles.
1419

1520
Thoughts on Swift
1621
-----------------
1722

18-
Swift is great. Pattern matching, tuples, and typeclasses are amazing. Programming in Swift feels much closer to programming in Scala than in Objective-C. Types are important again.
19-
20-
It's a little disappointing that Apple hasn't provided closure-based callbacks for UIKit controls. Selectors seem pretty hacky in Swift, but they do work.
21-
22-
Still have no idea how to make things private, public, or protected. In Objective-C you could hide internal details away in the .m file. In Swift, everything is exposed by default. Apparently this is something that will be added into the language before release; there will also be a flag to disable it (useful for exposing methods for unit testing).
23-
24-
Xcode is as unstable as always. The background compiler/code analyzer kept on crashing and restarting itself. Xcode was functional enough to allow the project to be brought to some state of completion. The debugger is horribly broken though. (Note that Xcode 6 DP is obviously beta software.)
25-
26-
### Features Swift has that Objective-C lacks
27-
(Not comprehensive)
28-
29-
- Tuples
30-
- Tagged enums (similar to Scala typeclasses)
31-
- Primitive types treated like objects (actually structs) - extensions can declare new methods upon ``Int``, for example
32-
- Enums and structs that support functions and constructors
33-
- ``override`` keyword to explicitly denote a method overriding a superclass implementation
34-
- C++ style function overloading
35-
- Optional function arguments with default values
36-
- Nested functions
37-
- Pattern matching (match with arbitrary conditionals on values, ranges, tuple structure, enums, or types)
38-
- Generics (type reification, not type erasure)
39-
- Typed containers
40-
- Safe typecasting
41-
- Optionals (and optional chaining, implicitly unwrapped optionals, ``weak`` vs ``unowned``, ...)
42-
- Overflow-safe arithmetic
43-
- ``@auto_closure`` attribute, allowing for a very basic form of pass-by-name (as opposed to pass-by-value) function arguments
44-
- ``@final`` attribute, to prevent overriding
45-
- Other attributes, which have a purpose similar to Java annotations or Python decorators
46-
- Type properties (analogous to class methods; must be computed for classes, but can be stored for enums and structs)
47-
- Syntactical sugar for function currying
48-
- Operator overloading
49-
- Custom operators
50-
- Arbitrary behavior for subscripts
51-
- REPL
52-
- Multiple forms of closure literal convenience syntax
53-
- Capture lists in closure declarations, to avoid retain cycles when using closures
54-
- Native range operators and limited array slicing (``..`` and ``...``)
55-
56-
57-
### Objective-C features with no direct native Swift idiom
58-
(AFAIK; some of these might be available through interop)
59-
60-
- Method swizzling
61-
- Key-Value Observing (KVO)
62-
- Adding or modifying methods and classes at runtime
63-
- Invocations
64-
- Message proxying
65-
- Selectors
66-
67-
68-
### Features I wish Swift had
69-
70-
- Better support for n-dimensional array initialization
71-
- Tuples usable as dictionary keys (although there are technical issues)
72-
- Python/MATLAB-style array slicing
73-
- Abstract methods
23+
Swift is a well-designed language that will, hopefully, drag mainstream programming halfway to ML (kicking and screaming the entire way, of course).
7424

25+
If you really want to see my out-of-date thoughts on Swift, check out the git history for `README.md`.
7526

7627
License
7728
-------
78-
(c) 2014 Austin Zheng. Released under the terms of the MIT license.
29+
(c) 2014-2015 Austin Zheng. Released under the terms of the MIT license.
7930

8031
2048 by Gabriele Cirulli (http://gabrielecirulli.com/). The original game can be found at http://gabrielecirulli.github.io/2048/, as can all relevant attributions. 2048 is inspired by an iOS game called "Threes", by Asher Vollmer.

swift-2048.xcodeproj/project.pbxproj

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,23 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 46;
6+
objectVersion = 47;
77
objects = {
88

99
/* Begin PBXBuildFile section */
1010
1AC563E3193DCE6000402286 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AC563E2193DCE6000402286 /* AppDelegate.swift */; };
1111
1AC563E5193DCE6000402286 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AC563E4193DCE6000402286 /* ViewController.swift */; };
1212
1AC563E8193DCE6000402286 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1AC563E6193DCE6000402286 /* Main.storyboard */; };
1313
1AC563EA193DCE6000402286 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1AC563E9193DCE6000402286 /* Images.xcassets */; };
14-
1AC563F6193DCE6000402286 /* swift_2048Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AC563F5193DCE6000402286 /* swift_2048Tests.swift */; };
1514
1AE339B2193DCF110081FFA4 /* GameModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE339B1193DCF110081FFA4 /* GameModel.swift */; };
1615
1AE339B4193DF5FF0081FFA4 /* ModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE339B3193DF5FF0081FFA4 /* ModelTests.swift */; };
17-
1AE339B5193DF6540081FFA4 /* GameModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE339B1193DCF110081FFA4 /* GameModel.swift */; };
1816
1AE8BEF0193EEE24007592BA /* GameboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE8BEEF193EEE24007592BA /* GameboardView.swift */; };
1917
1AE8BEF2193EF1C7007592BA /* AppearanceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE8BEF1193EF1C7007592BA /* AppearanceProvider.swift */; };
2018
1AE8BEF4193EF260007592BA /* NumberTileGame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE8BEF3193EF260007592BA /* NumberTileGame.swift */; };
2119
1AE8BEF6193EF4B6007592BA /* TileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AE8BEF5193EF4B6007592BA /* TileView.swift */; };
20+
1AEF46D01BAE736400119D81 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1AEF46CF1BAE736400119D81 /* Launch Screen.storyboard */; settings = {ASSET_TAGS = (); }; };
2221
1AF8F0B619403AA400A7049E /* AccessoryViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF8F0B519403AA400A7049E /* AccessoryViews.swift */; };
2322
1AF8F0B81941841000A7049E /* AuxiliaryModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF8F0B71941841000A7049E /* AuxiliaryModels.swift */; };
24-
1AF8F0B91941846F00A7049E /* AuxiliaryModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF8F0B71941841000A7049E /* AuxiliaryModels.swift */; };
2523
/* End PBXBuildFile section */
2624

2725
/* Begin PBXContainerItemProxy section */
@@ -50,13 +48,13 @@
5048
1AC563E9193DCE6000402286 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
5149
1AC563EF193DCE6000402286 /* swift-2048Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "swift-2048Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
5250
1AC563F4193DCE6000402286 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
53-
1AC563F5193DCE6000402286 /* swift_2048Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = swift_2048Tests.swift; sourceTree = "<group>"; };
5451
1AE339B1193DCF110081FFA4 /* GameModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameModel.swift; path = Models/GameModel.swift; sourceTree = "<group>"; };
5552
1AE339B3193DF5FF0081FFA4 /* ModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModelTests.swift; sourceTree = "<group>"; };
5653
1AE8BEEF193EEE24007592BA /* GameboardView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameboardView.swift; path = Views/GameboardView.swift; sourceTree = "<group>"; };
5754
1AE8BEF1193EF1C7007592BA /* AppearanceProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppearanceProvider.swift; sourceTree = "<group>"; };
5855
1AE8BEF3193EF260007592BA /* NumberTileGame.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberTileGame.swift; sourceTree = "<group>"; };
5956
1AE8BEF5193EF4B6007592BA /* TileView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TileView.swift; path = Views/TileView.swift; sourceTree = "<group>"; };
57+
1AEF46CF1BAE736400119D81 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = "<group>"; };
6058
1AF8F0B519403AA400A7049E /* AccessoryViews.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AccessoryViews.swift; path = Views/AccessoryViews.swift; sourceTree = "<group>"; };
6159
1AF8F0B71941841000A7049E /* AuxiliaryModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AuxiliaryModels.swift; path = Models/AuxiliaryModels.swift; sourceTree = "<group>"; };
6260
/* End PBXFileReference section */
@@ -100,6 +98,7 @@
10098
1AC563DF193DCE6000402286 /* swift-2048 */ = {
10199
isa = PBXGroup;
102100
children = (
101+
1AEF46CF1BAE736400119D81 /* Launch Screen.storyboard */,
103102
1AC563E2193DCE6000402286 /* AppDelegate.swift */,
104103
1AC563E4193DCE6000402286 /* ViewController.swift */,
105104
1AC563E6193DCE6000402286 /* Main.storyboard */,
@@ -124,7 +123,6 @@
124123
1AC563F2193DCE6000402286 /* swift-2048Tests */ = {
125124
isa = PBXGroup;
126125
children = (
127-
1AC563F5193DCE6000402286 /* swift_2048Tests.swift */,
128126
1AC563F3193DCE6000402286 /* Supporting Files */,
129127
1AE339B3193DF5FF0081FFA4 /* ModelTests.swift */,
130128
);
@@ -203,7 +201,8 @@
203201
1AC563D5193DCE6000402286 /* Project object */ = {
204202
isa = PBXProject;
205203
attributes = {
206-
LastUpgradeCheck = 0600;
204+
LastSwiftUpdateCheck = 0700;
205+
LastUpgradeCheck = 0700;
207206
ORGANIZATIONNAME = "Austin Zheng";
208207
TargetAttributes = {
209208
1AC563DC193DCE6000402286 = {
@@ -216,7 +215,7 @@
216215
};
217216
};
218217
buildConfigurationList = 1AC563D8193DCE6000402286 /* Build configuration list for PBXProject "swift-2048" */;
219-
compatibilityVersion = "Xcode 3.2";
218+
compatibilityVersion = "Xcode 6.3";
220219
developmentRegion = English;
221220
hasScannedForEncodings = 0;
222221
knownRegions = (
@@ -239,6 +238,7 @@
239238
isa = PBXResourcesBuildPhase;
240239
buildActionMask = 2147483647;
241240
files = (
241+
1AEF46D01BAE736400119D81 /* Launch Screen.storyboard in Resources */,
242242
1AC563E8193DCE6000402286 /* Main.storyboard in Resources */,
243243
1AC563EA193DCE6000402286 /* Images.xcassets in Resources */,
244244
);
@@ -274,10 +274,7 @@
274274
isa = PBXSourcesBuildPhase;
275275
buildActionMask = 2147483647;
276276
files = (
277-
1AF8F0B91941846F00A7049E /* AuxiliaryModels.swift in Sources */,
278-
1AC563F6193DCE6000402286 /* swift_2048Tests.swift in Sources */,
279277
1AE339B4193DF5FF0081FFA4 /* ModelTests.swift in Sources */,
280-
1AE339B5193DF6540081FFA4 /* GameModel.swift in Sources */,
281278
);
282279
runOnlyForDeploymentPostprocessing = 0;
283280
};
@@ -328,6 +325,7 @@
328325
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
329326
COPY_PHASE_STRIP = NO;
330327
ENABLE_STRICT_OBJC_MSGSEND = YES;
328+
ENABLE_TESTABILITY = YES;
331329
GCC_C_LANGUAGE_STANDARD = gnu99;
332330
GCC_DYNAMIC_NO_PIC = NO;
333331
GCC_OPTIMIZATION_LEVEL = 0;
@@ -391,9 +389,10 @@
391389
isa = XCBuildConfiguration;
392390
buildSettings = {
393391
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
394-
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
395392
INFOPLIST_FILE = "swift-2048/Info.plist";
393+
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
396394
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
395+
PRODUCT_BUNDLE_IDENTIFIER = "f3nghuang.${PRODUCT_NAME:rfc1034identifier}";
397396
PRODUCT_NAME = "$(TARGET_NAME)";
398397
};
399398
name = Debug;
@@ -402,9 +401,10 @@
402401
isa = XCBuildConfiguration;
403402
buildSettings = {
404403
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
405-
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
406404
INFOPLIST_FILE = "swift-2048/Info.plist";
405+
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
407406
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
407+
PRODUCT_BUNDLE_IDENTIFIER = "f3nghuang.${PRODUCT_NAME:rfc1034identifier}";
408408
PRODUCT_NAME = "$(TARGET_NAME)";
409409
};
410410
name = Release;
@@ -424,6 +424,7 @@
424424
INFOPLIST_FILE = "swift-2048Tests/Info.plist";
425425
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
426426
METAL_ENABLE_DEBUG_INFO = YES;
427+
PRODUCT_BUNDLE_IDENTIFIER = "f3nghuang.${PRODUCT_NAME:rfc1034identifier}";
427428
PRODUCT_NAME = "$(TARGET_NAME)";
428429
TEST_HOST = "$(BUNDLE_LOADER)";
429430
};
@@ -440,6 +441,7 @@
440441
INFOPLIST_FILE = "swift-2048Tests/Info.plist";
441442
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
442443
METAL_ENABLE_DEBUG_INFO = NO;
444+
PRODUCT_BUNDLE_IDENTIFIER = "f3nghuang.${PRODUCT_NAME:rfc1034identifier}";
443445
PRODUCT_NAME = "$(TARGET_NAME)";
444446
TEST_HOST = "$(BUNDLE_LOADER)";
445447
};

swift-2048/AppDelegate.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
1313

1414
var window: UIWindow?
1515

16+
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
17+
return true
18+
}
1619

17-
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
18-
return true
19-
}
2020
func applicationWillResignActive(application: UIApplication) {
2121
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
2222
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
@@ -38,7 +38,5 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
3838
func applicationWillTerminate(application: UIApplication) {
3939
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
4040
}
41-
42-
4341
}
4442

swift-2048/Base.lproj/Main.storyboard

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6154.17" systemVersion="13D65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
33
<dependencies>
4-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6153.11"/>
4+
<deployment identifier="iOS"/>
5+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
56
</dependencies>
67
<scenes>
78
<!--View Controller-->
@@ -13,11 +14,11 @@
1314
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
1415
</layoutGuides>
1516
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
16-
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
17+
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
1718
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1819
<subviews>
19-
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ng3-Kq-xkw">
20-
<rect key="frame" x="106" y="269" width="109" height="30"/>
20+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ng3-Kq-xkw">
21+
<rect key="frame" x="261" y="285" width="78" height="30"/>
2122
<state key="normal" title="Start Game">
2223
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
2324
</state>
@@ -27,9 +28,12 @@
2728
</button>
2829
</subviews>
2930
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
31+
<constraints>
32+
<constraint firstItem="Ng3-Kq-xkw" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="9LS-wc-aWw"/>
33+
<constraint firstItem="Ng3-Kq-xkw" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="J3L-8R-oCZ"/>
34+
</constraints>
3035
</view>
3136
<simulatedOrientationMetrics key="simulatedOrientationMetrics"/>
32-
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
3337
</viewController>
3438
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
3539
</objects>

swift-2048/Images.xcassets/AppIcon.appiconset/Contents.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,31 @@
55
"size" : "29x29",
66
"scale" : "2x"
77
},
8+
{
9+
"idiom" : "iphone",
10+
"size" : "29x29",
11+
"scale" : "3x"
12+
},
813
{
914
"idiom" : "iphone",
1015
"size" : "40x40",
1116
"scale" : "2x"
1217
},
18+
{
19+
"idiom" : "iphone",
20+
"size" : "40x40",
21+
"scale" : "3x"
22+
},
1323
{
1424
"idiom" : "iphone",
1525
"size" : "60x60",
1626
"scale" : "2x"
1727
},
28+
{
29+
"idiom" : "iphone",
30+
"size" : "60x60",
31+
"scale" : "3x"
32+
},
1833
{
1934
"idiom" : "ipad",
2035
"size" : "29x29",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"info" : {
3+
"version" : 1,
4+
"author" : "xcode"
5+
}
6+
}

0 commit comments

Comments
 (0)